From c3cd7603037108ba9e9f6507ec16cdcf0905bf4c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 2 Oct 2020 10:40:54 +0200 Subject: Remove compiler test Outdated test for old buggy compilers Change-Id: I605a2318a21121bde9a80c046a7beb6edcd2d546 Reviewed-by: Thiago Macieira --- tests/auto/other/compiler/tst_compiler.cpp | 1519 ---------------------------- 1 file changed, 1519 deletions(-) delete mode 100644 tests/auto/other/compiler/tst_compiler.cpp (limited to 'tests/auto/other/compiler/tst_compiler.cpp') diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp deleted file mode 100644 index bfcfbc02a3..0000000000 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ /dev/null @@ -1,1519 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2017 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include - -#define BASECLASS_NOT_ABSTRACT -#include "baseclass.h" -#include "derivedclass.h" - -#ifdef Q_COMPILER_ATOMICS -# include -#endif - -QT_USE_NAMESPACE - -class tst_Compiler : public QObject -{ -Q_OBJECT -private slots: - /* C++98 & C++03 base functionality */ - void template_methods(); - void template_constructors(); - void template_subclasses(); - void methodSpecialization(); - void constructorSpecialization(); - void staticTemplateMethods(); - void staticTemplateMethodSpecialization(); - void detectDataStream(); - void detectEnums(); - void overrideCFunction(); - void stdSortQList(); - void templateCallOrder(); - void virtualFunctionNoLongerPureVirtual(); - void charSignedness() const; - void privateStaticTemplateMember() const; - void staticConstUnionWithInitializerList() const; - void templateFriends(); - - /* C++11 features */ - void cxx11_alignas(); - void cxx11_alignof(); - void cxx11_alignas_alignof(); - void cxx11_atomics(); - void cxx11_attributes(); - void cxx11_auto_function(); - void cxx11_auto_type(); - void cxx11_class_enum(); - void cxx11_constexpr(); - void cxx11_decltype(); - void cxx11_default_members(); - void cxx11_delete_members(); - void cxx11_delegating_constructors(); - void cxx11_explicit_conversions(); - void cxx11_explicit_overrides(); - void cxx11_extern_templates(); - void cxx11_inheriting_constructors(); - void cxx11_initializer_lists(); - void cxx11_lambda(); - void cxx11_nonstatic_member_init(); - void cxx11_noexcept(); - void cxx11_nullptr(); - void cxx11_range_for(); - void cxx11_raw_strings(); - void cxx11_ref_qualifiers(); - void cxx11_rvalue_refs(); - void cxx11_static_assert(); - void cxx11_template_alias(); - void cxx11_thread_local(); - void cxx11_udl(); - void cxx11_unicode_strings(); - void cxx11_uniform_init(); - void cxx11_unrestricted_unions(); - void cxx11_variadic_macros(); - void cxx11_variadic_templates(); - - /* C++14 compiler features */ - void cxx14_binary_literals(); - void cxx14_init_captures(); - void cxx14_generic_lambdas(); - void cxx14_constexpr(); - void cxx14_decltype_auto(); - void cxx14_return_type_deduction(); - void cxx14_aggregate_nsdmi(); - void cxx14_variable_templates(); - - /* Future / Technical specification compiler features */ - void runtimeArrays(); - - /* treat source code as utf-8 */ - void utf8source(); -}; - -#if defined(Q_CC_HPACC) -# define DONT_TEST_TEMPLATE_CONSTRUCTORS -# define DONT_TEST_CONSTRUCTOR_SPECIALIZATION -# define DONT_TEST_DATASTREAM_DETECTION -#endif - -#if defined(Q_CC_SUN) -# define DONT_TEST_STL_SORTING -#endif - -class TemplateMethodClass -{ -public: - template - T foo() { return 42; } -}; - -void tst_Compiler::template_methods() -{ - TemplateMethodClass t; - - QCOMPARE(t.foo(), 42); - QCOMPARE(t.foo(), 42l); - QCOMPARE(t.foo(), 42.0); -} - -#ifndef DONT_TEST_TEMPLATE_CONSTRUCTORS -class TemplateConstructorClass -{ -public: - template - TemplateConstructorClass(const T& t) { i = int(t); } - - int i; -}; - -void tst_Compiler::template_constructors() -{ - TemplateConstructorClass t1(42); - TemplateConstructorClass t2(42l); - TemplateConstructorClass t3(42.0); - - QCOMPARE(t1.i, 42); - QCOMPARE(t2.i, 42); - QCOMPARE(t3.i, 42); -} -#else -void tst_Compiler::template_constructors() -{ QSKIP("Compiler doesn't do template constructors"); } -#endif - -template -struct OuterClass -{ - template - struct InnerClass - { - U convert(const T &t) { return static_cast(t); } - }; -}; - -void tst_Compiler::template_subclasses() -{ - OuterClass::InnerClass c1; - QCOMPARE(c1.convert('a'), int('a')); - - OuterClass::InnerClass c2; - QCOMPARE(c2.convert(QRect(1, 2, 3, 4)), QRectF(QRect(1, 2, 3, 4))); -} - -class TemplateMethodClass2 -{ -public: - template - T foo() { return 42; } -}; - -template<> -int TemplateMethodClass2::foo() -{ return 43; } - -void tst_Compiler::methodSpecialization() -{ - TemplateMethodClass2 t; - - QCOMPARE(t.foo(), 43); - QCOMPARE(t.foo(), 42l); - QCOMPARE(t.foo(), 42.0); -} - -#ifndef DONT_TEST_CONSTRUCTOR_SPECIALIZATION -class TemplateConstructorClass2 -{ -public: - template - TemplateConstructorClass2(const T &t) { i = int(t); } - - int i; -}; - -template<> -TemplateConstructorClass2::TemplateConstructorClass2(const int &t) { i = t + 1; } - -void tst_Compiler::constructorSpecialization() -{ - TemplateConstructorClass2 t1(42); - TemplateConstructorClass2 t2(42l); - TemplateConstructorClass2 t3(42.0); - - QCOMPARE(t1.i, 43); - QCOMPARE(t2.i, 42); - QCOMPARE(t3.i, 42); -} -#else -void tst_Compiler::constructorSpecialization() -{ QSKIP("Compiler doesn't do constructor specialization"); } -#endif - -class StaticTemplateClass -{ -public: - template - static T foo() { return 42; } -}; - -void tst_Compiler::staticTemplateMethods() -{ - QCOMPARE(StaticTemplateClass::foo(), 42); - QCOMPARE(StaticTemplateClass::foo(), 42u); -} - -class StaticTemplateClass2 -{ -public: - template - static T foo() { return 42; } -}; - -template<> -double StaticTemplateClass2::foo() { return 18.5; } - -void tst_Compiler::staticTemplateMethodSpecialization() -{ - QCOMPARE(StaticTemplateClass2::foo(), 42); - QCOMPARE(StaticTemplateClass2::foo(), 42u); - QCOMPARE(StaticTemplateClass2::foo(), 18.5); -} - -#ifndef DONT_TEST_DATASTREAM_DETECTION -/******* DataStream tester *********/ -namespace QtTestInternal -{ - struct EmptyStruct {}; - struct LowPreferenceStruct { LowPreferenceStruct(...); }; - - EmptyStruct operator<<(QDataStream &, const LowPreferenceStruct &); - EmptyStruct operator>>(QDataStream &, const LowPreferenceStruct &); - - template - struct DataStreamChecker - { - static EmptyStruct hasStreamHelper(const EmptyStruct &); - static QDataStream hasStreamHelper(const QDataStream &); - static QDataStream &dsDummy(); - static T &dummy(); - -#ifdef BROKEN_COMPILER - static const bool HasDataStream = - sizeof(hasStreamHelper(dsDummy() << dummy())) == sizeof(QDataStream) - && sizeof(hasStreamHelper(dsDummy() >> dummy())) == sizeof(QDataStream); -#else - enum { - HasOutDataStream = sizeof(hasStreamHelper(dsDummy() >> dummy())) == sizeof(QDataStream), - HasInDataStream = sizeof(hasStreamHelper(dsDummy() << dummy())) == sizeof(QDataStream), - HasDataStream = HasOutDataStream & HasInDataStream - }; -#endif - }; -}; - -struct MyString: public QString {}; -struct Qxxx {}; - -void tst_Compiler::detectDataStream() -{ - QVERIFY(QtTestInternal::DataStreamChecker::HasDataStream); - QVERIFY(QtTestInternal::DataStreamChecker::HasDataStream); - QVERIFY(QtTestInternal::DataStreamChecker::HasDataStream == true); - QVERIFY(QtTestInternal::DataStreamChecker::HasInDataStream == true); - QVERIFY(QtTestInternal::DataStreamChecker::HasOutDataStream == false); - QVERIFY(QtTestInternal::DataStreamChecker::HasDataStream == false); - QVERIFY(QtTestInternal::DataStreamChecker::HasDataStream); - - QVERIFY(QtTestInternal::DataStreamChecker::HasDataStream); - QVERIFY(QtTestInternal::DataStreamChecker::HasDataStream); - QVERIFY(!QtTestInternal::DataStreamChecker::HasDataStream); -} -#else -void tst_Compiler::detectDataStream() -{ QSKIP("Compiler doesn't evaluate templates correctly"); } -#endif - -enum Enum1 { Foo = 0, Bar = 1 }; -enum Enum2 {}; -enum Enum3 { Something = 1 }; - -template char QTypeInfoEnumHelper(T); -template void *QTypeInfoEnumHelper(...); - -template -struct QTestTypeInfo -{ - enum { IsEnum = sizeof(QTypeInfoEnumHelper(0)) == sizeof(void*) }; -}; - -void tst_Compiler::detectEnums() -{ - QVERIFY(QTestTypeInfo::IsEnum); - QVERIFY(QTestTypeInfo::IsEnum); - QVERIFY(QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(QTestTypeInfo::IsEnum); - QVERIFY(QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); - QVERIFY(QTestTypeInfo::IsEnum); - QVERIFY(!QTestTypeInfo::IsEnum); -} -static int indicator = 0; - -// this is a silly C function -extern "C" { - void someCFunc(void *) { indicator = 42; } -} - -// this is the catch-template that will be called if the C function doesn't exist -template -void someCFunc(T *) { indicator = 10; } - -void tst_Compiler::overrideCFunction() -{ - someCFunc((void*)0); - QCOMPARE(indicator, 42); -} - -#ifndef DONT_TEST_STL_SORTING -void tst_Compiler::stdSortQList() -{ - QList list; - list << 4 << 2; - std::sort(list.begin(), list.end()); - QCOMPARE(list.value(0), 2); - QCOMPARE(list.value(1), 4); - - QList slist; - slist << "b" << "a"; - std::sort(slist.begin(), slist.end()); - QCOMPARE(slist.value(0), QString("a")); - QCOMPARE(slist.value(1), QString("b")); -} -#else -void tst_Compiler::stdSortQList() -{ QSKIP("Compiler's STL broken"); } -void tst_Compiler::stdSortQVector() -{ QSKIP("Compiler's STL broken"); } -#endif - -// the C func will set it to 1, the template to 2 -static int whatWasCalled = 0; - -void callOrderFunc(void *) -{ - whatWasCalled = 1; -} - -template -void callOrderFunc(T *) -{ - whatWasCalled = 2; -} - -template -void callOrderNoCFunc(T *) -{ - whatWasCalled = 3; -} - -/* - This test will check what will get precendence - the C function - or the template. - - It also makes sure this template "override" will compile on all systems - and not result in ambiguities. -*/ -void tst_Compiler::templateCallOrder() -{ - QCOMPARE(whatWasCalled, 0); - - // call it with a void * - void *f = 0; - callOrderFunc(f); - QCOMPARE(whatWasCalled, 1); - whatWasCalled = 0; - - char *c = 0; - /* call it with a char * - AMBIGOUS, fails on several compilers - callOrderFunc(c); - QCOMPARE(whatWasCalled, 1); - whatWasCalled = 0; - */ - - // now try the case when there is no C function - callOrderNoCFunc(f); - QCOMPARE(whatWasCalled, 3); - whatWasCalled = 0; - - callOrderNoCFunc(c); - QCOMPARE(whatWasCalled, 3); - whatWasCalled = 0; -} - -// test to see if removing =0 from a pure virtual function is BC -void tst_Compiler::virtualFunctionNoLongerPureVirtual() -{ -#ifdef BASECLASS_NOT_ABSTRACT - // has a single virtual function, not pure virtual, can call it - BaseClass baseClass; - QTest::ignoreMessage(QtDebugMsg, "BaseClass::wasAPureVirtualFunction()"); - baseClass.wasAPureVirtualFunction(); -#endif - - // DerivedClass inherits from BaseClass, and function is declared - // pure virtual, make sure we can still call it - DerivedClass derivedClass; - QTest::ignoreMessage(QtDebugMsg, "DerivedClass::wasAPureVirtualFunction()"); - derivedClass.wasAPureVirtualFunction(); -} - -template const char *resolveCharSignedness(); - -template<> -const char *resolveCharSignedness() -{ - return "char"; -} - -template<> -const char *resolveCharSignedness() -{ - return "unsigned char"; -} - -template<> -const char *resolveCharSignedness() -{ - return "signed char"; -} - -void tst_Compiler::charSignedness() const -{ - QCOMPARE("char", resolveCharSignedness()); - QCOMPARE("unsigned char", resolveCharSignedness()); - QCOMPARE("signed char", resolveCharSignedness()); -} - -class PrivateStaticTemplateMember -{ -public: - long regularMember() - { - return helper(3); - } - -private: - template - static A helper(const B b) - { - return A(b); - } -}; - -void tst_Compiler::privateStaticTemplateMember() const -{ - PrivateStaticTemplateMember v; - - QCOMPARE(long(3), v.regularMember()); -} - - -#if !defined(Q_CC_MIPS) - -// make sure we can use a static initializer with a union and then use -// the second member of the union -static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; -static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; -static inline double qt_inf() -{ - return (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_inf_bytes.d - : qt_le_inf_bytes.d); -} - -#else - -static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; -static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; -static inline double qt_inf() -{ - const uchar *bytes; - bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_inf_bytes - : qt_le_inf_bytes); - - union { uchar c[8]; double d; } returnValue; - memcpy(returnValue.c, bytes, sizeof(returnValue.c)); - return returnValue.d; -} - -#endif - -void tst_Compiler::staticConstUnionWithInitializerList() const -{ - double d = qt_inf(); - QVERIFY(qIsInf(d)); -} - -#ifndef Q_NO_TEMPLATE_FRIENDS -template class TemplateFriends -{ - T value; -public: - TemplateFriends(T value) : value(value) {} - - template void copy(TemplateFriends other) - { value = other.value; } - - template friend class TemplateFriends; -}; - -void tst_Compiler::templateFriends() -{ - TemplateFriends ti(42); - TemplateFriends tl(0); - tl.copy(ti); -} -#else -void tst_Compiler::templateFriends() -{ - QSKIP("Compiler does not support template friends"); -} -#endif - -void tst_Compiler::cxx11_alignas() -{ -#ifndef Q_COMPILER_ALIGNAS - QSKIP("Compiler does not support C++11 feature"); -#else - struct S { - alignas(double) char c; - }; - QCOMPARE(alignof(S), alignof(double)); -#endif -} - -void tst_Compiler::cxx11_alignof() -{ -#ifndef Q_COMPILER_ALIGNOF - QSKIP("Compiler does not support C++11 feature"); -#else - size_t alignchar = alignof(char); - size_t aligndouble = alignof(double); - QVERIFY(alignchar >= 1); - QVERIFY(alignchar <= aligndouble); -#endif -} - -void tst_Compiler::cxx11_alignas_alignof() -{ -#if !defined(Q_COMPILER_ALIGNAS) && !defined(Q_COMPILER_ALIGNOF) - QSKIP("Compiler does not support C++11 feature"); -#else - alignas(alignof(double)) char c; - Q_UNUSED(c); -#endif -} - -void tst_Compiler::cxx11_atomics() -{ -#ifndef Q_COMPILER_ATOMICS - QSKIP("Compiler does not support C++11 feature"); -#else - std::atomic i; - i.store(42, std::memory_order_seq_cst); - QCOMPARE(i.load(std::memory_order_acquire), 42); - - std::atomic s; - s.store(42); - QCOMPARE(s.load(), short(42)); - - std::atomic_flag flag; - flag.clear(); - QVERIFY(!flag.test_and_set()); - QVERIFY(flag.test_and_set()); -#endif -} - -QT_WARNING_PUSH -QT_WARNING_DISABLE_CLANG("-Wignored-attributes") -QT_WARNING_DISABLE_CLANG("-Wunused-local-typedefs") -QT_WARNING_DISABLE_GCC("-Wattributes") -QT_WARNING_DISABLE_GCC("-Wunused-local-typedefs") - -#ifndef __has_cpp_attribute -# define __has_cpp_attribute(x) 0 -#endif -#ifdef Q_COMPILER_ATTRIBUTES -[[noreturn]] void attribute_f1(); -void attribute_f2 [[noreturn]] (); -# if (defined(__cpp_namespace_attributes) && __cpp_namespace_attributes >= 201411) && __has_cpp_attribute(deprecated) -namespace [[deprecated]] NS { } -# endif -#endif - -void tst_Compiler::cxx11_attributes() -{ -#ifndef Q_COMPILER_ATTRIBUTES - QSKIP("Compiler does not support C++11 feature"); -#else - // Attributes in function parameters and using clauses cause MSVC 2015 to crash - // https://connect.microsoft.com/VisualStudio/feedback/details/2011594 -# if (!defined(Q_CC_MSVC) || _MSC_FULL_VER >= 190023811) && !defined(Q_CC_INTEL) - void f([[ ]] int); - [[ ]] using namespace QtPrivate; - [[ ]] try { - } catch ([[]] int) { - } -# endif - - struct [[ ]] A { }; - struct B : A { - [[ ]] int m_i : 32; - [[noreturn]] void f() const { ::exit(0); } - -# ifdef Q_COMPILER_DEFAULT_DELETE_MEMBERS - [[ ]] ~B() = default; - [[ ]] B(const B &) = delete; -# endif - }; -# if __has_cpp_attribute(deprecated) - struct [[deprecated]] C { }; -# endif - enum [[ ]] E { }; - [[ ]] void [[ ]] * [[ ]] * [[ ]] ptr = 0; - int B::* [[ ]] pmm = 0; - -# if __has_cpp_attribute(deprecated) - enum [[deprecated]] E2 { -# if defined(__cpp_enumerator_attributes) && __cpp_enumerator_attributes >= 201411 - value [[deprecated]] = 0 -# endif - }; -# endif -# ifdef Q_COMPILER_LAMBDA - []()[[ ]] {}(); -# endif -# ifdef Q_COMPILER_TEMPLATE_ALIAS - using B2 [[ ]] = B; -# endif - - [[ ]] goto end; -# ifdef Q_CC_GNU - // Attributes in gnu:: namespace - [[gnu::unused]] end: - ; - [[gnu::unused]] struct D {} d; - struct D e [[gnu::used, gnu::unused]]; - [[gnu::aligned(8)]] int i [[ ]]; - int array[][[]] = { 1 }; -# else - // Non GNU, so use an empty attribute - [[ ]] end: - ; - [[ ]] struct D {} d; - struct D e [[ ]]; - [[ ]] int i [[ ]]; - int array[][[]] = { 1 }; -# endif - - int & [[ ]] lref = i; - int && [[ ]] rref = 1; - [[ ]] (void)1; - [[ ]] for (i = 0; i < 2; ++i) - ; - - Q_UNUSED(ptr); - Q_UNUSED(pmm); - Q_UNUSED(d); - Q_UNUSED(e); - Q_UNUSED(i); - Q_UNUSED(array); - Q_UNUSED(lref); - Q_UNUSED(rref); -#endif -} -QT_WARNING_POP - -#ifdef Q_COMPILER_AUTO_FUNCTION -auto autoFunction() -> unsigned -{ - return 1; -} -#endif - -void tst_Compiler::cxx11_auto_function() -{ -#ifndef Q_COMPILER_AUTO_FUNCTION - QSKIP("Compiler does not support C++11 feature"); -#else - QCOMPARE(autoFunction(), 1u); -#endif -} - -void tst_Compiler::cxx11_auto_type() -{ -#ifndef Q_COMPILER_AUTO_TYPE - QSKIP("Compiler does not support C++11 feature"); -#else - auto i = 1; - auto x = QRandomGenerator::global()->generate(); - auto l = 1L; - auto s = QStringLiteral("Hello World"); - - QCOMPARE(i, 1); - Q_UNUSED(x); - QCOMPARE(l, 1L); - QCOMPARE(s.toLower(), QString("hello world")); -#endif -} - -void tst_Compiler::cxx11_class_enum() -{ -#ifndef Q_COMPILER_CLASS_ENUM - QSKIP("Compiler does not support C++11 feature"); -#else - enum class X { EnumValue }; - X x = X::EnumValue; - QCOMPARE(x, X::EnumValue); - - enum class Y : short { Val = 2 }; - enum Z : long { ValLong = LONG_MAX }; -#endif -} - -#ifdef Q_COMPILER_CONSTEXPR -constexpr int constexprValue() -{ - return 42; -} -#endif - -void tst_Compiler::cxx11_constexpr() -{ -#ifndef Q_COMPILER_CONSTEXPR - QSKIP("Compiler does not support C++11 feature"); -#else - static constexpr QBasicAtomicInt atomic = Q_BASIC_ATOMIC_INITIALIZER(1); - static constexpr int i = constexprValue(); - QCOMPARE(i, constexprValue()); - QCOMPARE(atomic.loadRelaxed(), 1); -#endif -} - -void tst_Compiler::cxx11_decltype() -{ -#ifndef Q_COMPILER_DECLTYPE - QSKIP("Compiler does not support C++11 feature"); -#else - decltype(QRandomGenerator::global()->generate()) i = 0; - QCOMPARE(i, 0U); -#endif -} - -void tst_Compiler::cxx11_default_members() -{ -#ifndef Q_COMPILER_DEFAULT_MEMBERS - QSKIP("Compiler does not support C++11 feature"); -#else - class DefaultMembers - { - protected: - DefaultMembers() = default; - public: - DefaultMembers(int) {} - }; - class DefaultMembersChild: public DefaultMembers - { - DefaultMembersChild(const DefaultMembersChild &) : DefaultMembers() {} - public: - DefaultMembersChild():DefaultMembers() {}; - DefaultMembersChild(DefaultMembersChild &&) = default; - }; - DefaultMembersChild dm; - DefaultMembersChild dm2 = std::move(dm); - Q_UNUSED(dm2); -#endif -} - -void tst_Compiler::cxx11_delete_members() -{ -#ifndef Q_COMPILER_DELETE_MEMBERS - QSKIP("Compiler does not support C++11 feature"); -#else - class DeleteMembers - { - protected: - DeleteMembers() = delete; - public: - DeleteMembers(const DeleteMembers &) = delete; - ~DeleteMembers() = delete; - }; -#endif -} - -void tst_Compiler::cxx11_delegating_constructors() -{ -#ifndef Q_COMPILER_DELEGATING_CONSTRUCTORS - QSKIP("Compiler does not support C++11 feature"); -#else - struct DC { - DC(int i) : i(i) {} - DC() : DC(0) {} - int i; - }; - - DC dc; - QCOMPARE(dc.i, 0); -#endif -} - -void tst_Compiler::cxx11_explicit_conversions() -{ -#ifndef Q_COMPILER_EXPLICIT_CONVERSIONS - QSKIP("Compiler does not support C++11 feature"); -#else - struct EC { - explicit operator int() const { return 0; } - operator long long() const { return 1; } - }; - EC ec; - - int i(ec); - QCOMPARE(i, 0); - - int i2 = ec; - QCOMPARE(i2, 1); -#endif -} - -void tst_Compiler::cxx11_explicit_overrides() -{ -#ifndef Q_COMPILER_EXPLICIT_OVERRIDES - QSKIP("Compiler does not support C++11 feature"); -#else - struct Base { - virtual ~Base() {} - virtual void f() {} - }; - struct Derived final : public Base { - virtual void f() final override {} - }; -#endif -} - -#ifdef Q_COMPILER_EXTERN_TEMPLATES -template T externTemplate() { return T(0); } -extern template int externTemplate(); -#endif - -void tst_Compiler::cxx11_extern_templates() -{ -#ifndef Q_COMPILER_EXTERN_TEMPLATES - QSKIP("Compiler does not support C++11 feature"); -#else - QCOMPARE(externTemplate(), 42); -#endif -} - -void tst_Compiler::cxx11_inheriting_constructors() -{ -#ifndef Q_COMPILER_INHERITING_CONSTRUCTORS - QSKIP("Compiler does not support C++11 feature"); -#else - struct Base { - int i; - Base() : i(0) {} - Base(int i) : i(i) {} - }; - struct Derived : public Base { - using Base::Base; - }; - - Derived d(1); - QCOMPARE(d.i, 1); -#endif -} - -void tst_Compiler::cxx11_initializer_lists() -{ -#ifndef Q_COMPILER_INITIALIZER_LISTS - QSKIP("Compiler does not support C++11 feature"); -#else - QList l = { 1, 2, 3, 4, 5 }; - QCOMPARE(l.length(), 5); - QCOMPARE(l.at(0), 1); - QCOMPARE(l.at(4), 5); -#endif -} - -struct CallFunctor -{ - template static int f(Functor f) - { return f();} -}; - -void tst_Compiler::cxx11_lambda() -{ -#ifndef Q_COMPILER_LAMBDA - QSKIP("Compiler does not support C++11 feature"); -#else - QCOMPARE(CallFunctor::f([]() { return 42; }), 42); -#endif -} - -void tst_Compiler::cxx11_nonstatic_member_init() -{ -#ifndef Q_COMPILER_NONSTATIC_MEMBER_INIT - QSKIP("Compiler does not support C++11 feature"); -#else - struct S { - int i = 42; - long l = 47; - char c; - S() : l(-47), c(0) {} - }; - S s; - - QCOMPARE(s.i, 42); - QCOMPARE(s.l, -47L); - QCOMPARE(s.c, '\0'); -#endif -} - -void tst_Compiler::cxx11_noexcept() -{ -#ifndef Q_COMPILER_NOEXCEPT - QSKIP("Compiler does not support C++11 feature"); -#else - extern void may_throw(); - extern void noexcept_f() noexcept; - extern void g() noexcept(noexcept(noexcept_f())); - QCOMPARE(noexcept(may_throw()), false); - QCOMPARE(noexcept(noexcept_f), true); - QCOMPARE(noexcept(g), true); -#endif -} - -void tst_Compiler::cxx11_nullptr() -{ -#ifndef Q_COMPILER_NULLPTR - QSKIP("Compiler does not support C++11 feature"); -#else - void *v = nullptr; - char *c = nullptr; - const char *cc = nullptr; - volatile char *vc = nullptr; - std::nullptr_t np = nullptr; - v = np; - - Q_UNUSED(v); - Q_UNUSED(c); - Q_UNUSED(cc); - Q_UNUSED(vc); -#endif -} - -namespace SomeNamespace { -class AdlOnly { - QList v; - -public: - AdlOnly() : v(5) { std::fill_n(v.begin(), v.size(), 42); } - -private: - friend QList::const_iterator begin(const AdlOnly &x) { return x.v.begin(); } - friend QList::const_iterator end(const AdlOnly &x) { return x.v.end(); } - friend QList::iterator begin(AdlOnly &x) { return x.v.begin(); } - friend QList::iterator end(AdlOnly &x) { return x.v.end(); } -}; -} - -void tst_Compiler::cxx11_range_for() -{ -#ifndef Q_COMPILER_RANGE_FOR - QSKIP("Compiler does not support C++11 feature"); -#else - QList l; - l << 1 << 2 << 3; - for (int i : l) - Q_UNUSED(i); - - l.clear(); - l << 1; - for (int i : l) - QCOMPARE(i, 1); - - QList ll; - l << 2; - for (int i : ll) - QCOMPARE(i, 2); - - { - const int array[] = { 0, 1, 2, 3, 4 }; - int i = 0; - for (const int &e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (int e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (const int e : array) - QCOMPARE(e, array[i++]); -#ifdef Q_COMPILER_AUTO_TYPE - i = 0; - for (const auto &e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (auto &e : array) // auto deducing const - QCOMPARE(e, array[i++]); - i = 0; - for (auto e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (const auto e : array) - QCOMPARE(e, array[i++]); -#endif - } - - { - int array[] = { 0, 1, 2, 3, 4 }; - const int array2[] = { 10, 11, 12, 13, 14 }; - int i = 0; - for (const int &e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (int &e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (int e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (const int e : array) - QCOMPARE(e, array[i++]); -#ifdef Q_COMPILER_AUTO_TYPE - i = 0; - for (const auto &e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (auto &e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (auto e : array) - QCOMPARE(e, array[i++]); - i = 0; - for (const auto e : array) - QCOMPARE(e, array[i++]); -#endif - for (int &e : array) - e += 10; - i = 0; - for (const int &e : array) - QCOMPARE(e, array2[i++]); - } - - { - const SomeNamespace::AdlOnly x; - for (const int &e : x) - QCOMPARE(e, 42); - } - - { - SomeNamespace::AdlOnly x; - for (const int &e : x) - QCOMPARE(e, 42); - for (int &e : x) - e += 10; - for (const int &e : x) - QCOMPARE(e, 52); - } -#endif -} - -void tst_Compiler::cxx11_raw_strings() -{ -#ifndef Q_COMPILER_RAW_STRINGS - QSKIP("Compiler does not support C++11 feature"); -#else - static const char xml[] = R"()"; - static const char raw[] = R"***(*"*)***"; - QCOMPARE(strlen(raw), size_t(3)); - QCOMPARE(raw[1], '"'); - Q_UNUSED(xml); -#endif -} - -void tst_Compiler::cxx11_ref_qualifiers() -{ -#ifndef Q_COMPILER_REF_QUALIFIERS - QSKIP("Compiler does not support C++11 feature"); -#else -# ifndef Q_COMPILER_RVALUE_REFS -# error "Impossible condition: ref qualifiers are supported but not rvalue refs" -# endif - // also applies to function pointers - QByteArray (QString:: *lvalueref)() const & = &QString::toLatin1; - QByteArray (QString:: *rvalueref)() && = &QString::toLatin1; - - QString s("Hello"); - QCOMPARE((s.*lvalueref)(), QByteArray("Hello")); - QCOMPARE((std::move(s).*rvalueref)(), QByteArray("Hello")); - - // tests internal behavior: - QVERIFY(s.isEmpty()); -#endif -} - -class MoveDefinedQString { - QString s; -public: - MoveDefinedQString() : s() {} - explicit MoveDefinedQString(const QString &s) : s(s) {} - MoveDefinedQString(const MoveDefinedQString &other) : s(other.s) {} -#ifdef Q_COMPILER_RVALUE_REFS - MoveDefinedQString(MoveDefinedQString &&other) : s(std::move(other.s)) { other.s.clear(); } - MoveDefinedQString &operator=(MoveDefinedQString &&other) - { s = std::move(other.s); other.s.clear(); return *this; } -#endif - MoveDefinedQString &operator=(const MoveDefinedQString &other) { s = other.s; return *this; } - -private: - friend bool operator==(const MoveDefinedQString &lhs, const MoveDefinedQString &rhs) - { return lhs.s == rhs.s; } - friend bool operator!=(const MoveDefinedQString &lhs, const MoveDefinedQString &rhs) - { return !operator==(lhs, rhs); } - friend char* toString(const MoveDefinedQString &mds) - { using namespace QTest; return toString(mds.s); } -}; - -void tst_Compiler::cxx11_rvalue_refs() -{ -#ifndef Q_COMPILER_RVALUE_REFS - QSKIP("Compiler does not support C++11 feature"); -#else - // we require std::move: - { -QT_WARNING_PUSH -QT_WARNING_DISABLE_CLANG("-Wself-move") - int i = 1; - i = std::move(i); -QT_WARNING_POP - - MoveDefinedQString s("Hello"); - MoveDefinedQString t = std::move(s); - QCOMPARE(t, MoveDefinedQString("Hello")); - QCOMPARE(s, MoveDefinedQString()); - - s = t; - t = std::move(s); - QCOMPARE(t, MoveDefinedQString("Hello")); - QCOMPARE(s, MoveDefinedQString()); - - MoveDefinedQString &&r = std::move(t); // no actual move! - QCOMPARE(r, MoveDefinedQString("Hello")); - QCOMPARE(t, MoveDefinedQString("Hello")); // so 't' is unchanged - } - - // we require std::forward: - { - MoveDefinedQString s("Hello"); - MoveDefinedQString s2 = std::forward(s); // forward as rvalue - QCOMPARE(s2, MoveDefinedQString("Hello")); - QCOMPARE(s, MoveDefinedQString()); - - MoveDefinedQString s3 = std::forward(s2); // forward as lvalue - QCOMPARE(s2, MoveDefinedQString("Hello")); - QCOMPARE(s3, MoveDefinedQString("Hello")); - } - - // we require automatic generation of move special member functions: - { - struct M { MoveDefinedQString s1, s2; }; - M m1 = { MoveDefinedQString("Hello"), MoveDefinedQString("World") }; - QCOMPARE(m1.s1, MoveDefinedQString("Hello")); - QCOMPARE(m1.s2, MoveDefinedQString("World")); - M m2 = std::move(m1); - QCOMPARE(m1.s1, MoveDefinedQString()); - QCOMPARE(m1.s2, MoveDefinedQString()); - QCOMPARE(m2.s1, MoveDefinedQString("Hello")); - QCOMPARE(m2.s2, MoveDefinedQString("World")); - M m3; - QCOMPARE(m3.s1, MoveDefinedQString()); - QCOMPARE(m3.s2, MoveDefinedQString()); - m3 = std::move(m2); - QCOMPARE(m2.s1, MoveDefinedQString()); - QCOMPARE(m2.s2, MoveDefinedQString()); - QCOMPARE(m3.s1, MoveDefinedQString("Hello")); - QCOMPARE(m3.s2, MoveDefinedQString("World")); - } -#endif -} - -void tst_Compiler::cxx11_static_assert() -{ -#ifndef Q_COMPILER_STATIC_ASSERT - QSKIP("Compiler does not support C++11 feature"); -#else - static_assert(true, "Message"); -#endif -} - -#ifdef Q_COMPILER_TEMPLATE_ALIAS -template using Map = QMap; -#endif - -void tst_Compiler::cxx11_template_alias() -{ -#ifndef Q_COMPILER_TEMPLATE_ALIAS - QSKIP("Compiler does not support C++11 feature"); -#else - Map m; - m.insert("Hello", "World"); - QCOMPARE(m.value("Hello").toString(), QString("World")); - - using X = int; - X i = 0; - Q_UNUSED(i); -#endif -} - -#ifdef Q_COMPILER_THREAD_LOCAL -static thread_local int stl = 42; -thread_local int gtl = 42; -#endif - -void tst_Compiler::cxx11_thread_local() -{ -#ifndef Q_COMPILER_THREAD_LOCAL - QSKIP("Compiler does not support C++11 feature"); -#else - thread_local int v = 1; - QVERIFY(v); - QVERIFY(stl); - QVERIFY(gtl); - - thread_local QString s = "Hello"; - QVERIFY(!s.isEmpty()); -#endif -} - -#ifdef Q_COMPILER_UDL -QString operator"" _tstqstring(const char *str, size_t len) -{ - return QString::fromUtf8(str, len) + " UDL"; -} -#endif - -void tst_Compiler::cxx11_udl() -{ -#ifndef Q_COMPILER_UDL - QSKIP("Compiler does not support C++11 feature"); -#else - QString s = "Hello World"_tstqstring; - QCOMPARE(s, QString("Hello World UDL")); -#endif -} - -void tst_Compiler::cxx11_unicode_strings() -{ - static const char16_t u[] = u"\u200BHello\u00A0World"; - QCOMPARE(u[0], char16_t(0x200B)); - - static const char32_t U[] = U"\ufffe"; - QCOMPARE(U[0], char32_t(0xfffe)); - - QCOMPARE(u"\U00010000"[0], char16_t(0xD800)); - QCOMPARE(u"\U00010000"[1], char16_t(0xDC00)); -} - -static void noop(QPair) {} -void tst_Compiler::cxx11_uniform_init() -{ -#ifndef Q_COMPILER_UNIFORM_INIT - QSKIP("Compiler does not support C++11 feature"); - noop(QPair()); -#else - QString s{"Hello"}; - int i{}; - noop(QPair{1,1}); - noop({i,1}); -#endif -} - -void tst_Compiler::cxx11_unrestricted_unions() -{ -#ifndef Q_COMPILER_UNRESTRICTED_UNIONS - QSKIP("Compiler does not support C++11 feature"); -#else - union U { - QString s; - U() {} - U(const QString &s) : s(s) {} - ~U() {} - }; - U u; - std::aligned_storage as; - Q_UNUSED(u); - Q_UNUSED(as); - - U u2("hello"); - u2.s.~QString(); -#endif -} - -void tst_Compiler::cxx11_variadic_macros() -{ -#ifndef Q_COMPILER_VARIADIC_MACROS - QSKIP("Compiler does not support C++11 feature"); -#else -# define TEST_VARARG(x, ...) __VA_ARGS__ - QCOMPARE(TEST_VARARG(0, 1), 1); -#endif -} - -#ifdef Q_COMPILER_VARIADIC_TEMPLATES -template struct VariadicTemplate {}; -#endif - -void tst_Compiler::cxx11_variadic_templates() -{ -#ifndef Q_COMPILER_VARIADIC_TEMPLATES - QSKIP("Compiler does not support C++11 feature"); -#else - VariadicTemplate<> v0; - VariadicTemplate v1; - VariadicTemplate v8; - Q_UNUSED(v0); - Q_UNUSED(v1); - Q_UNUSED(v8); -#endif -} - -void tst_Compiler::cxx14_binary_literals() -{ -#if __cpp_binary_literals-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - int i = 0b11001001; - QCOMPARE(i, 0xC9); -#endif -} - -void tst_Compiler::cxx14_init_captures() -{ -#if __cpp_init_captures-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - QCOMPARE([x = 42]() { return x; }(), 42); -#endif -} - -void tst_Compiler::cxx14_generic_lambdas() -{ -#if __cpp_generic_lambdas-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - auto identity = [](auto x) { return x; }; - QCOMPARE(identity(42), 42); - QCOMPARE(identity(42U), 42U); - QCOMPARE(identity(42L), 42L); -#endif -} - -#if __cpp_constexpr-0 >= 201304 -constexpr int relaxedConstexpr(int i) -{ - i *= 2; - i += 2; - return i; -} -#endif - -void tst_Compiler::cxx14_constexpr() -{ -#if __cpp_constexpr-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - QCOMPARE(relaxedConstexpr(0), 2); - QCOMPARE(relaxedConstexpr(2), 6); -#endif -} - -void tst_Compiler::cxx14_decltype_auto() -{ -#if __cpp_decltype_auto-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - QList l; - l << 1; - decltype(auto) value = l[0]; - value = 2; - QCOMPARE(l.at(0), 2); -#endif -} - -#if __cpp_return_type_deduction >= 201304 -auto returnTypeDeduction(bool choice) -{ - if (choice) - return 1U; - return returnTypeDeduction(!choice); -} -#endif - -void tst_Compiler::cxx14_return_type_deduction() -{ -#if __cpp_return_type_deduction-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - QCOMPARE(returnTypeDeduction(false), 1U); -#endif -} - -void tst_Compiler::cxx14_aggregate_nsdmi() -{ -#if __cpp_aggregate_nsdmi-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - struct S { int i, j = i; }; - S s = { 1 }; - QCOMPARE(s.j, 1); -#endif -} - -#if __cpp_variable_templates >= 201304 -template constexpr T variableTemplate = T(42); -#endif -void tst_Compiler::cxx14_variable_templates() -{ -#if __cpp_variable_templates-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - QCOMPARE(variableTemplate, 42); - QCOMPARE(variableTemplate, 42L); - QCOMPARE(variableTemplate, 42U); - QCOMPARE(variableTemplate, 42ULL); -#endif -} - -void tst_Compiler::runtimeArrays() -{ -#if __cpp_runtime_arrays-0 < 201304 - QSKIP("Compiler does not support this C++14 feature"); -#else - int i[QRandomGenerator::global()->generate() & 0x1f]; - Q_UNUSED(i); -#endif -} - - - -void tst_Compiler::utf8source() -{ - const char *str = "Ελληνικά"; - auto u16str = u"Ελληνικά"; - QCOMPARE(QString::fromUtf16(u16str), QString::fromUtf8(str)); - - const char *ae = "\xc3\x86"; - auto u16ae = u"Æ"; - QCOMPARE(QString::fromUtf16(u16ae), QString::fromUtf8(ae)); -} - -QTEST_MAIN(tst_Compiler) -#include "tst_compiler.moc" -- cgit v1.2.3