brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · ef48ee5 Raw
161 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s2// C++ [expr.const]p1:3//   In several places, C++ requires expressions that evaluate to an integral4//   or enumeration constant: as array bounds, as case expressions, as5//   bit-field lengths, as enumerator initializers, as static member6//   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 types9//   initialized with constant expressions, and sizeof expressions. Floating10//   literals can appear only if they are cast to integral or enumeration types.11 12enum Enum { eval = 1 };13const int cval = 2;14const Enum ceval = eval;15struct Struct {16  static const int sval = 3;17  static const Enum seval = eval;18};19 20template <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) : 033  };34  unsigned35    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) : 046    ;47  static const int48    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) : 059    ;60  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 80template struct C<1, eval>;81template struct C<cval, ceval>;82template struct C<Struct::sval, Struct::seval>;83 84enum {85  a = sizeof(int) == 8,86  b = a? 8 : 487};88 89void diags(int n) {90  switch (n) {91    case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} expected-warning {{left operand of comma operator has no effect}}92    case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} expected-warning {{left operand of comma operator has no effect}}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 99namespace IntOrEnum {100  const int k = 0;101  const int &p = k; // expected-note {{declared here}}102  template<int n> struct S {};103  S<p> s; // expected-error {{not an integral constant expression}} expected-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}}104}105 106extern const int recurse1;107// recurse2 cannot be used in a constant expression because it is not108// initialized by a constant expression. The same expression appearing later in109// the TU would be a constant expression, but here it is not.110const int recurse2 = recurse1; // expected-note {{here}}111const int recurse1 = 1;112int array1[recurse1]; // ok113int array2[recurse2]; // expected-warning 2{{variable length array}} expected-note {{initializer of 'recurse2' is not a constant expression}}114 115namespace 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}} expected-note {{value 4.0E+20 is outside the range of representable values}}119}120 121// PR12626122namespace test3 {123  struct X; // expected-note {{forward declaration of 'test3::X'}}124  struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'X'}}125  int f() { return Y().b; }126}127 128// PR18283129namespace test4 {130  template <int> struct A {};131  int const i = { 42 };132  // i can be used as non-type template-parameter as "const int x = { 42 };" is133  // equivalent to "const int x = 42;" as per C++03 8.5/p13.134  typedef A<i> Ai; // ok135}136 137namespace rdar16064952 {138  template < typename T > void fn1() {139   T b;140   unsigned w = ({int a = b.val[sizeof(0)]; 0; }); // expected-warning {{use of GNU statement expression extension}}141  }142}143 144char PR17381_ice = 1000000 * 1000000; // expected-warning {{overflow}} expected-warning {{changes value}}145 146namespace PR31701 {147  struct C {148    template<int i> static int n; // expected-warning {{extension}}149  };150  template <int M> class D;151  template <int M>152  template<int i> void D<M>::set() { // expected-error {{from class 'PR31701::D<M>' without definition}}153    const C c = C::n<i>;154  }155}156 157struct PR65784s{158  int *ptr;159} const PR65784[] = {(int *)""};160PR65784s PR65784f() { return *PR65784; }161