diff options
author | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
commit | ea266cad53e3d49771fa38103913d3ec7a166694 (patch) | |
tree | 8f7776b7310bebaf415ac5b69e46e9f928c37144 /test/CXX | |
parent | c72c57c9e9b69944e3e009cd5e209634839581d3 (diff) | |
download | FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.zip FreeBSD-src-ea266cad53e3d49771fa38103913d3ec7a166694.tar.gz |
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3
release):
http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_33/final@183502
Diffstat (limited to 'test/CXX')
44 files changed, 779 insertions, 108 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp index 7da3087..6fba972 100644 --- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp +++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p14.cpp @@ -47,3 +47,26 @@ class Other { void Other::foo(YFloat a, YFloat b) { YFloat c = a - b; } + +// <rdar://problem/13540899> +namespace Other { + void other_foo(); +} + +namespace M2 { + using namespace Other; + + extern "C" { + namespace MInner { + extern "C" { + class Bar { + void bar(); + }; + } + } + } +} + +void M2::MInner::Bar::bar() { + other_foo(); +} diff --git a/test/CXX/basic/basic.types/p10.cpp b/test/CXX/basic/basic.types/p10.cpp index 6401c29..9d99a77 100644 --- a/test/CXX/basic/basic.types/p10.cpp +++ b/test/CXX/basic/basic.types/p10.cpp @@ -1,9 +1,16 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y %s -DCXX1Y struct NonLiteral { NonLiteral(); }; // A type is a literal type if it is: +// [C++1y] - void +constexpr void f() {} +#ifndef CXX1Y +// expected-error@-2 {{'void' is not a literal type}} +#endif + // - a scalar type constexpr int f1(double) { return 0; } @@ -11,7 +18,6 @@ constexpr int f1(double) { return 0; } struct S { S(); }; constexpr int f2(S &) { return 0; } -// FIXME: I'm not entirely sure whether the following is legal or not... struct BeingDefined; extern BeingDefined beingdefined; struct BeingDefined { @@ -32,13 +38,13 @@ constexpr ClassTemp<int> classtemplate2[] = {}; // - it has a trivial destructor struct UserProvDtor { - constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} ~UserProvDtor(); // expected-note {{has a user-provided destructor}} }; struct NonTrivDtor { constexpr NonTrivDtor(); - constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} expected-note {{because it is virtual}} }; struct NonTrivDtorBase { @@ -71,11 +77,11 @@ struct CtorTemplate { }; struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} constexpr CopyCtorOnly(CopyCtorOnly&); - constexpr int f(); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} }; struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}} constexpr MoveCtorOnly(MoveCtorOnly&&); - constexpr int f(); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} }; template<typename T> struct CtorArg { @@ -104,7 +110,7 @@ constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitM struct NonLitBase : S { // expected-note {{base class 'S' of non-literal type}} constexpr NonLitBase(); - constexpr int f() { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} + constexpr int f() const { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} }; struct LitMemBase : Agg { Agg agg; @@ -117,7 +123,7 @@ struct MemberType { constexpr int f(MemberType<int>) { return 0; } constexpr int f(MemberType<NonLiteral>) { return 0; } // expected-error {{not a literal type}} -// - an array of literal type +// - an array of literal type [C++1y] other than an array of runtime bound struct ArrGood { Agg agg[24]; double d[12]; @@ -130,3 +136,7 @@ struct ArrBad { S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}} }; constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}} + +constexpr int arb(int n) { + int a[n]; // expected-error {{variable of non-literal type 'int [n]' cannot be defined in a constexpr function}} +} diff --git a/test/CXX/class/class.friend/p6.cpp b/test/CXX/class/class.friend/p6.cpp index 7d7a064..82ca50e 100644 --- a/test/CXX/class/class.friend/p6.cpp +++ b/test/CXX/class/class.friend/p6.cpp @@ -1,10 +1,18 @@ -// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -Wc++11-compat -verify -std=c++11 %s class A { friend static class B; // expected-error {{'static' is invalid in friend declarations}} friend extern class C; // expected-error {{'extern' is invalid in friend declarations}} - friend auto class D; // expected-warning {{incompatible with C++11}} expected-error {{'auto' is invalid in friend declarations}} friend register class E; // expected-error {{'register' is invalid in friend declarations}} friend mutable class F; // expected-error {{'mutable' is invalid in friend declarations}} friend typedef class G; // expected-error {{'typedef' is invalid in friend declarations}} + friend __thread class G; // expected-error {{'__thread' is invalid in friend declarations}} + friend _Thread_local class G; // expected-error {{'_Thread_local' is invalid in friend declarations}} + friend static _Thread_local class G; // expected-error {{'static _Thread_local' is invalid in friend declarations}} +#if __cplusplus < 201103L + friend auto class D; // expected-warning {{incompatible with C++11}} expected-error {{'auto' is invalid in friend declarations}} +#else + friend thread_local class G; // expected-error {{'thread_local' is invalid in friend declarations}} +#endif }; diff --git a/test/CXX/dcl.dcl/dcl.link/p7-2.cpp b/test/CXX/dcl.dcl/dcl.link/p7-2.cpp new file mode 100644 index 0000000..40f61c6 --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.link/p7-2.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -ast-print -o - %s | FileCheck %s + +extern "C" void f(void); +// CHECK: extern "C" void f() + +extern "C" void v; +// CHECK: extern "C" void v diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp index a3a964a..122a400 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp @@ -71,7 +71,7 @@ struct ConstexprDtor { template <typename T> constexpr T ft(T t) { return t; } template <typename T> T gt(T t) { return t; } struct S { - template<typename T> constexpr T f(); + template<typename T> constexpr T f(); // expected-warning {{C++1y}} template<typename T> T g() const; }; @@ -81,7 +81,7 @@ template <> char ft(char c) { return c; } // expected-note {{previous}} template <> constexpr char ft(char nl); // expected-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}} template <> constexpr int gt(int nl) { return nl; } template <> notlit S::f() const { return notlit(); } -template <> constexpr int S::g() { return 0; } // expected-note {{previous}} +template <> constexpr int S::g() { return 0; } // expected-note {{previous}} expected-warning {{C++1y}} template <> int S::g() const; // expected-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}} // specializations can drop the 'constexpr' but not the implied 'const'. template <> char S::g() { return 0; } // expected-error {{no function template matches}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp index cafdd63..4393727 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -verify -std=c++11 %s +// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions %s +// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y %s namespace N { typedef char C; @@ -8,7 +9,7 @@ namespace M { typedef double D; } -struct NonLiteral { // expected-note 2{{no constexpr constructors}} +struct NonLiteral { // expected-note 3{{no constexpr constructors}} NonLiteral() {} NonLiteral(int) {} }; @@ -28,45 +29,53 @@ struct SS : S { // constraints: struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}} constexpr T(); - constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}} + constexpr int f() const; // expected-error {{non-literal type 'T' cannot have constexpr members}} // - it shall not be virtual; - virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}} + virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}} - constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}} + constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}} // - its return type shall be a literal type; - constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} - constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}} + constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} + constexpr void VoidReturn() const { return; } +#ifndef CXX1Y + // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}} +#endif constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}} - typedef NonLiteral F(); + typedef NonLiteral F() const; constexpr F NonLiteralReturn2; // ok until definition // - each of its parameter types shall be a literal type; - constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} - typedef int G(NonLiteral); + constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} + typedef int G(NonLiteral) const; constexpr G NonLiteralParam2; // ok until definition // - its function-body shall be = delete, = default, - constexpr int Deleted() = delete; - // It's not possible for the function-body to legally be "= default" here. + constexpr int Deleted() const = delete; + // It's not possible for the function-body to legally be "= default" here + // (that is, for a non-constructor function) in C++11. // Other than constructors, only the copy- and move-assignment operators and // destructor can be defaulted. Destructors can't be constexpr since they // don't have a literal return type. Defaulted assignment operators can't be // constexpr since they can't be const. - constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} + constexpr T &operator=(const T&) = default; +#ifndef CXX1Y + // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} + // expected-warning@-3 {{C++1y}} +#endif }; struct U { - constexpr U SelfReturn(); - constexpr int SelfParam(U); + constexpr U SelfReturn() const; + constexpr int SelfParam(U) const; }; struct V : virtual U { // expected-note {{here}} - constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} + constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} }; -// or a compound-statememt that contains only -constexpr int AllowedStmts() { +// or a compound-statememt that contains only [CXX11] +constexpr int AllowedStmtsCXX11() { // - null statements ; @@ -91,34 +100,118 @@ constexpr int AllowedStmts() { // - and exactly one return statement return sizeof(K) + sizeof(C) + sizeof(K); } + +// or a compound-statement that does not contain [CXX1Y] +constexpr int DisallowedStmtsCXX1Y_1() { + // - an asm-definition + asm("int3"); // expected-error {{statement not allowed in constexpr function}} + return 0; +} +constexpr int DisallowedStmtsCXX1Y_2() { + // - a goto statement + goto x; // expected-error {{statement not allowed in constexpr function}} +x: + return 0; +} +constexpr int DisallowedStmtsCXX1Y_3() { + // - a try-block, + try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}} + return 0; +} +constexpr int DisallowedStmtsCXX1Y_4() { + // - a definition of a variable of non-literal type + NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}} + return 0; +} +constexpr int DisallowedStmtsCXX1Y_5() { + // - a definition of a variable of static storage duration + static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}} + return n; +} +constexpr int DisallowedStmtsCXX1Y_6() { + // - a definition of a variable of thread storage duration + thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}} + return n; +} +constexpr int DisallowedStmtsCXX1Y_7() { + // - a definition of a variable for which no initialization is performed + int n; // expected-error {{variables defined in a constexpr function must be initialized}} + return 0; +} + constexpr int ForStmt() { - for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}} + for (int n = 0; n < 10; ++n) +#ifndef CXX1Y + // expected-error@-2 {{statement not allowed in constexpr function}} +#endif return 0; } constexpr int VarDecl() { - constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}} + int a = 0; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif + return 0; +} +constexpr int ConstexprVarDecl() { + constexpr int a = 0; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif return 0; } +constexpr int VarWithCtorDecl() { + Literal a; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif + return 0; +} +NonLiteral nl; +constexpr NonLiteral &ExternNonLiteralVarDecl() { + extern NonLiteral nl; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} +#endif + return nl; +} +static_assert(&ExternNonLiteralVarDecl() == &nl, ""); constexpr int FuncDecl() { - constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}} + constexpr int ForwardDecl(int); +#ifndef CXX1Y + // expected-error@-2 {{use of this statement in a constexpr function is a C++1y extension}} +#endif return ForwardDecl(42); } constexpr int ClassDecl1() { - typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}} + typedef struct { } S1; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} +#endif return 0; } constexpr int ClassDecl2() { - using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}} + using S2 = struct { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} +#endif return 0; } constexpr int ClassDecl3() { - struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}} + struct S3 { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} +#endif return 0; } constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} constexpr int MultiReturn() { - return 0; // expected-note {{return statement}} - return 0; // expected-error {{multiple return statements in constexpr function}} + return 0; + return 0; +#ifndef CXX1Y + // expected-error@-2 {{multiple return statements in constexpr function}} + // expected-note@-4 {{return statement}} +#endif } // - every constructor call and implicit conversion used in initializing the @@ -137,3 +230,60 @@ namespace DR1364 { return kGlobal; // expected-note {{read of non-const}} } } + +namespace rdar13584715 { + typedef __PTRDIFF_TYPE__ ptrdiff_t; + + template<typename T> struct X { + static T value() {}; + }; + + void foo(ptrdiff_t id) { + switch (id) { + case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \ + // expected-note{{reinterpret_cast is not allowed in a constant expression}} + break; + } + } +} + +namespace std_example { + constexpr int square(int x) { + return x * x; + } + constexpr long long_max() { + return 2147483647; + } + constexpr int abs(int x) { + if (x < 0) +#ifndef CXX1Y + // expected-error@-2 {{C++1y}} +#endif + x = -x; + return x; + } + constexpr int first(int n) { + static int value = n; // expected-error {{static variable not permitted}} + return value; + } + constexpr int uninit() { + int a; // expected-error {{must be initialized}} + return a; + } + constexpr int prev(int x) { + return --x; + } +#ifndef CXX1Y + // expected-error@-4 {{never produces a constant expression}} + // expected-note@-4 {{subexpression}} +#endif + constexpr int g(int x, int n) { + int r = 1; + while (--n > 0) r *= x; + return r; + } +#ifndef CXX1Y + // expected-error@-5 {{C++1y}} + // expected-error@-5 {{statement not allowed}} +#endif +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp index ad156c8..8a4fa42 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions %s +// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++1y-extensions %s +// RUN: %clang_cc1 -verify -std=c++1y -fcxx-exceptions -DCXX1Y %s namespace N { typedef char C; @@ -82,26 +83,47 @@ struct V { } constexpr V(int(&)[1]) { - for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}} + for (int n = 0; n < 10; ++n) /**/; +#ifndef CXX1Y + // expected-error@-3 {{statement not allowed in constexpr constructor}} +#endif } constexpr V(int(&)[2]) { - constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}} + constexpr int a = 0; +#ifndef CXX1Y + // expected-error@-2 {{variable declaration in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[3]) { - constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}} + constexpr int ForwardDecl(int); +#ifndef CXX1Y + // expected-error@-2 {{use of this statement in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[4]) { - typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}} + typedef struct { } S1; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[5]) { - using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}} + using S2 = struct { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[6]) { - struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}} + struct S3 { }; +#ifndef CXX1Y + // expected-error@-2 {{type definition in a constexpr constructor is a C++1y extension}} +#endif } constexpr V(int(&)[7]) { - return; // expected-error {{statement not allowed in constexpr constructor}} + return; +#ifndef CXX1Y + // expected-error@-2 {{use of this statement in a constexpr constructor is a C++1y extension}} +#endif } }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp index bca73ee..5e40f69 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp @@ -102,7 +102,7 @@ X x = cmin(X(), X()); // ok, not constexpr template<typename T> struct Y { constexpr Y() {} - constexpr int get() { return T(); } + constexpr int get() { return T(); } // expected-warning {{C++1y}} }; struct Z { operator int(); }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp index 1a6dc9e..bb7f7ac 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp @@ -24,7 +24,7 @@ struct S { struct T {}; template<typename T> struct ImplicitVirtualFromDependentBase : T { - constexpr int ImplicitlyVirtual() { return 0; } + constexpr int ImplicitlyVirtual() const { return 0; } }; constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // expected-error {{constant expression}} expected-note {{cannot evaluate virtual function call}} @@ -32,7 +32,7 @@ constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); // constexpr int c = ImplicitVirtualFromDependentBase<S>().ImplicitVirtualFromDependentBase<S>::ImplicitlyVirtual(); template<typename R> struct ConstexprMember { - constexpr R F() { return 0; } + constexpr R F() const { return 0; } }; constexpr int d = ConstexprMember<int>().F(); // ok constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp index 344f8ce..40aa600 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p8.cpp @@ -3,13 +3,13 @@ using size_t = decltype(sizeof(int)); struct S { - constexpr int f(); + constexpr int f(); // expected-warning {{C++1y}} constexpr int g() const; - constexpr int h(); + constexpr int h(); // expected-warning {{C++1y}} int h(); static constexpr int Sf(); /*static*/ constexpr void *operator new(size_t) noexcept; - template<typename T> constexpr T tm(); + template<typename T> constexpr T tm(); // expected-warning {{C++1y}} template<typename T> static constexpr T ts(); }; @@ -26,12 +26,12 @@ void f(const S &s) { } constexpr int S::f() const { return 0; } -constexpr int S::g() { return 1; } -constexpr int S::h() { return 0; } +constexpr int S::g() { return 1; } // expected-warning {{C++1y}} +constexpr int S::h() { return 0; } // expected-warning {{C++1y}} int S::h() { return 0; } constexpr int S::Sf() { return 2; } constexpr void *S::operator new(size_t) noexcept { return 0; } -template<typename T> constexpr T S::tm() { return T(); } +template<typename T> constexpr T S::tm() { return T(); } // expected-warning {{C++1y}} template<typename T> constexpr T S::ts() { return T(); } namespace std_example { @@ -39,7 +39,7 @@ namespace std_example { class debug_flag { // expected-note {{not an aggregate and has no constexpr constructors}} public: explicit debug_flag(bool); - constexpr bool is_on(); // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}} + constexpr bool is_on() const; // expected-error {{non-literal type 'std_example::debug_flag' cannot have constexpr members}} private: bool flag; }; diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp index a385aa9..83b12d4 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp @@ -7,7 +7,7 @@ struct S { // Note, this is not permitted: conversion-declarator cannot have a trailing return type. // FIXME: don't issue the second diagnostic for this. - operator auto(*)()->int(); // expected-error{{'auto' not allowed here}} expected-error {{C++ requires a type specifier}} + operator auto(*)()->int(); // expected-error{{'auto' not allowed in conversion function type}} expected-error {{C++ requires a type specifier}} }; typedef auto Fun(int a) -> decltype(a + a); diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp new file mode 100644 index 0000000..39c547b --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-1y.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-c++1y-extensions + +// FIXME: This is in p11 (?) in C++1y. +void f() { + decltype(auto) a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}} + if (decltype(auto) b = b) {} // expected-error {{variable 'b' declared with 'auto' type cannot appear in its own initializer}} + decltype(auto) c = ({ decltype(auto) d = c; 0; }); // expected-error {{variable 'c' declared with 'auto' type cannot appear in its own initializer}} +} + +void g() { + decltype(auto) a; // expected-error{{declaration of variable 'a' with type 'decltype(auto)' requires an initializer}} + + decltype(auto) *b; // expected-error{{cannot form pointer to 'decltype(auto)'}} expected-error{{declaration of variable 'b' with type 'decltype(auto) *' requires an initializer}} + + if (decltype(auto) b) {} // expected-error {{must have an initializer}} + for (;decltype(auto) b;) {} // expected-error {{must have an initializer}} + while (decltype(auto) b) {} // expected-error {{must have an initializer}} + if (decltype(auto) b = true) { (void)b; } +} + +decltype(auto) n(1,2,3); // expected-error{{initializer for variable 'n' with type 'decltype(auto)' contains multiple expressions}} + +namespace N +{ + // All of these are references, because a string literal is an lvalue. + decltype(auto) a = "const char (&)[19]", b = a, c = (a); +} + +void h() { + decltype(auto) b = 42ULL; + + for (decltype(auto) c = 0; c < b; ++c) { + } +} + +template<typename T, typename U> struct same; +template<typename T> struct same<T, T> {}; + +void i() { + decltype(auto) x = 5; + decltype(auto) int r; // expected-error {{cannot combine with previous 'decltype(auto)' declaration specifier}} expected-error {{requires an initializer}} +} + +namespace p3_example { + template<typename T, typename U> struct is_same_impl { + static const bool value = false; + }; + template<typename T> struct is_same_impl<T, T> { + static const bool value = true; + }; + template<typename T, typename U> constexpr bool is_same() { + return is_same_impl<T,U>::value; + } + + auto x = 5; + const auto *v = &x, u = 6; + static auto y = 0.0; + auto int r; // expected-warning {{storage class}} expected-error {{file-scope}} + + static_assert(is_same<decltype(x), int>(), ""); + static_assert(is_same<decltype(v), const int*>(), ""); + static_assert(is_same<decltype(u), const int>(), ""); + static_assert(is_same<decltype(y), double>(), ""); + +#ifdef CXX1Y + auto f() -> int; + auto g() { return 0.0; } + auto h(); + + static_assert(is_same<decltype(f), int()>(), ""); + static_assert(is_same<decltype(g), double()>(), ""); +#endif +} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp index 7499829..0cdf3c6 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -11,7 +11,7 @@ struct S { friend auto; // expected-error{{'auto' not allowed in non-static struct member}} - operator auto(); // expected-error{{'auto' not allowed here}} + operator auto(); // expected-error{{'auto' not allowed in conversion function type}} }; // PR 9278: auto is not allowed in typedefs, except with a trailing return type. diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp new file mode 100644 index 0000000..66085ed --- /dev/null +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6-1y.cpp @@ -0,0 +1,97 @@ +// RUN: %clang_cc1 -verify -std=c++1y %s + +namespace std { + template<typename T> struct initializer_list { + const T *p; + unsigned long n; + initializer_list(const T *p, unsigned long n); + }; +} + +// FIXME: This may not be p6 in C++1y; N3638 isn't very clear whether paragraphs +// were added. It might be p8? + +int i; +int &&f(); + +using Int = int; +using IntLRef = int&; +using IntRRef = int&&; +using InitListInt = std::initializer_list<int>; +using IntPtr = int*; + +auto x3a = i; +decltype(auto) x3d = i; +using Int = decltype(x3a); +using Int = decltype(x3d); + +auto x4a = (i); +decltype(auto) x4d = (i); +using Int = decltype(x4a); +using IntLRef = decltype(x4d); + +auto x5a = f(); +decltype(auto) x5d = f(); +using Int = decltype(x5a); +using IntRRef = decltype(x5d); + +auto x6a = { 1, 2 }; +decltype(auto) x6d = { 1, 2 }; // expected-error {{cannot deduce 'decltype(auto)' from initializer list}} +using InitListInt = decltype(x6a); + +auto *x7a = &i; +decltype(auto) *x7d = &i; // expected-error {{cannot form pointer to 'decltype(auto)'}} +using IntPtr = decltype(x7a); + +struct S {}; + +decltype(auto) f1(); +decltype(auto) (*f2)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}} +decltype(auto) *f3(); // expected-error {{cannot form pointer to 'decltype(auto)'}} +const decltype(auto) f4(); // expected-error {{'decltype(auto)' cannot be combined with other type specifiers}} +typedef decltype(auto) f5(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} +decltype(auto) ((((((f6))))())); // ok +decltype(auto) f7()(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{function cannot return function type}} +decltype(auto) (S::*f8)(); // expected-error {{'decltype(auto)' can only be used as a return type in a function declaration}} expected-error {{requires an initializer}} +decltype(auto) &f9(); // expected-error {{cannot form reference to 'decltype(auto)'}} +decltype(auto) (&f10())[10]; // expected-error {{cannot form array of 'decltype(auto)'}} + +decltype(auto) ((((((v1)))))) = 0; // ok +decltype(auto) v2[1] = { 0 }; // expected-error {{cannot form array of 'decltype(auto)'}} +decltype(auto) &v3 = { 0 }; // expected-error {{cannot form reference to 'decltype(auto)'}} +decltype(auto) *v4 = { 0 }; // expected-error {{cannot form pointer to 'decltype(auto)'}} + +auto multi1a = 0, &multi1b = multi1a; +auto multi1c = multi1a, multi1d = multi1b; +decltype(auto) multi1e = multi1a, multi1f = multi1b; // expected-error {{'decltype(auto)' deduced as 'int' in declaration of 'multi1e' and deduced as 'int &' in declaration of 'multi1f'}} + +auto f1a() { return 0; } +decltype(auto) f1d() { return 0; } +using Int = decltype(f1a()); +using Int = decltype(f1d()); + +auto f2a(int n) { return n; } +decltype(auto) f2d(int n) { return n; } +using Int = decltype(f2a(0)); +using Int = decltype(f2d(0)); + +auto f3a(int n) { return (n); } +decltype(auto) f3d(int n) { return (n); } // expected-warning {{reference to stack memory}} +using Int = decltype(f3a(0)); +using IntLRef = decltype(f3d(0)); + +auto f4a(int n) { return f(); } +decltype(auto) f4d(int n) { return f(); } +using Int = decltype(f4a(0)); +using IntRRef = decltype(f4d(0)); + +auto f5aa(int n) { auto x = f(); return x; } +auto f5ad(int n) { decltype(auto) x = f(); return x; } +decltype(auto) f5da(int n) { auto x = f(); return x; } +decltype(auto) f5dd(int n) { decltype(auto) x = f(); return x; } // expected-error {{rvalue reference to type 'int' cannot bind to lvalue}} +using Int = decltype(f5aa(0)); +using Int = decltype(f5ad(0)); +using Int = decltype(f5da(0)); + +auto init_list_1() { return { 1, 2, 3 }; } // expected-error {{cannot deduce return type from initializer list}} +decltype(auto) init_list_2() { return { 1, 2, 3 }; } // expected-error {{cannot deduce return type from initializer list}} diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp index 093bc14..1ed93b1 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp @@ -41,7 +41,9 @@ decltype( PD(), // expected-error {{private destructor}} PD()) pd1; // expected-error {{private destructor}} decltype(DD(), // expected-error {{deleted function}} - DD()) dd1; // expected-error {{deleted function}} + DD()) dd1; +decltype(A(), + DD()) dd2; // expected-error {{deleted function}} decltype( PD(), // expected-error {{temporary of type 'PD' has private destructor}} 0) pd2; @@ -76,7 +78,7 @@ namespace libcxx_example { template<typename T> struct swappable { typedef decltype(swap(declval<T&>(), declval<T&>())) type; static const bool value = !is_same<type, nat>::value; - constexpr operator bool() { return value; } + constexpr operator bool() const { return value; } }; static_assert(swappable<int>(), ""); diff --git a/test/CXX/dcl.dcl/p4-0x.cpp b/test/CXX/dcl.dcl/p4-0x.cpp index 31d4912..1f4cdda 100644 --- a/test/CXX/dcl.dcl/p4-0x.cpp +++ b/test/CXX/dcl.dcl/p4-0x.cpp @@ -2,15 +2,15 @@ struct S { constexpr S(bool b) : b(b) {} - constexpr explicit operator bool() { return b; } + constexpr explicit operator bool() const { return b; } bool b; }; struct T { - constexpr operator int() { return 1; } + constexpr operator int() const { return 1; } }; struct U { - constexpr operator int() { return 1; } // expected-note {{candidate}} - constexpr operator long() { return 0; } // expected-note {{candidate}} + constexpr operator int() const { return 1; } // expected-note {{candidate}} + constexpr operator long() const { return 0; } // expected-note {{candidate}} }; static_assert(S(true), ""); diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp index 783aba1..b9a1bc5 100644 --- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp +++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp @@ -6,8 +6,8 @@ struct S1 { constexpr S1() = default; // expected-error {{defaulted definition of default constructor is not constexpr}} constexpr S1(const S1&) = default; constexpr S1(S1&&) = default; - constexpr S1 &operator=(const S1&) = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}} - constexpr S1 &operator=(S1&&) = default; // expected-error {{explicitly-defaulted move assignment operator may not have}} + constexpr S1 &operator=(const S1&) const = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}} + constexpr S1 &operator=(S1&&) const = default; // expected-error {{explicitly-defaulted move assignment operator may not have}} constexpr ~S1() = default; // expected-error {{destructor cannot be marked constexpr}} int n; }; diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp index fef3692..8767678 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y %s -DCXX1Y // An aggregate is an array or a class... struct Aggr { @@ -18,9 +19,6 @@ struct NonAggr1a { // expected-note 2 {{candidate constructor}} NonAggr1a(int, int); // expected-note {{candidate constructor}} int k; }; -// In C++0x, 'user-provided' is only defined for special member functions, so -// this type is considered to be an aggregate. This is considered to be -// a language defect. NonAggr1a na1a = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1a'}} struct NonAggr1b { @@ -30,10 +28,15 @@ struct NonAggr1b { NonAggr1b na1b = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr1b'}} // no brace-or-equal-initializers for non-static data members, ... -struct NonAggr2 { // expected-note 3 {{candidate constructor}} +// Note, this bullet was removed in C++1y. +struct NonAggr2 { int m = { 123 }; }; -NonAggr2 na2 = { 42 }; // expected-error {{no matching constructor for initialization of 'NonAggr2'}} +NonAggr2 na2 = { 42 }; +#ifndef CXX1Y +// expected-error@-2 {{no matching constructor for initialization of 'NonAggr2'}} +// expected-note@-6 3 {{candidate constructor}} +#endif // no private... struct NonAggr3 { // expected-note 3 {{candidate constructor}} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp new file mode 100644 index 0000000..d1fbe76 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p7.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++1y %s -verify + +// expected-no-diagnostics + +struct S { int a; const char *b; int c; int d = b[a]; }; +constexpr S ss = { 1, "asdf" }; + +static_assert(ss.a == 1, ""); +static_assert(ss.b[2] == 'd', ""); +static_assert(ss.c == 0, ""); +static_assert(ss.d == 's', ""); + +struct X { int i, j, k = 42; }; +constexpr X a[] = { 1, 2, 3, 4, 5, 6 }; +constexpr X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; + +constexpr bool operator==(X a, X b) { + return a.i == b.i && a.j == b.j && a.k == b.k; +} + +static_assert(sizeof(a) == sizeof(b), ""); +static_assert(a[0] == b[0], ""); +static_assert(a[1] == b[1], ""); diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp index 812d0de..fdfa678 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp @@ -200,3 +200,37 @@ namespace rdar13278115 { X &&f1(Y &y) { return y; } // expected-error{{rvalue reference to type 'rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}} const X &&f2(Y &y) { return y; } // expected-error{{rvalue reference to type 'const rdar13278115::X' cannot bind to lvalue of type 'rdar13278115::Y'}} } + +namespace bitfields { + struct IntBitfield { + int i : 17; // expected-note 3 {{bit-field is declared here}} + }; + + // A simplified version of std::move. + template <typename T> + T &&move(T &obj) { + return static_cast<T &&>(obj); + } + + void test() { + int & ir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} + int & ir2 = (xvalue<IntBitfield>().i); // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}} + int && ir3 = (xvalue<IntBitfield>().i); // no-warning + int && ir4 = move(lvalue<IntBitfield>()).i; // no-warning + + volatile int & vir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} + volatile int & vir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'volatile int' cannot bind to a temporary of type 'int'}} + volatile int && vir3 = (xvalue<IntBitfield>().i); // no-warning + volatile int && vir4 = move(lvalue<IntBitfield>()).i; // no-warning + + const int & cir1 = (lvalue<IntBitfield>().i); // no-warning + const int & cir2 = (xvalue<IntBitfield>().i); // no-warning + const int && cir3 = (xvalue<IntBitfield>().i); // no-warning + const int && cir4 = move(lvalue<IntBitfield>()).i; // no-warning + + const volatile int & cvir1 = (lvalue<IntBitfield>().i); // expected-error{{non-const reference cannot bind to bit-field 'i'}} + const volatile int & cvir2 = (xvalue<IntBitfield>().i); // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}} + const volatile int && cvir3 = (xvalue<IntBitfield>().i); // no-warning + const volatile int && cvir4 = move(lvalue<IntBitfield>()).i; // no-warning + } +} diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp index 51d61a5..263f661 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp @@ -38,3 +38,26 @@ namespace PR6066 { return 0; } } + +namespace test3 { + struct A { + unsigned bitX : 4; // expected-note 4 {{bit-field is declared here}} + unsigned bitY : 4; // expected-note {{bit-field is declared here}} + unsigned var; + + void foo(); + }; + + void test(A *a) { + unsigned &t0 = a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t1 = (unsigned&) a->bitX; // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t2 = const_cast<unsigned&>(a->bitX); // expected-error {{const_cast from bit-field lvalue to reference type 'unsigned int &'}} + unsigned &t3 = (a->foo(), a->bitX); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t4 = (a->var ? a->bitX : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t5 = (a->var ? a->bitX : a->bitX); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t6 = (a->var ? a->bitX : a->var); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t7 = (a->var ? a->var : a->bitY); // expected-error {{non-const reference cannot bind to bit-field}} + unsigned &t8 = (a->bitX = 3); // expected-error {{non-const reference cannot bind to bit-field 'bitX'}} + unsigned &t9 = (a->bitY += 3); // expected-error {{non-const reference cannot bind to bit-field 'bitY'}} + } +} diff --git a/test/CXX/except/except.spec/p1.cpp b/test/CXX/except/except.spec/p1.cpp index e184ec4..a32f37d 100644 --- a/test/CXX/except/except.spec/p1.cpp +++ b/test/CXX/except/except.spec/p1.cpp @@ -55,7 +55,7 @@ namespace noex { struct A {}; void g1() noexcept(A()); // expected-error {{not contextually convertible}} - void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}} + void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}} expected-note {{read of non-const variable 'b'}} expected-note {{here}} } diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp index 99ed2fd..dda69e9 100644 --- a/test/CXX/except/except.spec/p14.cpp +++ b/test/CXX/except/except.spec/p14.cpp @@ -112,3 +112,26 @@ namespace rdar13017229 { Typo foo(); // expected-error{{unknown type name 'Typo'}} }; } + +namespace InhCtor { + template<int> struct X {}; + struct Base { + Base(X<0>) noexcept(true); + Base(X<1>) noexcept(false); + Base(X<2>) throw(X<2>); + template<typename T> Base(T) throw(T); + }; + template<typename T> struct Throw { + Throw() throw(T); + }; + struct Derived : Base, Throw<X<3>> { + using Base::Base; + Throw<X<4>> x; + }; + struct Test { + friend Derived::Derived(X<0>) throw(X<3>, X<4>); + friend Derived::Derived(X<1>) noexcept(false); + friend Derived::Derived(X<2>) throw(X<2>, X<3>, X<4>); + }; + static_assert(!noexcept(Derived{X<5>{}}), ""); +} diff --git a/test/CXX/expr/expr.ass/p9-cxx11.cpp b/test/CXX/expr/expr.ass/p9-cxx11.cpp index 206c82c..ecc6d2c 100644 --- a/test/CXX/expr/expr.ass/p9-cxx11.cpp +++ b/test/CXX/expr/expr.ass/p9-cxx11.cpp @@ -24,8 +24,8 @@ struct S { int a, b; }; struct T { - constexpr int operator=(S s) { return s.a; } - constexpr int operator+=(S s) { return s.b; } + constexpr int operator=(S s) const { return s.a; } + constexpr int operator+=(S s) const { return s.b; } }; static_assert((T() = {4, 9}) == 4, ""); static_assert((T() += {4, 9}) == 9, ""); diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp index 065a12b..634dee3 100644 --- a/test/CXX/expr/expr.const/p2-0x.cpp +++ b/test/CXX/expr/expr.const/p2-0x.cpp @@ -118,7 +118,7 @@ namespace IncompleteClassTypeAddr { constexpr S (*p2)[] = &sArr; // ok struct S { - constexpr S *operator&() { return nullptr; } + constexpr S *operator&() const { return nullptr; } }; constexpr S *q = &s; // ok static_assert(!q, ""); @@ -205,7 +205,7 @@ namespace UndefinedBehavior { constexpr const int &np = (*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot access array element of null pointer}} struct C { - constexpr int f() { return 0; } + constexpr int f() const { return 0; } } constexpr c = C(); constexpr int k1 = c.f(); // ok constexpr int k2 = ((C*)nullptr)->f(); // expected-error {{constant expression}} expected-note {{cannot call member function on null pointer}} @@ -481,14 +481,14 @@ namespace UnspecifiedRelations { public: constexpr A() : a(0), b(0) {} int a; - constexpr bool cmp() { return &a < &b; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'A' with differing access specifiers (public vs private) has unspecified value}} + constexpr bool cmp() const { return &a < &b; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'A' with differing access specifiers (public vs private) has unspecified value}} private: int b; }; class B { public: A a; - constexpr bool cmp() { return &a.a < &b.a; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'B' with differing access specifiers (public vs protected) has unspecified value}} + constexpr bool cmp() const { return &a.a < &b.a; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{comparison of address of fields 'a' and 'b' of 'B' with differing access specifiers (public vs protected) has unspecified value}} protected: A b; }; diff --git a/test/CXX/expr/expr.const/p3-0x.cpp b/test/CXX/expr/expr.const/p3-0x.cpp index 6ddd11b..047e238 100644 --- a/test/CXX/expr/expr.const/p3-0x.cpp +++ b/test/CXX/expr/expr.const/p3-0x.cpp @@ -101,7 +101,7 @@ int n = Val<bool, &S::operator int>::value; // expected-error {{conversion from namespace NonConstLValue { struct S { - constexpr operator int() { return 10; } + constexpr operator int() const { return 10; } }; S s; // not constexpr // Under the FDIS, this is not a converted constant expression. diff --git a/test/CXX/expr/expr.const/p5-0x.cpp b/test/CXX/expr/expr.const/p5-0x.cpp index bdb2b23..0a4ac22 100644 --- a/test/CXX/expr/expr.const/p5-0x.cpp +++ b/test/CXX/expr/expr.const/p5-0x.cpp @@ -7,8 +7,8 @@ namespace std_example { struct A { constexpr A(int i) : val(i) { } - constexpr operator int() { return val; } - constexpr operator long() { return 43; } + constexpr operator int() const { return val; } + constexpr operator long() const { return 43; } private: int val; }; @@ -21,17 +21,17 @@ int ary[a]; // expected-error {{size of array has non-integer type 'const std_ex struct OK { constexpr OK() {} - constexpr operator int() { return 8; } + constexpr operator int() const { return 8; } } constexpr ok; extern struct Incomplete incomplete; // expected-note 4{{forward decl}} struct Explicit { constexpr Explicit() {} - constexpr explicit operator int() { return 4; } // expected-note 4{{here}} + constexpr explicit operator int() const { return 4; } // expected-note 4{{here}} } constexpr expl; struct Ambiguous { constexpr Ambiguous() {} - constexpr operator int() { return 2; } // expected-note 4{{here}} - constexpr operator long() { return 1; } // expected-note 4{{here}} + constexpr operator int() const { return 2; } // expected-note 4{{here}} + constexpr operator long() const { return 1; } // expected-note 4{{here}} } constexpr ambig; constexpr int test_ok = ok; // ok diff --git a/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp index be89876..76ea96f 100644 --- a/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp +++ b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -// expected-no-diagnostics // The result of the expression const_cast<T>(v) is of type T. If T is // an lvalue reference to object type, the result is an lvalue; if T @@ -16,3 +15,19 @@ void test_classification(const int *ptr) { int *ptr1 = const_cast<int *&&>(xvalue<const int*>()); int *ptr2 = const_cast<int *&&>(prvalue<const int*>()); } + +struct A { + volatile unsigned ubf : 4; + volatile unsigned uv; + volatile int sv; + void foo(); + bool pred(); +}; + +void test(A &a) { + unsigned &t0 = const_cast<unsigned&>(a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t1 = const_cast<unsigned&>(a.foo(), a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t2 = const_cast<unsigned&>(a.pred() ? a.ubf : a.ubf); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t3 = const_cast<unsigned&>(a.pred() ? a.ubf : a.uv); // expected-error {{const_cast from bit-field lvalue to reference type}} + unsigned &t4 = const_cast<unsigned&>(a.pred() ? a.ubf : a.sv); // expected-error {{const_cast from rvalue to reference type}} +} diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp index 5dac886..38d5d0a 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -Wno-lambda-extensions -verify +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify void defargs() { auto l1 = [](int i, int j = 17, int k = 18) { return i + j + k; }; diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp index 9dffc1f..dc2c209 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp +++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp @@ -39,12 +39,10 @@ void test_quals() { bogus_override_if_virtual<decltype(l)> bogus; } -// Default arguments (8.3.6) shall not be specified in the -// parameter-declaration-clause of a lambda- declarator. -// Note: Removed by core issue 974. +// Core issue 974: default arguments (8.3.6) may be specified in the +// parameter-declaration-clause of a lambda-declarator. int test_default_args() { - return [](int i = 5, // expected-warning{{C++11 forbids default arguments for lambda expressions}} - int j = 17) { return i+j;}(5, 6); + return [](int i = 5, int j = 17) { return i+j;}(5, 6); } // Any exception-specification specified on a lambda-expression diff --git a/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp new file mode 100644 index 0000000..6a59e3d --- /dev/null +++ b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct A { + unsigned bitX : 4; + unsigned bitY : 4; + unsigned var; + + void foo(); +}; + +void test(A *a) { + int x; + x = sizeof(a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof((unsigned) a->bitX); + x = sizeof(a->foo(), a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->var ? a->bitX : a->bitY); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->var ? a->bitX : a->bitX); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->bitX = 3); // expected-error {{invalid application of 'sizeof' to bit-field}} + x = sizeof(a->bitY += 3); // expected-error {{invalid application of 'sizeof' to bit-field}} +} diff --git a/test/CXX/over/over.oper/over.literal/p2.cpp b/test/CXX/over/over.oper/over.literal/p2.cpp index c012104..00466fb 100644 --- a/test/CXX/over/over.oper/over.literal/p2.cpp +++ b/test/CXX/over/over.oper/over.literal/p2.cpp @@ -33,3 +33,12 @@ template<char...> void operator "" _h() {} template<> void operator "" _h<'a', 'b', 'c'>() {} template void operator "" _h<'a', 'b', 'c', 'd'>(); + +namespace rdar13605348 { + +class C { + double operator"" _x(long double value) { return double(value); } // expected-error{{literal operator 'operator "" _x' must be in a namespace or global scope}} + double value() { return 3.2_x; } // expected-error{{no matching literal operator for call to}} +}; + +} diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp index 184e902..b986f65 100644 --- a/test/CXX/special/class.inhctor/elsewhere.cpp +++ b/test/CXX/special/class.inhctor/elsewhere.cpp @@ -55,3 +55,10 @@ template<typename T> struct F : D<bool> { using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}} }; F<bool> fb; // expected-note {{here}} + +template<typename T> +struct G : T { + using T::T; + G(int &) : G(0) {} +}; +G<B1> g(123); diff --git a/test/CXX/special/class.inhctor/p1.cpp b/test/CXX/special/class.inhctor/p1.cpp index 57e9150..8721dec 100644 --- a/test/CXX/special/class.inhctor/p1.cpp +++ b/test/CXX/special/class.inhctor/p1.cpp @@ -2,17 +2,24 @@ // Per a core issue (no number yet), an ellipsis is always dropped. struct A { A(...); // expected-note {{here}} - A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 5{{here}} + A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 9{{here}} A(int = 0, int = 0, ...); // expected-note {{here}} + + template<typename T> A(T, int = 0, ...); // expected-note 5{{here}} + + template<typename T, int N> A(const T (&)[N]); // expected-note 2{{here}} + template<typename T, int N> A(const T (&)[N], int = 0); // expected-note 2{{here}} }; -struct B : A { // expected-note 3{{candidate}} - using A::A; // expected-warning 3{{inheriting constructor does not inherit ellipsis}} expected-note 4{{candidate}} expected-note 2{{deleted}} +struct B : A { // expected-note 6{{candidate}} + using A::A; // expected-warning 4{{inheriting constructor does not inherit ellipsis}} expected-note 16{{candidate}} expected-note 3{{deleted}} }; +struct C {} c; + B b0{}; // expected-error@-1 {{call to implicitly-deleted default constructor}} -// expected-note@9 {{default constructor of 'B' is implicitly deleted because base class 'A' has multiple default constructors}} +// expected-note@-8 {{default constructor of 'B' is implicitly deleted because base class 'A' has multiple default constructors}} B b1{1}; // FIXME: explain why the inheriting constructor was deleted @@ -29,3 +36,29 @@ B b4{1,2,3,4}; B b5{1,2,3,4,5}; // expected-error@-1 {{no matching constructor for initialization of 'B'}} + +B b6{c}; +// ok + +B b7{c,0}; +// ok + +B b8{c,0,1}; +// expected-error@-1 {{no matching constructor}} + +B b9{"foo"}; +// FIXME: explain why the inheriting constructor was deleted +// expected-error@-2 {{call to deleted constructor of 'B'}} + +namespace PR15755 { + struct X { + template<typename...Ts> X(int, Ts...); + }; + struct Y : X { + using X::X; + }; + struct Z : Y { + using Y::Y; + }; + Z z(0); +} diff --git a/test/CXX/special/class.inhctor/p2.cpp b/test/CXX/special/class.inhctor/p2.cpp index e426738..e6abd68 100644 --- a/test/CXX/special/class.inhctor/p2.cpp +++ b/test/CXX/special/class.inhctor/p2.cpp @@ -3,7 +3,7 @@ template<int> struct X {}; // Constructor characteristics are: -// - the template parameter list [FIXME] +// - the template parameter list // - the parameter-type-list // - absence or presence of explicit // - absence or presence of constexpr @@ -85,3 +85,37 @@ struct ConstexprEval3 : ConstexprEval, ConstexprEval2 { constexpr ConstexprEval3 ce{4, "foobar"}; static_assert(ce.k == 'a', ""); static_assert(ce.k2 == 'x', ""); + + +struct TemplateCtors { + constexpr TemplateCtors() {} + template<template<int> class T> TemplateCtors(X<0>, T<0>); + template<int N> TemplateCtors(X<1>, X<N>); + template<typename T> TemplateCtors(X<2>, T); + + template<typename T = int> TemplateCtors(int, int = 0, int = 0); // expected-note {{inherited from here}} +}; + +struct UsingTemplateCtors : TemplateCtors { + using TemplateCtors::TemplateCtors; // expected-note 4{{here}} expected-note {{candidate}} + + constexpr UsingTemplateCtors(X<0>, X<0>) {} + constexpr UsingTemplateCtors(X<1>, X<1>) {} + constexpr UsingTemplateCtors(X<2>, X<2>) {} + + template<int = 0> constexpr UsingTemplateCtors(int) {} // expected-note {{candidate}} + template<typename T = void> constexpr UsingTemplateCtors(int, int) {} + template<typename T, typename U> constexpr UsingTemplateCtors(int, int, int) {} +}; + +template<int> struct Y {}; +constexpr UsingTemplateCtors uct1{ X<0>{}, X<0>{} }; +constexpr UsingTemplateCtors uct2{ X<0>{}, Y<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr UsingTemplateCtors uct3{ X<1>{}, X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr UsingTemplateCtors uct4{ X<1>{}, X<1>{} }; +constexpr UsingTemplateCtors uct5{ X<2>{}, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} +constexpr UsingTemplateCtors uct6{ X<2>{}, X<2>{} }; + +constexpr UsingTemplateCtors utc7{ 0 }; // expected-error {{ambiguous}} +constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok +constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} diff --git a/test/CXX/special/class.inhctor/p3.cpp b/test/CXX/special/class.inhctor/p3.cpp index f71ab16..7aaaa7a 100644 --- a/test/CXX/special/class.inhctor/p3.cpp +++ b/test/CXX/special/class.inhctor/p3.cpp @@ -46,3 +46,13 @@ struct U { friend T3<int>::T3(int); friend T3<int>::T3(int, int); }; + +struct B4 { + template<typename T> explicit B4(T, int = 0); +}; +template<typename T> struct T4 : B4 { + using B4::B4; // expected-note {{here}} + template<typename U> T4(U); +}; +T4<void> t4a = {0}; +T4<void> t4b = {0, 0}; // expected-error {{chosen constructor is explicit}} diff --git a/test/CXX/special/class.inhctor/p4.cpp b/test/CXX/special/class.inhctor/p4.cpp index eea3bf2..512705e 100644 --- a/test/CXX/special/class.inhctor/p4.cpp +++ b/test/CXX/special/class.inhctor/p4.cpp @@ -44,11 +44,13 @@ FA fa2{X<2>{}}; // expected-error {{calling a private constructor}} // It is deleted if the corresponding constructor [...] is deleted. struct G { G(int) = delete; + template<typename T> G(T*) = delete; }; struct H : G { - using G::G; // expected-note {{marked deleted here}} + using G::G; // expected-note 2{{marked deleted here}} }; -H h(5); // expected-error {{call to implicitly-deleted function of 'H'}} +H h1(5); // expected-error {{call to implicitly-deleted function of 'H'}} +H h2("foo"); // expected-error {{call to deleted constructor of 'H'}} // Core defect: It is also deleted if multiple base constructors generate the diff --git a/test/CXX/special/class.inhctor/p7.cpp b/test/CXX/special/class.inhctor/p7.cpp index 9ae160f..a57e855 100644 --- a/test/CXX/special/class.inhctor/p7.cpp +++ b/test/CXX/special/class.inhctor/p7.cpp @@ -27,3 +27,21 @@ template<typename T> struct B4 : B3<T>, B1 { }; B4<char> b4c; B4<int> b4i; // expected-note {{here}} + +struct B5 { + template<typename T> B5(T); // expected-note {{previous constructor}} +}; +struct B6 { + template<typename T> B6(T); // expected-note {{conflicting constructor}} +}; +struct B7 { + template<typename T, int> B7(T); +}; +struct D56 : B5, B6, B7 { + using B5::B5; // expected-note {{inherited here}} + using B6::B6; // expected-error {{already inherited}} +}; +struct D57 : B5, B6, B7 { + using B5::B5; + using B7::B7; // ok, not the same signature +}; diff --git a/test/CXX/special/class.inhctor/p8.cpp b/test/CXX/special/class.inhctor/p8.cpp index e2b07df..0c85738 100644 --- a/test/CXX/special/class.inhctor/p8.cpp +++ b/test/CXX/special/class.inhctor/p8.cpp @@ -19,3 +19,12 @@ constexpr B b0{0}; constexpr B b1{k}; static_assert(a0.rval && !a1.rval && b0.rval && !b1.rval, ""); + +struct C { + template<typename T> constexpr C(T t) : v(t) {} + int v; +}; +struct D : C { + using C::C; +}; +static_assert(D(123).v == 123, ""); diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp index 3952afd..b159a15 100644 --- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp +++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp @@ -242,3 +242,13 @@ void example() { for (int &x : array) x *= 2; } + +namespace rdar13712739 { + template<typename T> + void foo(const T& t) { + auto &x = t.get(); // expected-error{{member reference base type 'const int' is not a structure or union}} + for (auto &blah : x) { } + } + + template void foo(const int&); // expected-note{{in instantiation of function template specialization}} +} diff --git a/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp index d0f15d4..fda0c5c 100644 --- a/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp +++ b/test/CXX/stmt.stmt/stmt.select/stmt.switch/p2-0x.cpp @@ -3,12 +3,12 @@ struct Value { constexpr Value(int n) : n(n) {} - constexpr operator short() { return n; } + constexpr operator short() const { return n; } int n; }; enum E { E0, E1 }; struct Alt { - constexpr operator E() { return E0; } + constexpr operator E() const { return E0; } }; constexpr short s = Alt(); diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp index 59ce8b6..3f65466 100644 --- a/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp +++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp @@ -1,19 +1,23 @@ -// RUN: %clang_cc1 -std=c++11 %s -verify +// RUN: %clang_cc1 -std=c++11 %s -verify -triple x86_64-linux-gnu namespace std { typedef decltype(nullptr) nullptr_t; } -template<int *ip> struct IP { // expected-note 4 {{template parameter is declared here}} +template<int *ip> struct IP { // expected-note 5 {{template parameter is declared here}} IP<ip> *ip2; }; +template<int &ip> struct IR {}; + constexpr std::nullptr_t get_nullptr() { return nullptr; } constexpr std::nullptr_t np = nullptr; std::nullptr_t nonconst_np; // expected-note{{declared here}} +thread_local int tl; // expected-note {{refers here}} + IP<0> ip0; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} IP<(0)> ip1; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}} IP<nullptr> ip2; @@ -23,6 +27,9 @@ IP<np> ip5; IP<nonconst_np> ip5; // expected-error{{non-type template argument of type 'std::nullptr_t' (aka 'nullptr_t') is not a constant expression}} \ // expected-note{{read of non-constexpr variable 'nonconst_np' is not allowed in a constant expression}} IP<(float*)0> ip6; // expected-error{{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}} +IP<&tl> ip7; // expected-error{{non-type template argument of type 'int *' is not a constant expression}} + +IR<tl> ir1; // expected-error{{non-type template argument refers to thread-local object}} struct X { }; template<int X::*pm> struct PM { // expected-note 2 {{template parameter is declared here}} diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp index e0ffef5..82114cf 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp @@ -193,18 +193,18 @@ namespace PacksAtDifferentLevels { template<typename...A> struct X6 { template<typename...B> - constexpr auto f1(A ...a) -> decltype(g(A(a + B())...)) { return g(A(a + B())...); } + constexpr auto f1(A ...a) const -> decltype(g(A(a + B())...)) { return g(A(a + B())...); } template<typename...B> - constexpr auto f2(A ...a, B ...b) -> decltype(g((&a)[b] ...)) { return g((&a)[b] ...); } // expected-note {{past-the-end}} + constexpr auto f2(A ...a, B ...b) const -> decltype(g((&a)[b] ...)) { return g((&a)[b] ...); } // expected-note {{past-the-end}} template<typename...B> struct Inner { template<typename...C> - constexpr auto f(A ...a, B ...b, C ...c) -> decltype(g(a+b+c...)) { return g(a+b+c...); } + constexpr auto f(A ...a, B ...b, C ...c) const -> decltype(g(a+b+c...)) { return g(a+b+c...); } }; }; - struct A { constexpr operator int() { return 2; } }; - struct B { constexpr operator int() { return 1; } }; + struct A { constexpr operator int() const { return 2; } }; + struct B { constexpr operator int() const { return 1; } }; static_assert(X6<unsigned char, int>().f1<A, B>(255, 1) == 12, ""); static_assert(X6<int, int>().f2(3, 4, 0, 0) == 34, ""); diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp index e0c7b35..f804d4d 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp @@ -9,7 +9,7 @@ template inline void X<int>::f(); // expected-error{{explicit instantiation cann template<typename T> struct Y { - constexpr int f() { return 0; } + constexpr int f() { return 0; } // expected-warning{{C++1y}} }; template constexpr int Y<int>::f() const; // expected-error{{explicit instantiation cannot be 'constexpr'}} |