p3.cpp revision eb96af8a908ea28b2ca76e3848b2476852f592a6
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3struct NonLit {
4  NonLit();
5};
6
7struct S {
8  static constexpr int a = 0;
9  static constexpr int b; // expected-error {{declaration of constexpr static data member 'b' requires an initializer}}
10
11  static constexpr int c = 0;
12  static const int d;
13  static const int d2 = 0;
14
15  static constexpr double e = 0.0; // ok
16  static const double f = 0.0; // expected-warning {{extension}} expected-note {{use 'constexpr' specifier}}
17  static char *const g = 0; // expected-error {{requires 'constexpr' specifier}}
18  static const NonLit h = NonLit(); // expected-error {{must be initialized out of line}}
19};
20
21constexpr int S::a;
22constexpr int S::b = 0;
23
24const int S::c;
25constexpr int S::d = 0;
26constexpr int S::d2;
27
28template<typename T>
29struct U {
30  static constexpr int a = 0;
31  static constexpr int b; // expected-error {{declaration of constexpr static data member 'b' requires an initializer}}
32  // FIXME: It'd be nice to error on this at template definition time.
33  static constexpr NonLit h = NonLit(); // expected-error 2{{must be initialized by a constant expression}} expected-note 2{{non-literal type}}
34  static constexpr T c = T(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type}}
35  static const T d;
36};
37
38template<typename T> constexpr T U<T>::d = T(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type 'const NonLit'}}
39
40U<int> u1; // expected-note {{here}}
41U<NonLit> u2; // expected-note {{here}}
42
43static_assert(U<int>::a == 0, "");
44
45constexpr int outofline = (U<NonLit>::d, 0); // expected-note {{here}} expected-warning {{unused}}
46