tests/auto/compiler/tst_compiler.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtCore/QtCore>
       
    44 #include <QtTest/QtTest>
       
    45 
       
    46 #include <algorithm>
       
    47 
       
    48 #define BASECLASS_NOT_ABSTRACT
       
    49 #include "baseclass.h"
       
    50 #include "derivedclass.h"
       
    51 
       
    52 QT_USE_NAMESPACE
       
    53 
       
    54 class tst_Compiler : public QObject
       
    55 {
       
    56 Q_OBJECT
       
    57 
       
    58 private slots:
       
    59     void template_methods();
       
    60     void template_constructors();
       
    61     void template_subclasses();
       
    62     void methodSpecialization();
       
    63     void constructorSpecialization();
       
    64     void staticTemplateMethods();
       
    65     void staticTemplateMethodSpecialization();
       
    66     void detectDataStream();
       
    67     void detectEnums();
       
    68     void overrideCFunction();
       
    69     void stdSortQList();
       
    70     void stdSortQVector();
       
    71     void templateCallOrder();
       
    72     void virtualFunctionNoLongerPureVirtual();
       
    73     void charSignedness() const;
       
    74     void privateStaticTemplateMember() const;
       
    75     void staticConstUnionWithInitializerList() const;
       
    76 };
       
    77 
       
    78 #if defined(Q_CC_MSVC) && _MSC_VER < 1300
       
    79 #define MSVC6
       
    80 #endif
       
    81 
       
    82 #if defined(Q_CC_MSVC) && _MSC_VER == 1300
       
    83 #define MSVC2002
       
    84 #endif
       
    85 
       
    86 #if defined(MSVC6)
       
    87 # define DONT_TEST_TEMPLATE_METHODS
       
    88 # define DONT_TEST_TEMPLATE_CONSTRUCTORS
       
    89 # define DONT_TEST_METHOD_SPECIALIZATION
       
    90 # define DONT_TEST_CONSTRUCTOR_SPECIALIZATION
       
    91 # define DONT_TEST_STATIC_TEMPLATE_METHODS
       
    92 # define DONT_TEST_STATIC_TEMPLATE_METHOD_SPECIALIZATION
       
    93 # define DONT_TEST_STL_SORTING
       
    94 # define DONT_TEST_SIGNEDNESS
       
    95 #endif
       
    96 
       
    97 #if defined(MSVC2002)
       
    98 # define DONT_TEST_TEMPLATE_METHODS
       
    99 # define DONT_TEST_DETECT_ENUMS
       
   100 # define DONT_TEST_METHOD_SPECIALIZATION
       
   101 # define DONT_TEST_CONSTRUCTOR_SPECIALIZATION
       
   102 # define DONT_TEST_STATIC_TEMPLATE_METHOD_SPECIALIZATION
       
   103 # define DONT_TEST_STL_SORTING
       
   104 #endif
       
   105 
       
   106 #if defined(Q_CC_HPACC)
       
   107 # define DONT_TEST_TEMPLATE_CONSTRUCTORS
       
   108 # define DONT_TEST_CONSTRUCTOR_SPECIALIZATION
       
   109 # define DONT_TEST_DATASTREAM_DETECTION
       
   110 #endif
       
   111 
       
   112 #if defined(Q_CC_SUN)
       
   113 # define DONT_TEST_STL_SORTING
       
   114 #endif
       
   115 
       
   116 #ifndef DONT_TEST_TEMPLATE_METHODS
       
   117 class TemplateMethodClass
       
   118 {
       
   119 public:
       
   120     template <class T>
       
   121     T foo() { return 42; }
       
   122 };
       
   123 
       
   124 void tst_Compiler::template_methods()
       
   125 {
       
   126     TemplateMethodClass t;
       
   127 
       
   128     QCOMPARE(t.foo<int>(), 42);
       
   129     QCOMPARE(t.foo<long>(), 42l);
       
   130     QCOMPARE(t.foo<double>(), 42.0);
       
   131 }
       
   132 #else
       
   133 void tst_Compiler::template_methods()
       
   134 { QSKIP("Compiler doesn't do template methods", SkipAll); }
       
   135 #endif
       
   136 
       
   137 #ifndef DONT_TEST_TEMPLATE_CONSTRUCTORS
       
   138 class TemplateConstructorClass
       
   139 {
       
   140 public:
       
   141     template <class T>
       
   142     TemplateConstructorClass(const T& t) { i = int(t); }
       
   143 
       
   144     int i;
       
   145 };
       
   146 
       
   147 void tst_Compiler::template_constructors()
       
   148 {
       
   149     TemplateConstructorClass t1(42);
       
   150     TemplateConstructorClass t2(42l);
       
   151     TemplateConstructorClass t3(42.0);
       
   152 
       
   153     QCOMPARE(t1.i, 42);
       
   154     QCOMPARE(t2.i, 42);
       
   155     QCOMPARE(t3.i, 42);
       
   156 }
       
   157 #else
       
   158 void tst_Compiler::template_constructors()
       
   159 { QSKIP("Compiler doesn't do template constructors", SkipAll); }
       
   160 #endif
       
   161 
       
   162 template <typename T>
       
   163 struct OuterClass
       
   164 {
       
   165     template <typename U>
       
   166     struct InnerClass
       
   167     {
       
   168         U convert(const T &t) { return static_cast<U>(t); }
       
   169     };
       
   170 };
       
   171 
       
   172 void tst_Compiler::template_subclasses()
       
   173 {
       
   174     OuterClass<char>::InnerClass<int> c1;
       
   175     QCOMPARE(c1.convert('a'), int('a'));
       
   176 
       
   177     OuterClass<QRect>::InnerClass<QRectF> c2;
       
   178     QCOMPARE(c2.convert(QRect(1, 2, 3, 4)), QRectF(QRect(1, 2, 3, 4)));
       
   179 }
       
   180 
       
   181 #ifndef DONT_TEST_METHOD_SPECIALIZATION
       
   182 class TemplateMethodClass2
       
   183 {
       
   184 public:
       
   185     template <class T>
       
   186     T foo() { return 42; }
       
   187 };
       
   188 
       
   189 template<>
       
   190 int TemplateMethodClass2::foo<int>()
       
   191 { return 43; }
       
   192 
       
   193 void tst_Compiler::methodSpecialization()
       
   194 {
       
   195     TemplateMethodClass2 t;
       
   196 
       
   197     QCOMPARE(t.foo<int>(), 43);
       
   198     QCOMPARE(t.foo<long>(), 42l);
       
   199     QCOMPARE(t.foo<double>(), 42.0);
       
   200 }
       
   201 #else
       
   202 void tst_Compiler::methodSpecialization()
       
   203 { QSKIP("Compiler doesn't do template specialization", SkipAll); }
       
   204 #endif
       
   205 
       
   206 #ifndef DONT_TEST_CONSTRUCTOR_SPECIALIZATION
       
   207 class TemplateConstructorClass2
       
   208 {
       
   209 public:
       
   210     template <class T>
       
   211     TemplateConstructorClass2(const T &t) { i = int(t); }
       
   212 
       
   213     int i;
       
   214 };
       
   215 
       
   216 template<>
       
   217 TemplateConstructorClass2::TemplateConstructorClass2(const int &t) { i = t + 1; }
       
   218 
       
   219 void tst_Compiler::constructorSpecialization()
       
   220 {
       
   221     TemplateConstructorClass2 t1(42);
       
   222     TemplateConstructorClass2 t2(42l);
       
   223     TemplateConstructorClass2 t3(42.0);
       
   224 
       
   225     QCOMPARE(t1.i, 43);
       
   226     QCOMPARE(t2.i, 42);
       
   227     QCOMPARE(t3.i, 42);
       
   228 }
       
   229 #else
       
   230 void tst_Compiler::constructorSpecialization()
       
   231 { QSKIP("Compiler doesn't do constructor specialization", SkipAll); }
       
   232 #endif
       
   233 
       
   234 #ifndef DONT_TEST_STATIC_TEMPLATE_METHODS
       
   235 class StaticTemplateClass
       
   236 {
       
   237 public:
       
   238     template <class T>
       
   239     static T foo() { return 42; }
       
   240 };
       
   241 
       
   242 void tst_Compiler::staticTemplateMethods()
       
   243 {
       
   244     QCOMPARE(StaticTemplateClass::foo<int>(), 42);
       
   245     QCOMPARE(StaticTemplateClass::foo<uint>(), 42u);
       
   246 }
       
   247 #else
       
   248 void tst_Compiler::staticTemplateMethods()
       
   249 { QSKIP("Compiler doesn't do static template methods", SkipAll); }
       
   250 #endif
       
   251 
       
   252 #ifndef DONT_TEST_STATIC_TEMPLATE_METHOD_SPECIALIZATION
       
   253 class StaticTemplateClass2
       
   254 {
       
   255 public:
       
   256     template <class T>
       
   257     static T foo() { return 42; }
       
   258 };
       
   259 
       
   260 template<>
       
   261 double StaticTemplateClass2::foo<double>() { return 18.5; }
       
   262 
       
   263 void tst_Compiler::staticTemplateMethodSpecialization()
       
   264 {
       
   265     QCOMPARE(StaticTemplateClass2::foo<int>(), 42);
       
   266     QCOMPARE(StaticTemplateClass2::foo<uint>(), 42u);
       
   267     QCOMPARE(StaticTemplateClass2::foo<double>(), 18.5);
       
   268 }
       
   269 #else
       
   270 void tst_Compiler::staticTemplateMethodSpecialization()
       
   271 { QSKIP("Compiler doesn't do static template method specialization", SkipAll); }
       
   272 #endif
       
   273 
       
   274 #ifndef DONT_TEST_DATASTREAM_DETECTION
       
   275 /******* DataStream tester *********/
       
   276 namespace QtTestInternal
       
   277 {
       
   278     struct EmptyStruct {};
       
   279     struct LowPreferenceStruct { LowPreferenceStruct(...); };
       
   280 
       
   281     EmptyStruct operator<<(QDataStream &, const LowPreferenceStruct &);
       
   282     EmptyStruct operator>>(QDataStream &, const LowPreferenceStruct &);
       
   283 
       
   284     template<typename T>
       
   285     struct DataStreamChecker
       
   286     {
       
   287         static EmptyStruct hasStreamHelper(const EmptyStruct &);
       
   288         static QDataStream hasStreamHelper(const QDataStream &);
       
   289         static QDataStream &dsDummy();
       
   290         static T &dummy();
       
   291 
       
   292 #ifdef BROKEN_COMPILER
       
   293         static const bool HasDataStream =
       
   294             sizeof(hasStreamHelper(dsDummy() << dummy())) == sizeof(QDataStream)
       
   295             && sizeof(hasStreamHelper(dsDummy() >> dummy())) == sizeof(QDataStream);
       
   296 #else
       
   297         enum {
       
   298             HasOutDataStream = sizeof(hasStreamHelper(dsDummy() >> dummy())) == sizeof(QDataStream),
       
   299             HasInDataStream = sizeof(hasStreamHelper(dsDummy() << dummy())) == sizeof(QDataStream),
       
   300             HasDataStream = HasOutDataStream & HasInDataStream
       
   301         };
       
   302 #endif
       
   303     };
       
   304 
       
   305     template<bool>
       
   306     struct DataStreamOpHelper
       
   307     {
       
   308         template <typename T>
       
   309         struct Getter {
       
   310             static QMetaType::SaveOperator saveOp() { return 0; }
       
   311         };
       
   312     };
       
   313 
       
   314     template<>
       
   315     struct DataStreamOpHelper<true>
       
   316     {
       
   317         template <typename T>
       
   318         struct Getter {
       
   319             static QMetaType::SaveOperator saveOp()
       
   320             {
       
   321                 typedef void(*SavePtr)(QDataStream &, const T *);
       
   322                 SavePtr op = ::qMetaTypeSaveHelper<T>;
       
   323                 return reinterpret_cast<QMetaType::SaveOperator>(op);
       
   324             }
       
   325         };
       
   326 
       
   327     };
       
   328 
       
   329     template<typename T>
       
   330     inline QMetaType::SaveOperator getSaveOperator(T * = 0)
       
   331     {
       
   332         typedef typename DataStreamOpHelper<DataStreamChecker<T>::HasDataStream>::template Getter<T> GetterHelper;
       
   333         return GetterHelper::saveOp();
       
   334     }
       
   335 };
       
   336 
       
   337 struct MyString: public QString {};
       
   338 struct Qxxx {};
       
   339 
       
   340 void tst_Compiler::detectDataStream()
       
   341 {
       
   342     QVERIFY(QtTestInternal::DataStreamChecker<int>::HasDataStream == true);
       
   343     QVERIFY(QtTestInternal::DataStreamChecker<uint>::HasDataStream == true);
       
   344     QVERIFY(QtTestInternal::DataStreamChecker<char *>::HasDataStream == true);
       
   345     QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasInDataStream == true);
       
   346     QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasOutDataStream == false);
       
   347     QVERIFY(QtTestInternal::DataStreamChecker<const int>::HasDataStream == false);
       
   348     QVERIFY(QtTestInternal::DataStreamChecker<double>::HasDataStream == true);
       
   349 
       
   350     QVERIFY(QtTestInternal::DataStreamChecker<QString>::HasDataStream == true);
       
   351     QVERIFY(QtTestInternal::DataStreamChecker<MyString>::HasDataStream == true);
       
   352     QVERIFY(QtTestInternal::DataStreamChecker<Qxxx>::HasDataStream == false);
       
   353 
       
   354     QVERIFY(QtTestInternal::getSaveOperator<int>() != 0);
       
   355     QVERIFY(QtTestInternal::getSaveOperator<uint>() != 0);
       
   356     QVERIFY(QtTestInternal::getSaveOperator<char *>() != 0);
       
   357     QVERIFY(QtTestInternal::getSaveOperator<double>() != 0);
       
   358     QVERIFY(QtTestInternal::getSaveOperator<QString>() != 0);
       
   359     QVERIFY(QtTestInternal::getSaveOperator<MyString>() != 0);
       
   360     QVERIFY(QtTestInternal::getSaveOperator<Qxxx>() == 0);
       
   361 }
       
   362 #else
       
   363 void tst_Compiler::detectDataStream()
       
   364 { QSKIP("Compiler doesn't evaluate templates correctly", SkipAll); }
       
   365 #endif
       
   366 
       
   367 #ifndef DONT_TEST_DETECT_ENUMS
       
   368 enum Enum1 { Foo = 0, Bar = 1 };
       
   369 enum Enum2 {};
       
   370 enum Enum3 { Something = 1 };
       
   371 
       
   372 template <typename T> char QTypeInfoEnumHelper(T);
       
   373 template <typename T> void *QTypeInfoEnumHelper(...);
       
   374 
       
   375 #if defined(MSVC6)
       
   376 
       
   377 template <int>
       
   378 struct QTestTypeInfoHelper
       
   379 {
       
   380     enum { IsE = 0 };
       
   381 };
       
   382 
       
   383 template <>
       
   384 struct QTestTypeInfoHelper<sizeof(void *)>
       
   385 {
       
   386     enum { IsE = 1 };
       
   387 };
       
   388 
       
   389 
       
   390 template <typename T>
       
   391 struct QTestTypeInfo
       
   392 {
       
   393     typedef typename QTestTypeInfoHelper<sizeof(QTypeInfoEnumHelper<T>(0))> TIHelper;
       
   394     enum { IsEnum = TIHelper::IsE };
       
   395 };
       
   396 #else
       
   397 template <typename T>
       
   398 struct QTestTypeInfo
       
   399 {
       
   400     enum { IsEnum = sizeof(QTypeInfoEnumHelper<T>(0)) == sizeof(void*) };
       
   401 };
       
   402 #endif
       
   403 
       
   404 void tst_Compiler::detectEnums()
       
   405 {
       
   406     QVERIFY(QTestTypeInfo<Enum1>::IsEnum);
       
   407     QVERIFY(QTestTypeInfo<Enum2>::IsEnum);
       
   408     QVERIFY(QTestTypeInfo<Enum3>::IsEnum);
       
   409     QVERIFY(!QTestTypeInfo<int>::IsEnum);
       
   410     QVERIFY(!QTestTypeInfo<char>::IsEnum);
       
   411     QVERIFY(!QTestTypeInfo<uint>::IsEnum);
       
   412     QVERIFY(!QTestTypeInfo<short>::IsEnum);
       
   413     QVERIFY(!QTestTypeInfo<ushort>::IsEnum);
       
   414     QVERIFY(!QTestTypeInfo<void*>::IsEnum);
       
   415     QVERIFY(!QTestTypeInfo<QString>::IsEnum);
       
   416     QVERIFY(QTestTypeInfo<Qt::Key>::IsEnum);
       
   417     QVERIFY(QTestTypeInfo<Qt::ToolBarArea>::IsEnum);
       
   418     QVERIFY(!QTestTypeInfo<Qt::ToolBarAreas>::IsEnum);
       
   419     QVERIFY(QTestTypeInfo<Qt::MatchFlag>::IsEnum);
       
   420     QVERIFY(!QTestTypeInfo<Qt::MatchFlags>::IsEnum);
       
   421 }
       
   422 #else
       
   423 void tst_Compiler::detectEnums()
       
   424 { QSKIP("Compiler doesn't evaluate templates correctly", SkipAll); }
       
   425 #endif
       
   426 
       
   427 static int indicator = 0;
       
   428 
       
   429 
       
   430 // this is a silly C function
       
   431 extern "C" {
       
   432     void someCFunc(void *) { indicator = 42; }
       
   433 }
       
   434 
       
   435 // this is the catch-template that will be called if the C function doesn't exist
       
   436 template <typename T>
       
   437 void someCFunc(T *) { indicator = 10; }
       
   438 
       
   439 void tst_Compiler::overrideCFunction()
       
   440 {
       
   441     someCFunc((void*)0);
       
   442     QCOMPARE(indicator, 42);
       
   443 }
       
   444 
       
   445 #ifndef DONT_TEST_STL_SORTING
       
   446 void tst_Compiler::stdSortQList()
       
   447 {
       
   448     QList<int> list;
       
   449     list << 4 << 2;
       
   450     std::sort(list.begin(), list.end());
       
   451     QCOMPARE(list.value(0), 2);
       
   452     QCOMPARE(list.value(1), 4);
       
   453 
       
   454     QList<QString> slist;
       
   455     slist << "b" << "a";
       
   456     std::sort(slist.begin(), slist.end());
       
   457     QCOMPARE(slist.value(0), QString("a"));
       
   458     QCOMPARE(slist.value(1), QString("b"));
       
   459 }
       
   460 
       
   461 void tst_Compiler::stdSortQVector()
       
   462 {
       
   463     QVector<int> vector;
       
   464     vector << 4 << 2;
       
   465     std::sort(vector.begin(), vector.end());
       
   466     QCOMPARE(vector.value(0), 2);
       
   467     QCOMPARE(vector.value(1), 4);
       
   468 
       
   469     QVector<QString> strvec;
       
   470     strvec << "b" << "a";
       
   471     std::sort(strvec.begin(), strvec.end());
       
   472     QCOMPARE(strvec.value(0), QString("a"));
       
   473     QCOMPARE(strvec.value(1), QString("b"));
       
   474 }
       
   475 #else
       
   476 void tst_Compiler::stdSortQList()
       
   477 { QSKIP("Compiler's STL broken", SkipAll); }
       
   478 void tst_Compiler::stdSortQVector()
       
   479 { QSKIP("Compiler's STL broken", SkipAll); }
       
   480 #endif
       
   481 
       
   482 // the C func will set it to 1, the template to 2
       
   483 static int whatWasCalled = 0;
       
   484 
       
   485 void callOrderFunc(void *)
       
   486 {
       
   487     whatWasCalled = 1;
       
   488 }
       
   489 
       
   490 template <typename T>
       
   491 void callOrderFunc(T *)
       
   492 {
       
   493     whatWasCalled = 2;
       
   494 }
       
   495 
       
   496 template <typename T>
       
   497 void callOrderNoCFunc(T *)
       
   498 {
       
   499     whatWasCalled = 3;
       
   500 }
       
   501 
       
   502 /*
       
   503    This test will check what will get precendence - the C function
       
   504    or the template.
       
   505 
       
   506    It also makes sure this template "override" will compile on all systems
       
   507    and not result in ambiguities.
       
   508 */
       
   509 void tst_Compiler::templateCallOrder()
       
   510 {
       
   511     QCOMPARE(whatWasCalled, 0);
       
   512 
       
   513     // call it with a void *
       
   514     void *f = 0;
       
   515     callOrderFunc(f);
       
   516     QCOMPARE(whatWasCalled, 1);
       
   517     whatWasCalled = 0;
       
   518 
       
   519     char *c = 0;
       
   520     /* call it with a char * - AMBIGOUS, fails on several compilers
       
   521     callOrderFunc(c);
       
   522     QCOMPARE(whatWasCalled, 1);
       
   523     whatWasCalled = 0;
       
   524     */
       
   525 
       
   526     // now try the case when there is no C function
       
   527     callOrderNoCFunc(f);
       
   528     QCOMPARE(whatWasCalled, 3);
       
   529     whatWasCalled = 0;
       
   530 
       
   531     callOrderNoCFunc(c);
       
   532     QCOMPARE(whatWasCalled, 3);
       
   533     whatWasCalled = 0;
       
   534 }
       
   535 
       
   536 // test to see if removing =0 from a pure virtual function is BC
       
   537 void tst_Compiler::virtualFunctionNoLongerPureVirtual()
       
   538 {
       
   539 #ifdef BASECLASS_NOT_ABSTRACT
       
   540     // has a single virtual function, not pure virtual, can call it
       
   541     BaseClass baseClass;
       
   542     QTest::ignoreMessage(QtDebugMsg, "BaseClass::wasAPureVirtualFunction()");
       
   543     baseClass.wasAPureVirtualFunction();
       
   544 #endif
       
   545 
       
   546     // DerivedClass inherits from BaseClass, and function is declared
       
   547     // pure virtual, make sure we can still call it
       
   548     DerivedClass derivedClass;
       
   549     QTest::ignoreMessage(QtDebugMsg, "DerivedClass::wasAPureVirtualFunction()");
       
   550     derivedClass.wasAPureVirtualFunction();
       
   551 }
       
   552 
       
   553 template<typename T> const char *resolveCharSignedness();
       
   554 
       
   555 template<>
       
   556 const char *resolveCharSignedness<char>()
       
   557 {
       
   558     return "char";
       
   559 }
       
   560 
       
   561 template<>
       
   562 const char *resolveCharSignedness<unsigned char>()
       
   563 {
       
   564     return "unsigned char";
       
   565 }
       
   566 
       
   567 template<>
       
   568 const char *resolveCharSignedness<signed char>()
       
   569 {
       
   570     return "signed char";
       
   571 }
       
   572 
       
   573 void tst_Compiler::charSignedness() const
       
   574 {
       
   575 #ifdef DONT_TEST_SIGNEDNESS
       
   576     QSKIP("MS VC 6.0 instantiates the char function for type unsigned char.", SkipSingle);
       
   577 #else
       
   578     QCOMPARE("char",            resolveCharSignedness<char>());
       
   579     QCOMPARE("unsigned char",   resolveCharSignedness<unsigned char>());
       
   580     QCOMPARE("signed char",     resolveCharSignedness<signed char>());
       
   581 #endif
       
   582 }
       
   583 
       
   584 class PrivateStaticTemplateMember
       
   585 {
       
   586 public:
       
   587     long regularMember()
       
   588     {
       
   589         return helper<long, int>(3);
       
   590     }
       
   591 
       
   592 private:
       
   593     template<typename A, typename B>
       
   594     static A helper(const B b)
       
   595     {
       
   596         return A(b);
       
   597     }
       
   598 };
       
   599 
       
   600 void tst_Compiler::privateStaticTemplateMember() const
       
   601 {
       
   602     PrivateStaticTemplateMember v;
       
   603 
       
   604     QCOMPARE(long(3), v.regularMember());
       
   605 }
       
   606 
       
   607 
       
   608 #if !defined(Q_CC_MIPS)
       
   609 
       
   610 // make sure we can use a static initializer with a union and then use
       
   611 // the second member of the union
       
   612 static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } };
       
   613 static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } };
       
   614 static const union { unsigned char c[8]; double d; } qt_armfpa_inf_bytes = { { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } };
       
   615 static inline double qt_inf()
       
   616 {
       
   617 #ifdef QT_ARMFPA
       
   618     return qt_armfpa_inf_bytes.d;
       
   619 #else
       
   620     return (QSysInfo::ByteOrder == QSysInfo::BigEndian
       
   621             ? qt_be_inf_bytes.d
       
   622             : qt_le_inf_bytes.d);
       
   623 #endif
       
   624 }
       
   625 
       
   626 #else
       
   627 
       
   628 static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
       
   629 static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
       
   630 static const unsigned char qt_armfpa_inf_bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
       
   631 static inline double qt_inf()
       
   632 {
       
   633     const uchar *bytes;
       
   634 #ifdef QT_ARMFPA
       
   635     bytes = qt_armfpa_inf_bytes;
       
   636 #else
       
   637     bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
       
   638              ? qt_be_inf_bytes
       
   639              : qt_le_inf_bytes);
       
   640 #endif
       
   641 
       
   642     union { uchar c[8]; double d; } returnValue;
       
   643     qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
       
   644     return returnValue.d;
       
   645 }
       
   646 
       
   647 #endif
       
   648 
       
   649 void tst_Compiler::staticConstUnionWithInitializerList() const
       
   650 {
       
   651     double d = qt_inf();
       
   652     QVERIFY(qIsInf(d));
       
   653 }
       
   654 
       
   655 QTEST_MAIN(tst_Compiler)
       
   656 #include "tst_compiler.moc"