1b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith// RUN: %clang_cc1 -verify -std=c++11 %s
2b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith
3b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith// Unlike in C++98, C++11 allows unions to have static data members.
4b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith
5b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithunion U1 {
6b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  static constexpr int k1 = 0;
7b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  static const int k2 = k1;
8b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  static int k3 = k2; // expected-error {{non-const static data member must be initialized out of line}}
9b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  static constexpr double k4 = k2;
10a367e9de80eb05e78f06dc35c1e050799e735282David Blaikie  static const double k5 = k4; // expected-error {{requires 'constexpr' specifier}} expected-note {{add 'constexpr'}}
11b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  int n[k1 + 3];
12b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith};
13b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith
14b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithconstexpr int U1::k1;
15b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithconstexpr int U1::k2;
16b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithint U1::k3;
17b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith
18b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithconst double U1::k4;
19b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithconst double U1::k5;
20b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith
21b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithtemplate<typename T>
22b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithunion U2 {
23b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  static const int k1;
24b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  static double k2;
25b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  T t;
26b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith};
27b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithtemplate<typename T> constexpr int U2<T>::k1 = sizeof(U2<T>);
28b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithtemplate<typename T> double U2<T>::k2 = 5.3;
29b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith
30b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithstatic_assert(U2<int>::k1 == sizeof(int), "");
31b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithstatic_assert(U2<char>::k1 == sizeof(char), "");
32b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith
33b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smithunion U3 {
34b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  static const int k;
35b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith  U3() : k(0) {} // expected-error {{does not name a non-static data member}}
36b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith};
37449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith
38449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smithstruct S {
39449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith  union {
40449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith    static const int n; // expected-error {{static members cannot be declared in an anonymous union}}
41449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith    int a;
42449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith    int b;
43449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith  };
44449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith};
45449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smithstatic union {
46449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith  static const int k; // expected-error {{static members cannot be declared in an anonymous union}}
47449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith  int n;
48449d4f06fe7501ed53e3aaaa465a499442285e90Richard Smith};
49