// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors namespace dr705 { // dr705: yes namespace N { struct S {}; void f(S); // expected-note {{declared here}} } void g() { N::S s; f(s); // ok (f)(s); // expected-error {{use of undeclared}} } } namespace dr712 { // dr712: partial void use(int); void f() { const int a = 0; // expected-note 5{{here}} struct X { void g(bool cond) { use(a); use((a)); use(cond ? a : a); use((cond, a)); // expected-warning 2{{unused}} FIXME: should only warn once (void)a; // FIXME: expected-error {{declared in enclosing}} (void)(a); // FIXME: expected-error {{declared in enclosing}} (void)(cond ? a : a); // FIXME: expected-error 2{{declared in enclosing}} (void)(cond, a); // FIXME: expected-error {{declared in enclosing}} expected-warning {{unused}} } }; } #if __cplusplus >= 201103L void g() { struct A { int n; }; constexpr A a = {0}; // expected-note 2{{here}} struct X { void g(bool cond) { use(a.n); use(a.*&A::n); (void)a.n; // FIXME: expected-error {{declared in enclosing}} (void)(a.*&A::n); // FIXME: expected-error {{declared in enclosing}} } }; } #endif } namespace dr727 { // dr727: partial struct A { template struct C; // expected-note 6{{here}} template void f(); // expected-note {{here}} template static int N; // expected-error 0-1{{C++14}} expected-note 6{{here}} template<> struct C; template<> void f(); template<> static int N; template struct C; template static int N; struct B { template<> struct C; // expected-error {{not in class 'A' or an enclosing namespace}} template<> void f(); // expected-error {{no function template matches}} template<> static int N; // expected-error {{not in class 'A' or an enclosing namespace}} template struct C; // expected-error {{not in class 'A' or an enclosing namespace}} template static int N; // expected-error {{not in class 'A' or an enclosing namespace}} template<> struct A::C; // expected-error {{not in class 'A' or an enclosing namespace}} template<> void A::f(); // expected-error {{no function template matches}} expected-error {{cannot have a qualified name}} template<> static int A::N; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}} template struct A::C; // expected-error {{not in class 'A' or an enclosing namespace}} template static int A::N; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}} }; }; template<> struct A::C; template<> void A::f(); template<> int A::N; template struct A::C; template int A::N; namespace C { template<> struct A::C; // expected-error {{not in class 'A' or an enclosing namespace}} template<> void A::f(); // expected-error {{not in class 'A' or an enclosing namespace}} template<> int A::N; // expected-error {{not in class 'A' or an enclosing namespace}} template struct A::C; // expected-error {{not in class 'A' or an enclosing namespace}} template int A::N; // expected-error {{not in class 'A' or an enclosing namespace}} } template struct D { template struct C { typename T::error e; }; // expected-error {{no members}} template void f() { T::error; } // expected-error {{no members}} template static const int N = T::error; // expected-error {{no members}} expected-error 0-1{{C++14}} template<> struct C {}; template<> void f() {} template<> static const int N; template struct C {}; template static const int N; }; void d(D di) { D::C(); di.f(); int a = D::N; D::C(); int b = D::N; D::C(); // expected-note {{instantiation of}} di.f(); // expected-note {{instantiation of}} int c = D::N; // expected-note {{instantiation of}} } namespace mixed_inner_outer_specialization { #if __cplusplus >= 201103L template struct A { template constexpr int f() const { return 1; } template<> constexpr int f<0>() const { return 2; } }; template<> template constexpr int A<0>::f() const { return 3; } template<> template<> constexpr int A<0>::f<0>() const { return 4; } static_assert(A<1>().f<1>() == 1, ""); static_assert(A<1>().f<0>() == 2, ""); static_assert(A<0>().f<1>() == 3, ""); static_assert(A<0>().f<0>() == 4, ""); #endif #if __cplusplus >= 201402L template struct B { template static const int u = 1; template<> static const int u<0> = 2; // expected-note {{here}} // Note that in C++17 onwards, these are implicitly inline, and so the // initializer of v<0> is not instantiated with the declaration. In // C++14, v<0> is a non-defining declaration and its initializer is // instantiated with the class. template static constexpr int v = 1; template<> static constexpr int v<0> = 2; // #v0 template static const inline int w = 1; // expected-error 0-1{{C++17 extension}} template<> static const inline int w<0> = 2; // expected-error 0-1{{C++17 extension}} }; template<> template constexpr int B<0>::u = 3; template<> template<> constexpr int B<0>::u<0> = 4; // expected-error {{already has an initializer}} template<> template constexpr int B<0>::v = 3; template<> template<> constexpr int B<0>::v<0> = 4; #if __cplusplus < 201702L // expected-error@-2 {{already has an initializer}} // expected-note@#v0 {{here}} #endif template<> template constexpr int B<0>::w = 3; template<> template<> constexpr int B<0>::w<0> = 4; static_assert(B<1>().u<1> == 1, ""); static_assert(B<1>().u<0> == 2, ""); static_assert(B<0>().u<1> == 3, ""); static_assert(B<1>().v<1> == 1, ""); static_assert(B<1>().v<0> == 2, ""); static_assert(B<0>().v<1> == 3, ""); static_assert(B<0>().v<0> == 4, ""); #if __cplusplus < 201702L // expected-error@-2 {{failed}} #endif static_assert(B<1>().w<1> == 1, ""); static_assert(B<1>().w<0> == 2, ""); static_assert(B<0>().w<1> == 3, ""); static_assert(B<0>().w<0> == 4, ""); #endif } template struct Collision { // FIXME: Missing diagnostic for duplicate function explicit specialization declaration. template int f1(); template<> int f1(); template<> int f1(); // FIXME: Missing diagnostic for fucntion redefinition! template int f2(); template<> int f2() {} template<> int f2() {} template static int v1; // expected-error 0-1{{C++14 extension}} template<> static int v1; // expected-note {{previous}} template<> static int v1; // expected-error {{duplicate member}} template static inline int v2; // expected-error 0-1{{C++17 extension}} expected-error 0-1{{C++14 extension}} template<> static inline int v2; // expected-error 0-1{{C++17 extension}} expected-note {{previous}} template<> static inline int v2; // expected-error 0-1{{C++17 extension}} expected-error {{duplicate member}} // FIXME: Missing diagnostic for duplicate class explicit specialization. template struct S1; template<> struct S1; template<> struct S1; template struct S2; template<> struct S2 {}; // expected-note {{previous}} template<> struct S2 {}; // expected-error {{redefinition}} }; Collision c; // expected-note {{in instantiation of}} } namespace dr777 { // dr777: 3.7 #if __cplusplus >= 201103L template void f(int i = 0, T ...args) {} void ff() { f(); } template void g(int i = 0, T ...args, T ...args2) {} template void h(int i = 0, T ...args, int j = 1) {} #endif }