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>bb10
parent
416c112aea
commit
eab7ec586d
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue