summaryrefslogtreecommitdiffstats
path: root/tests/auto/other
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2014-06-18 14:30:50 -0700
committerThiago Macieira <thiago.macieira@intel.com>2014-06-27 08:27:03 +0200
commiteab7ec586d7502946aff634af668630a13909ec7 (patch)
tree73f2b25444e4945c12e1fd8b6a713a134b552003 /tests/auto/other
parent416c112aea592e41a66d65a21a885f31d9a566d0 (diff)
Expand the compiler test with C++11 and C++14 compiler tests
This allows us to quickly test if a compiler actually supports what it claims to support. Change-Id: Ia32212a11774aa7947ddffae30837c53665374f3 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'tests/auto/other')
-rw-r--r--tests/auto/other/compiler/compiler.pro4
-rw-r--r--tests/auto/other/compiler/othersource.cpp51
-rw-r--r--tests/auto/other/compiler/tst_compiler.cpp758
3 files changed, 811 insertions, 2 deletions
diff --git a/tests/auto/other/compiler/compiler.pro b/tests/auto/other/compiler/compiler.pro
index 8ebcf60bc0..213429050f 100644
--- a/tests/auto/other/compiler/compiler.pro
+++ b/tests/auto/other/compiler/compiler.pro
@@ -1,9 +1,9 @@
CONFIG += testcase
TARGET = tst_compiler
-SOURCES += tst_compiler.cpp baseclass.cpp derivedclass.cpp
+SOURCES += tst_compiler.cpp baseclass.cpp derivedclass.cpp othersource.cpp
HEADERS += baseclass.h derivedclass.h
QT = core testlib
-
+contains(QT_CONFIG, c++11): CONFIG += c++14 c++11
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/other/compiler/othersource.cpp b/tests/auto/other/compiler/othersource.cpp
new file mode 100644
index 0000000000..6ff7c4d8a9
--- /dev/null
+++ b/tests/auto/other/compiler/othersource.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Intel Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+
+#ifdef Q_COMPILER_EXTERN_TEMPLATES
+template <typename T> T externTemplate();
+template<> int externTemplate<int>()
+{
+ return 42;
+}
+#endif
+
diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp
index a239e2c888..9ed5c64c4f 100644
--- a/tests/auto/other/compiler/tst_compiler.cpp
+++ b/tests/auto/other/compiler/tst_compiler.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -48,12 +49,17 @@
#include "baseclass.h"
#include "derivedclass.h"
+#ifdef Q_COMPILER_ATOMICS
+# include <atomic>
+#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();
@@ -71,6 +77,57 @@ private slots:
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();
};
#if defined(Q_CC_HPACC)
@@ -556,5 +613,706 @@ void tst_Compiler::staticConstUnionWithInitializerList() const
QVERIFY(qIsInf(d));
}
+#ifndef Q_NO_TEMPLATE_FRIENDS
+template <typename T> class TemplateFriends
+{
+ T value;
+public:
+ TemplateFriends(T value) : value(value) {}
+
+ template <typename X> void copy(TemplateFriends<X> other)
+ { value = other.value; }
+
+ template <typename X> friend class TemplateFriends;
+};
+
+void tst_Compiler::templateFriends()
+{
+ TemplateFriends<int> ti(42);
+ TemplateFriends<long> 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
+ alignas(double) char c;
+ QVERIFY(Q_ALIGNOF(c) == Q_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<int> i;
+ i.store(42, std::memory_order_seq_cst);
+ QCOMPARE(i.load(std::memory_order_acquire), 42);
+
+ std::atomic<short> 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
+}
+
+void tst_Compiler::cxx11_attributes()
+{
+#ifndef Q_COMPILER_ATTRIBUTES
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ struct [[deprecated]] C {};
+ [[gnu::unused]] struct D {} d;
+ [[noreturn]] void f();
+ struct D e [[gnu::used, gnu::unused]];
+ [[gnu::aligned(8)]] int i;
+
+[[gnu::unused]] end:
+ ;
+
+ Q_UNUSED(d);
+ Q_UNUSED(e);
+ Q_UNUSED(i);
+#endif
+}
+
+#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 = qrand();
+ 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.load(), 1);
+#endif
+}
+
+void tst_Compiler::cxx11_decltype()
+{
+#ifndef Q_COMPILER_DECLTYPE
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ decltype(qrand()) i = 0;
+ QCOMPARE(i, 0);
+#endif
+}
+
+void tst_Compiler::cxx11_default_members()
+{
+#ifndef Q_COMPILER_DEFAULT_MEMBERS
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ struct DefaultMembers
+ {
+ DefaultMembers() = default;
+ DefaultMembers(int) {}
+ };
+ DefaultMembers dm;
+ Q_UNUSED(dm);
+#endif
+}
+
+void tst_Compiler::cxx11_delete_members()
+{
+#ifndef Q_COMPILER_DELETE_MEMBERS
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ struct DeleteMembers
+ {
+ DeleteMembers() = delete;
+ 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 <typename T> T externTemplate() { return T(0); }
+extern template int externTemplate<int>();
+#endif
+
+void tst_Compiler::cxx11_extern_templates()
+{
+#ifndef Q_COMPILER_EXTERN_TEMPLATES
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ QCOMPARE(externTemplate<int>(), 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<int> l = { 1, 2, 3, 4, 5 };
+ QCOMPARE(l.length(), 5);
+ QCOMPARE(l.at(0), 1);
+ QCOMPARE(l.at(4), 5);
+#endif
+}
+
+struct CallFunctor
+{
+ template <typename Functor> 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 noexcept_f() noexcept;
+ extern void g() noexcept(noexcept(noexcept_f()));
+ QCOMPARE(noexcept(cxx11_noexcept()), 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
+}
+
+void tst_Compiler::cxx11_range_for()
+{
+#ifndef Q_COMPILER_RANGE_FOR
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ QList<int> l;
+ l << 1 << 2 << 3;
+ for (int i : l)
+ Q_UNUSED(i);
+
+ l.clear();
+ l << 1;
+ for (int i : l)
+ QCOMPARE(i, 1);
+
+ QList<long> ll;
+ l << 2;
+ for (int i : ll)
+ QCOMPARE(i, 2);
+#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"(<?xml version="1.0" encoding="UTF-8" ?>)";
+ 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
+}
+
+void tst_Compiler::cxx11_rvalue_refs()
+{
+#ifndef Q_COMPILER_RVALUE_REFS
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ int i = 1;
+ i = std::move(i);
+
+ QString s = "Hello";
+ QString t = std::move(s);
+ QCOMPARE(t, QString("Hello"));
+
+ s = t;
+ t = std::move(s);
+ QCOMPARE(t, QString("Hello"));
+
+ QString &&r = std::move(s);
+ QCOMPARE(r, QString("Hello"));
+#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 <typename T> using Map = QMap<QString, T>;
+#endif
+
+void tst_Compiler::cxx11_template_alias()
+{
+#ifndef Q_COMPILER_TEMPLATE_ALIAS
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ Map<QVariant> 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()
+{
+#ifndef Q_COMPILER_UNICODE_STRINGS
+ QSKIP("Compiler does not support C++11 feature");
+#else
+ 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));
+#endif
+}
+
+static void noop(QPair<int, int>) {}
+void tst_Compiler::cxx11_uniform_init()
+{
+#ifndef Q_COMPILER_UNIFORM_INIT
+ QSKIP("Compiler does not support C++11 feature");
+ noop(QPair<int,int>());
+#else
+ QString s{"Hello"};
+ int i{};
+ noop(QPair<int,int>{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<sizeof(QString), Q_ALIGNOF(QString)> 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 <typename... Args> 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<int> v1;
+ VariadicTemplate<int, int, int, int,
+ int, int, int, int> 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<int> l;
+ l << 1;
+ decltype(auto) value = l[0];
+ value = 2;
+ QCOMPARE(l.at(0), 2);
+#endif
+}
+
+#if __cpp_return_type_deduction >= 201304
+auto returnTypeDeduction()
+{
+ return 1U;
+}
+#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(), 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 <typename T> 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<int>, 42);
+ QCOMPARE(variableTemplate<long>, 42L);
+ QCOMPARE(variableTemplate<unsigned>, 42U);
+ QCOMPARE(variableTemplate<unsigned long long>, 42ULL);
+#endif
+}
+
+void tst_Compiler::runtimeArrays()
+{
+#if __cpp_runtime_arrays-0 < 201304
+ QSKIP("Compiler does not support this C++14 feature");
+#else
+ int i[qrand() & 0x1f];
+ Q_UNUSED(i);
+#endif
+}
+
QTEST_MAIN(tst_Compiler)
#include "tst_compiler.moc"