1 // RUN: %clang_cc1 -std=c++11 -verify %s
4 static const int a
= 1;
6 template<typename T
> struct S
: Base
{
8 constexpr int f() const;
9 constexpr int g() const;
12 template<> enum S
<char>::E
: int {}; // expected-note {{enum 'S<char>::E' was explicitly specialized here}}
13 template<> enum S
<short>::E
: int { b
= 2 };
14 template<> enum S
<int>::E
: int { a
= 4 };
15 template<typename T
> enum S
<T
>::E
: int { b
= 8 };
17 // The unqualified-id here names a member of the non-dependent base class Base
18 // and not the injected enumerator name 'a' from the specialization.
19 template<typename T
> constexpr int S
<T
>::f() const { return a
; }
20 static_assert(S
<char>().f() == 1, "");
21 static_assert(S
<int>().f() == 1, "");
23 // The unqualified-id here names a member of the current instantiation, which
24 // bizarrely might not exist in some instantiations.
25 template<typename T
> constexpr int S
<T
>::g() const { return b
; } // expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}}
26 static_assert(S
<char>().g() == 1, ""); // expected-note {{here}} expected-error {{not an integral constant expression}}
27 static_assert(S
<short>().g() == 2, "");
28 static_assert(S
<long>().g() == 8, "");
30 // 'b' is type-dependent, so these assertions should not fire before 'h' is
32 template<typename T
> void S
<T
>::h() {
34 static_assert(b
!= 8, "");
35 static_assert(sizeof(c
) != 8, "");
38 S
<short>().h(); // ok, b == 2