• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
2  // C++ [expr.const]p1:
3  //   In several places, C++ requires expressions that evaluate to an integral
4  //   or enumeration constant: as array bounds, as case expressions, as
5  //   bit-field lengths, as enumerator initializers, as static member
6  //   initializers, and as integral or enumeration non-type template arguments.
7  //   An integral constant-expression can involve only literals, enumerators,
8  //   const variables or static data members of integral or enumeration types
9  //   initialized with constant expressions, and sizeof expressions. Floating
10  //   literals can appear only if they are cast to integral or enumeration types.
11  
12  enum Enum { eval = 1 };
13  const int cval = 2;
14  const Enum ceval = eval;
15  struct Struct {
16    static const int sval = 3;
17    static const Enum seval = eval;
18  };
19  
20  template <int itval, Enum etval> struct C {
21    enum E {
22      v1 = 1,
23      v2 = eval,
24      v3 = cval,
25      v4 = ceval,
26      v5 = Struct::sval,
27      v6 = Struct::seval,
28      v7 = itval,
29      v8 = etval,
30      v9 = (int)1.5,
31      v10 = sizeof(Struct),
32      v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
33    };
34    unsigned
35      b1 : 1,
36      b2 : eval,
37      b3 : cval,
38      b4 : ceval,
39      b5 : Struct::sval,
40      b6 : Struct::seval,
41      b7 : itval,
42      b8 : etval,
43      b9 : (int)1.5,
44      b10 : sizeof(Struct),
45      b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
46      ;
47    static const int
48      i1 = 1,
49      i2 = eval,
50      i3 = cval,
51      i4 = ceval,
52      i5 = Struct::sval,
53      i6 = Struct::seval,
54      i7 = itval,
55      i8 = etval,
56      i9 = (int)1.5,
57      i10 = sizeof(Struct),
58      i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
59      ;
fC60    void f(int cond) {
61      switch(cond) {
62      case    0 + 1:
63      case  100 + eval:
64      case  200 + cval:
65      case  300 + ceval:
66      case  400 + Struct::sval:
67      case  500 + Struct::seval:
68      case  600 + itval:
69      case  700 + etval:
70      case  800 + (int)1.5:
71      case  900 + sizeof(Struct):
72      case 1000 + (true? 1 + cval * Struct::sval ^
73                   itval / (int)1.5 - sizeof(Struct) : 0):
74        ;
75      }
76    }
77    typedef C<itval, etval> T0;
78  };
79  
80  template struct C<1, eval>;
81  template struct C<cval, ceval>;
82  template struct C<Struct::sval, Struct::seval>;
83  
84  enum {
85    a = sizeof(int) == 8,
86    b = a? 8 : 4
87  };
88  
diags(int n)89  void diags(int n) {
90    switch (n) {
91      case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
92      case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
93      case __imag(1/0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
94      case (int)__imag((double)(1/0)): // expected-error {{not an integral constant expression}} expected-note {{division by zero}}
95        ;
96    }
97  }
98  
99  namespace IntOrEnum {
100    const int k = 0;
101    const int &p = k;
102    template<int n> struct S {};
103    S<p> s; // expected-error {{not an integral constant expression}}
104  }
105  
106  extern const int recurse1;
107  // recurse2 cannot be used in a constant expression because it is not
108  // initialized by a constant expression. The same expression appearing later in
109  // the TU would be a constant expression, but here it is not.
110  const int recurse2 = recurse1;
111  const int recurse1 = 1;
112  int array1[recurse1]; // ok
113  int array2[recurse2]; // expected-warning {{variable length array}} expected-warning {{integer constant expression}}
114  
115  namespace FloatConvert {
116    typedef int a[(int)42.3];
117    typedef int a[(int)42.997];
118    typedef int b[(long long)4e20]; // expected-warning {{variable length}} expected-error {{variable length}} expected-warning {{'long long' is a C++11 extension}}
119  }
120  
121  // PR12626
122  namespace test3 {
123    struct X; // expected-note {{forward declaration of 'test3::X'}}
124    struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
f()125    int f() { return Y().b; }
126  }
127