diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/SemaCXX/constant-expression.cpp | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/SemaCXX/constant-expression.cpp')
-rw-r--r-- | clang/test/SemaCXX/constant-expression.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/constant-expression.cpp b/clang/test/SemaCXX/constant-expression.cpp new file mode 100644 index 0000000..23a4dda --- /dev/null +++ b/clang/test/SemaCXX/constant-expression.cpp @@ -0,0 +1,119 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s +// C++ [expr.const]p1: +// In several places, C++ requires expressions that evaluate to an integral +// or enumeration constant: as array bounds, as case expressions, as +// bit-field lengths, as enumerator initializers, as static member +// initializers, and as integral or enumeration non-type template arguments. +// An integral constant-expression can involve only literals, enumerators, +// const variables or static data members of integral or enumeration types +// initialized with constant expressions, and sizeof expressions. Floating +// literals can appear only if they are cast to integral or enumeration types. + +enum Enum { eval = 1 }; +const int cval = 2; +const Enum ceval = eval; +struct Struct { + static const int sval = 3; + static const Enum seval = eval; +}; + +template <int itval, Enum etval> struct C { + enum E { + v1 = 1, + v2 = eval, + v3 = cval, + v4 = ceval, + v5 = Struct::sval, + v6 = Struct::seval, + v7 = itval, + v8 = etval, + v9 = (int)1.5, + v10 = sizeof(Struct), + v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0 + }; + unsigned + b1 : 1, + b2 : eval, + b3 : cval, + b4 : ceval, + b5 : Struct::sval, + b6 : Struct::seval, + b7 : itval, + b8 : etval, + b9 : (int)1.5, + b10 : sizeof(Struct), + b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0 + ; + static const int + i1 = 1, + i2 = eval, + i3 = cval, + i4 = ceval, + i5 = Struct::sval, + i6 = Struct::seval, + i7 = itval, + i8 = etval, + i9 = (int)1.5, + i10 = sizeof(Struct), + i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0 + ; + void f(int cond) { + switch(cond) { + case 0 + 1: + case 100 + eval: + case 200 + cval: + case 300 + ceval: + case 400 + Struct::sval: + case 500 + Struct::seval: + case 600 + itval: + case 700 + etval: + case 800 + (int)1.5: + case 900 + sizeof(Struct): + case 1000 + (true? 1 + cval * Struct::sval ^ + itval / (int)1.5 - sizeof(Struct) : 0): + ; + } + } + typedef C<itval, etval> T0; +}; + +template struct C<1, eval>; +template struct C<cval, ceval>; +template struct C<Struct::sval, Struct::seval>; + +enum { + a = sizeof(int) == 8, + b = a? 8 : 4 +}; + +void diags(int n) { + switch (n) { + case (1/0, 1): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} + case (int)(1/0, 2.0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} + case __imag(1/0): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} + case (int)__imag((double)(1/0)): // expected-error {{not an integral constant expression}} expected-note {{division by zero}} + ; + } +} + +namespace IntOrEnum { + const int k = 0; + const int &p = k; + template<int n> struct S {}; + S<p> s; // expected-error {{not an integral constant expression}} +} + +extern const int recurse1; +// recurse2 cannot be used in a constant expression because it is not +// initialized by a constant expression. The same expression appearing later in +// the TU would be a constant expression, but here it is not. +const int recurse2 = recurse1; +const int recurse1 = 1; +int array1[recurse1]; // ok +int array2[recurse2]; // expected-warning {{variable length array}} expected-warning {{integer constant expression}} + +namespace FloatConvert { + typedef int a[(int)42.3]; + typedef int a[(int)42.997]; + typedef int b[(int)4e10]; // expected-warning {{variable length}} expected-error {{variable length}} +} |