constant-expression-cxx11.cpp revision 1bf9a9e6a5bdc0de7939908855dcddf46b661800
159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// RUN: %clang_cc1 -triple i686-linux -fsyntax-only -verify -std=c++11 %s
259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// This version of static_assert just requires a foldable value as the
459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// expression, not an ICE.
559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: Once we implement the C++11 ICE rules, most uses of this here should
659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// be converted to static_assert.
759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith#define static_assert_fold(expr, str) \
859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    static_assert(__builtin_constant_p(expr), "not an integral constant expression"); \
959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    static_assert(__builtin_constant_p(expr) ? expr : true, str)
1059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
1159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace StaticAssertFoldTest {
1259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
1359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithint x;
1459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(++x, "test"); // expected-error {{not an integral constant expression}}
1559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(false, "test"); // expected-error {{test}}
1659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
1759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
1859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
1959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: support const T& parameters here.
2059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith//template<typename T> constexpr T id(const T &t) { return t; }
2159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithtemplate<typename T> constexpr T id(T t) { return t; }
2259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: support templates here.
2359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith//template<typename T> constexpr T min(const T &a, const T &b) {
2459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith//  return a < b ? a : b;
2559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith//}
2659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith//template<typename T> constexpr T max(const T &a, const T &b) {
2759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith//  return a < b ? b : a;
2859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith//}
2959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int min(const int &a, const int &b) { return a < b ? a : b; }
3059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int max(const int &a, const int &b) { return a < b ? b : a; }
3159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
3259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct MemberZero {
3359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int zero() { return 0; }
3459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
3559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
3659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace DerivedToVBaseCast {
3759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
3859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct U { int n; };
3959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct V : U { int n; };
4059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct A : virtual V { int n; };
4159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct Aa { int n; };
4259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct B : virtual A, Aa {};
4359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct C : virtual A, Aa {};
4459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct D : B, C {};
4559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
4659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  D d;
4759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr B *p = &d;
4859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr C *q = &d;
4959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((void*)p != (void*)q, "");
5059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((A*)p == (A*)q, "");
5159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((Aa*)p != (Aa*)q, "");
5259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
5359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr B &pp = d;
5459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr C &qq = d;
5559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((void*)&pp != (void*)&qq, "");
5659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(&(A&)pp == &(A&)qq, "");
5759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(&(Aa&)pp != &(Aa&)qq, "");
5859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
5959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr V *v = p;
6059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr V *w = q;
6159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr V *x = (A*)p;
6259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(v == w, "");
6359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(v == x, "");
6459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
6559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((U*)&d == p, "");
6659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((U*)&d == q, "");
6759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((U*)&d == v, "");
6859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((U*)&d == w, "");
6959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((U*)&d == x, "");
7059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
7159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct X {};
7259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct Y1 : virtual X {};
7359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct Y2 : X {};
7459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct Z : Y1, Y2 {};
7559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  Z z;
7659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold((X*)(Y1*)&z != (X*)(Y2*)&z, "");
7759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
7859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
7959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
80f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithnamespace ConstCast {
81f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smith
82f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr int n1 = 0;
83f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr int n2 = const_cast<int&>(n1);
84f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr int *n3 = const_cast<int*>(&n1);
85f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr int n4 = *const_cast<int*>(&n1);
86f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr const int * const *n5 = const_cast<const int* const*>(&n3);
87f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr int **n6 = const_cast<int**>(&n3);
88f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr int n7 = **n5;
89f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smithconstexpr int n8 = **n6;
90f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smith
91f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smith}
92f64699e8db3946e21b5f4a0421cbc58a3e439599Richard Smith
9359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace TemplateArgumentConversion {
9459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  template<int n> struct IntParam {};
9559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
9659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  using IntParam0 = IntParam<0>;
9759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  // FIXME: This should be accepted once we do constexpr function invocation.
9859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  using IntParam0 = IntParam<id(0)>; // expected-error {{not an integral constant expression}}
9959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}} expected-error {{not an integral constant expression}}
10059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
10159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
10259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace CaseStatements {
10359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  void f(int n) {
10459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    switch (n) {
10559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    // FIXME: Produce the 'add ()' fixit for this.
10659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    case MemberZero().zero: // desired-error {{did you mean to call it with no arguments?}} expected-error {{not an integer constant expression}}
10759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    // FIXME: This should be accepted once we do constexpr function invocation.
10859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    case id(1): // expected-error {{not an integer constant expression}}
10959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith      return;
11059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    }
11159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
11259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
11359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
11459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithextern int &Recurse1;
11559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithint &Recurse2 = Recurse1, &Recurse1 = Recurse2;
11659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}}
11759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
11859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace MemberEnum {
11959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct WithMemberEnum {
12059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    enum E { A = 42 };
12159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  } wme;
12259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
12359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(wme.A == 42, "");
12459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
12559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
12659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace DefaultArguments {
12759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
12859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconst int z = int();
12959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int Sum(int a = 0, const int &b = 0, const int *c = &z, char d = 0) {
13059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return a + b + *c + d;
13159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
13259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconst int four = 4;
13359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int eight = 8;
13459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const int twentyseven = 27;
13559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(Sum() == 0, "");
13659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(Sum(1) == 1, "");
13759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(Sum(1, four) == 5, "");
13859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(Sum(1, eight, &twentyseven) == 36, "");
13959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(Sum(1, 2, &four, eight) == 15, "");
14059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
14159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
14259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
14359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace Ellipsis {
14459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
14559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// Note, values passed through an ellipsis can't actually be used.
14659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int F(int a, ...) { return a; }
14759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(F(0) == 0, "");
14859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(F(1, 0) == 1, "");
14959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(F(2, "test") == 2, "");
15059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(F(3, &F) == 3, "");
15159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithint k = 0;
15259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(F(4, k) == 3, ""); // expected-error {{constant expression}}
15359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
15459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
15559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
15659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace Recursion {
15759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int fib(int n) { return n > 1 ? fib(n-1) + fib(n-2) : n; }
15859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(fib(11) == 89, "");
15959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
16059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int gcd_inner(int a, int b) {
16159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return b == 0 ? a : gcd_inner(b, a % b);
16259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
16359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int gcd(int a, int b) {
16459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return gcd_inner(max(a, b), min(a, b));
16559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
16659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
16759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(gcd(1749237, 5628959) == 7, "");
16859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
16959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
17059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace FunctionCast {
17159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  // When folding, we allow functions to be cast to different types. Such
17259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  // cast functions cannot be called, even if they're constexpr.
17359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int f() { return 1; }
17459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  typedef double (*DoubleFn)();
17559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  typedef int (*IntFn)();
17659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}}
17759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int b[(int)IntFn(f)()];    // ok
17859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
17959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
18059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace StaticMemberFunction {
18159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct S {
18259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    static constexpr int k = 42;
18359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    static constexpr int f(int n) { return n * k + 2; }
18459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  } s;
18559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
18659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int n = s.f(19);
18759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(S::f(19) == 800, "");
18859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(s.f(19) == 800, "");
18959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(n == 800, "");
1901bf9a9e6a5bdc0de7939908855dcddf46b661800Richard Smith
1911bf9a9e6a5bdc0de7939908855dcddf46b661800Richard Smith  constexpr int (*sf1)(int) = &S::f;
1921bf9a9e6a5bdc0de7939908855dcddf46b661800Richard Smith  constexpr int (*sf2)(int) = &s.f;
1931bf9a9e6a5bdc0de7939908855dcddf46b661800Richard Smith  constexpr const int *sk = &s.k;
19459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
19559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
19659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace ParameterScopes {
19759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
19859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  const int k = 42;
19959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr const int &ObscureTheTruth(const int &a) { return a; }
20059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr const int &MaybeReturnJunk(bool b, const int a) {
20159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return ObscureTheTruth(b ? a : k);
20259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
20359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(MaybeReturnJunk(false, 0) == 42, ""); // ok
20459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}}
20559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
20659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr const int MaybeReturnNonstaticRef(bool b, const int a) {
20759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    // If ObscureTheTruth returns a reference to 'a', the result is not a
20859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    // constant expression even though 'a' is still in scope.
20959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return ObscureTheTruth(b ? a : k);
21059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
21159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok
21259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int b = MaybeReturnNonstaticRef(true, 0); // expected-error {{constant expression}}
21359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
21459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int InternalReturnJunk(int n) {
21559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    // FIXME: We should reject this: it never produces a constant expression.
21659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return MaybeReturnJunk(true, n);
21759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
21859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}}
21959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
22059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int LToR(int &n) { return n; }
22159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int GrabCallersArgument(bool which, int a, int b) {
22259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return LToR(which ? b : a);
22359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
22459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(GrabCallersArgument(false, 1, 2) == 1, "");
22559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(GrabCallersArgument(true, 4, 8) == 8, "");
22659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
22759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
22859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
22959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace Pointers {
23059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
23159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int f(int n, const int *a, const int *b, const int *c) {
23259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return n == 0 ? 0 : *a + f(n-1, b, c, a);
23359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
23459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
23559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  const int x = 1, y = 10, z = 100;
23659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(f(23, &x, &y, &z) == 788, "");
23759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
23859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int g(int n, int a, int b, int c) {
23959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return f(n, &a, &b, &c);
24059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
24159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(g(23, x, y, z) == 788, "");
24259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
24359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
24459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
24559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace FunctionPointers {
24659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
24759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int Double(int n) { return 2 * n; }
24859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int Triple(int n) { return 3 * n; }
24959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int Twice(int (*F)(int), int n) { return F(F(n)); }
25059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int Quadruple(int n) { return Twice(Double, n); }
25159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr auto Select(int n) -> int (*)(int) {
25259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0;
25359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
25459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int Apply(int (*F)(int), int n) { return F(n); }
25559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
25659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  static_assert_fold(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, "");
25759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
25859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}}
25959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
26059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
26159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
26259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace PointerComparison {
26359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
26459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithint x, y;
26559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x == &y, "false"); // expected-error {{false}}
26659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x != &y, "");
26759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool g1 = &x == &y;
26859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool g2 = &x != &y;
26959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool g3 = &x <= &y; // expected-error {{must be initialized by a constant expression}}
27059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool g4 = &x >= &y; // expected-error {{must be initialized by a constant expression}}
27159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool g5 = &x < &y; // expected-error {{must be initialized by a constant expression}}
27259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool g6 = &x > &y; // expected-error {{must be initialized by a constant expression}}
27359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
27459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct S { int x, y; } s;
27559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&s.x == &s.y, "false"); // expected-error {{false}}
27659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&s.x != &s.y, "");
27759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&s.x <= &s.y, "");
27859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&s.x >= &s.y, "false"); // expected-error {{false}}
27959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&s.x < &s.y, "");
28059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&s.x > &s.y, "false"); // expected-error {{false}}
28159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
28259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(0 == &y, "false"); // expected-error {{false}}
28359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(0 != &y, "");
28459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n3 = 0 <= &y; // expected-error {{must be initialized by a constant expression}}
28559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n4 = 0 >= &y; // expected-error {{must be initialized by a constant expression}}
28659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n5 = 0 < &y; // expected-error {{must be initialized by a constant expression}}
28759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n6 = 0 > &y; // expected-error {{must be initialized by a constant expression}}
28859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
28959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x == 0, "false"); // expected-error {{false}}
29059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x != 0, "");
29159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n9 = &x <= 0; // expected-error {{must be initialized by a constant expression}}
29259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n10 = &x >= 0; // expected-error {{must be initialized by a constant expression}}
29359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n11 = &x < 0; // expected-error {{must be initialized by a constant expression}}
29459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool n12 = &x > 0; // expected-error {{must be initialized by a constant expression}}
29559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
29659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x == &x, "");
29759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x != &x, "false"); // expected-error {{false}}
29859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x <= &x, "");
29959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x >= &x, "");
30059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x < &x, "false"); // expected-error {{false}}
30159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&x > &x, "false"); // expected-error {{false}}
30259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
30359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr S* sptr = &s;
30459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: This is not a constant expression; check we reject this and move this
30559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// test elsewhere.
30659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool dyncast = sptr == dynamic_cast<S*>(sptr);
30759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
30859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithextern char externalvar[];
30959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: This is not a constant expression; check we reject this and move this
31059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// test elsewhere.
31159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool constaddress = (void *)externalvar == (void *)0x4000UL;  // expected-error {{must be initialized by a constant expression}}
31259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}}
31359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(0 != "foo", "");
31459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
31559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
31659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
31759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace MaterializeTemporary {
31859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
31959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int f(const int &r) { return r; }
32059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int n = f(1);
32159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
32259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool same(const int &a, const int &b) { return &a == &b; }
32359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool sameTemporary(const int &n) { return same(n, n); }
32459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
32559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(n, "");
32659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(!same(4, 4), "");
32759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(same(n, n), "");
32859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(sameTemporary(9), "");
32959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
33059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
33159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
33259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int strcmp_ce(const char *p, const char *q) {
33359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return (!*p || *p != *q) ? *p - *q : strcmp_ce(p+1, q+1);
33459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
33559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
33659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace StringLiteral {
33759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
33859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: Refactor this once we support constexpr templates.
33959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int MangleChars(const char *p) {
34059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return *p + 3 * (*p ? MangleChars(p+1) : 0);
34159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
34259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int MangleChars(const char16_t *p) {
34359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return *p + 3 * (*p ? MangleChars(p+1) : 0);
34459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
34559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int MangleChars(const char32_t *p) {
34659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return *p + 3 * (*p ? MangleChars(p+1) : 0);
34759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
34859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
34959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(MangleChars("constexpr!") == 1768383, "");
35059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(MangleChars(u"constexpr!") == 1768383, "");
35159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(MangleChars(U"constexpr!") == 1768383, "");
35259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
35359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr char c0 = "nought index"[0];
35459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr char c1 = "nice index"[10];
35559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{indexes past the end}}
35659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{indexes before the beginning}}
35759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}}
35859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
35959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const char *p = "test" + 2;
36059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(*p == 's', "");
36159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
36259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const char *max_iter(const char *a, const char *b) {
36359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return *a < *b ? b : a;
36459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
36559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const char *max_element(const char *a, const char *b) {
36659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return (a+1 >= b) ? a : max_iter(a, max_element(a+1, b));
36759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
36859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
36959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const char *begin(const char (&arr)[45]) { return arr; }
37059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const char *end(const char (&arr)[45]) { return arr + 45; }
37159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
37259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr char str[] = "the quick brown fox jumped over the lazy dog";
37359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const char *max = max_element(begin(str), end(str));
37459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(*max == 'z', "");
37559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(max == str + 38, "");
37659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
37759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(strcmp_ce("hello world", "hello world") == 0, "");
37859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(strcmp_ce("hello world", "hello clang") > 0, "");
37959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(strcmp_ce("constexpr", "test") < 0, "");
38059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(strcmp_ce("", " ") < 0, "");
38159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
38259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
38359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
38459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace Array {
38559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
38659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: Use templates for these once we support constexpr templates.
38759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int Sum(const int *begin, const int *end) {
38859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return begin == end ? 0 : *begin + Sum(begin+1, end);
38959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
39059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const int *begin(const int (&xs)[5]) { return xs; }
39159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const int *end(const int (&xs)[5]) { return xs + 5; }
39259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
39359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int xs[] = { 1, 2, 3, 4, 5 };
39459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int ys[] = { 5, 4, 3, 2, 1 };
39559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int sum_xs = Sum(begin(xs), end(xs));
39659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(sum_xs == 15, "");
39759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
39859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int ZipFoldR(int (*F)(int x, int y, int c), int n,
39959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith                       const int *xs, const int *ys, int c) {
40059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return n ? F(*xs, *ys, ZipFoldR(F, n-1, xs+1, ys+1, c)) : c;
40159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
40259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int MulAdd(int x, int y, int c) { return x * y + c; }
40359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int InnerProduct = ZipFoldR(MulAdd, 5, xs, ys, 0);
40459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(InnerProduct == 35, "");
40559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
40659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int SubMul(int x, int y, int c) { return (x - y) * c; }
40759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int DiffProd = ZipFoldR(SubMul, 2, xs+3, ys+3, 1);
40859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(DiffProd == 8, "");
40959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // expected-error {{constant expression}}
41059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
41159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const int *p = xs + 3;
41259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int xs4 = p[1]; // ok
41359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int xs5 = p[2]; // expected-error {{constant expression}}
41459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int xs0 = p[-3]; // ok
41559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int xs_1 = p[-4]; // expected-error {{constant expression}}
41659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
41759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
41859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(zs[0][0][0][0] == 1, "");
41959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(zs[1][1][1][1] == 16, "");
42059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}}
42159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold((&zs[0][0][0][2])[-1] == 2, "");
42259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(**(**(zs + 1) + 1) == 11, "");
42359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][-1] + 1) == 11, "");
42459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
42559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int arr[40] = { 1, 2, 3, [8] = 4 };
42659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int SumNonzero(const int *p) {
42759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return *p + (*p ? SumNonzero(p+1) : 0);
42859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
42959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int CountZero(const int *p, const int *q) {
43059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return p == q ? 0 : (*p == 0) + CountZero(p+1, q);
43159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
43259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(SumNonzero(arr) == 6, "");
43359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(CountZero(arr, arr + 40) == 36, "");
43459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
43559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
43659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
43759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace DependentValues {
43859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
43959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct I { int n; typedef I V[10]; };
44059efe266b804330f4c1f3a1b0ff783e67dd90378Richard SmithI::V x, y;
44159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithtemplate<bool B> struct S {
44259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int k;
44359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  void f() {
44459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    I::V &cells = B ? x : y;
44559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    I &i = cells[k];
44659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    switch (i.n) {}
44759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
44859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
44959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
45059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
45159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
45259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace Class {
45359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
45459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct A { constexpr A(int a, int b) : k(a + b) {} int k; };
45559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int fn(const A &a) { return a.k; }
45659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(fn(A(4,5)) == 9, "");
45759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
45859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct B { int n; int m; } constexpr b = { 0, b.n }; // expected-warning {{uninitialized}}
45959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct C {
46059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr C(C *this_) : m(42), n(this_->m) {} // ok
46159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int m, n;
46259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
46359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct D {
46459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  C c;
46559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr D() : c(&c) {}
46659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
46759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(D().c.n == 42, "");
46859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
46959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct E {
47059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr E() : p(&p) {}
47159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  void *p;
47259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
47359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr const E &e1 = E(); // expected-error {{constant expression}}
47459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// This is a constant expression if we elide the copy constructor call, and
47559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// is not a constant expression if we don't! But we do, so it is.
47659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: The move constructor is not currently implicitly defined as constexpr.
47759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// We notice this when evaluating an expression which uses it, but not when
47859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// checking its initializer.
47959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr E e2 = E(); // unexpected-error {{constant expression}}
48059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(e2.p == &e2.p, ""); // unexpected-error {{constant expression}}
48159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// FIXME: We don't pass through the fact that 'this' is ::e3 when checking the
48259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith// initializer of this declaration.
48359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr E e3; // unexpected-error {{constant expression}}
48459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(e3.p == &e3.p, "");
48559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
48659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithextern const class F f;
48759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct F {
48859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr F() : p(&f.p) {}
48959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  const void *p;
49059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
49159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr F f = F();
49259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
49359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct G {
49459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  struct T {
49559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    constexpr T(T *p) : u1(), u2(p) {}
49659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    union U1 {
49759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith      constexpr U1() {}
49859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith      int a, b = 42;
49959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    } u1;
50059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    union U2 {
50159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith      constexpr U2(T *p) : c(p->u1.b) {}
50259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith      int c, d;
50359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    } u2;
50459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  } t;
50559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr G() : t(&t) {}
50659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith} constexpr g;
50759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
50859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(g.t.u1.a == 42, ""); // expected-error {{constant expression}}
50959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(g.t.u1.b == 42, "");
51059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(g.t.u2.c == 42, "");
51159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(g.t.u2.d == 42, ""); // expected-error {{constant expression}}
51259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
51359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct S {
51459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int a, b;
51559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  const S *p;
51659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  double d;
51759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  const char *q;
51859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
51959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr S(int n, const S *p) : a(5), b(n), p(p), d(n), q("hello") {}
52059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
52159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
52259efe266b804330f4c1f3a1b0ff783e67dd90378Richard SmithS global(43, &global);
52359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
52459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(S(15, &global).b == 15, "");
52559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
52659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool CheckS(const S &s) {
52759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return s.a == 5 && s.b == 27 && s.p == &global && s.d == 27. && s.q[3] == 'l';
52859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
52959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(CheckS(S(27, &global)), "");
53059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
53159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct Arr {
53259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  char arr[3];
53359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr Arr() : arr{'x', 'y', 'z'} {}
53459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
53559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int hash(Arr &&a) {
53659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return a.arr[0] + a.arr[1] * 0x100 + a.arr[2] * 0x10000;
53759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
53859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr int k = hash(Arr());
53959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(k == 0x007a7978, "");
54059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
54159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
54259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct AggregateInit {
54359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  const char &c;
54459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int n;
54559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  double d;
54659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int arr[5];
54759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  void *p;
54859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
54959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
55059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr AggregateInit agg1 = { "hello"[0] };
55159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
55259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(strcmp_ce(&agg1.c, "hello") == 0, "");
55359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(agg1.n == 0, "");
55459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(agg1.d == 0.0, "");
55559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(agg1.arr[-1] == 0, ""); // expected-error {{constant expression}}
55659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(agg1.arr[0] == 0, "");
55759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(agg1.arr[4] == 0, "");
55859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(agg1.arr[5] == 0, ""); // expected-error {{constant expression}}
55959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(agg1.p == nullptr, "");
56059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
56159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace SimpleDerivedClass {
56259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
56359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct B {
56459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr B(int n) : a(n) {}
56559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int a;
56659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
56759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct D : B {
56859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr D(int n) : B(n) {}
56959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
57059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr D d(3);
57159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(d.a == 3, "");
57259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
57359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
57459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
57559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct Base {
57659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr Base(int a = 42, const char *b = "test") : a(a), b(b) {}
57759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int a;
57859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  const char *b;
57959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
58059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct Base2 {
58159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr Base2(const int &r) : r(r) {}
58259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int q = 123;
58359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  // FIXME: When we track the global for which we are computing the initializer,
58459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  // use a reference here.
58559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  //const int &r;
58659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int r;
58759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
58859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstruct Derived : Base, Base2 {
58959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr Derived() : Base(76), Base2(a) {}
59059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int c = r + b[1];
59159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
59259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
59359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr bool operator==(const Base &a, const Base &b) {
59459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return a.a == b.a && strcmp_ce(a.b, b.b) == 0;
59559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
59659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
59759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr Base base;
59859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr Base base2(76);
59959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr Derived derived;
60059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(derived.a == 76, "");
60159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(derived.b[2] == 's', "");
60259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(derived.c == 76 + 'e', "");
60359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(derived.q == 123, "");
60459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(derived.r == 76, "");
60559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(&derived.r == &derived.a, ""); // expected-error {{}}
60659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
60759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(!(derived == base), "");
60859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(derived == base2, "");
60959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
61059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
61159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
61259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace Union {
61359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
61459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithunion U {
61559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int a;
61659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int b;
61759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
61859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
61959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr U u[4] = { { .a = 0 }, { .b = 1 }, { .a = 2 }, { .b = 3 } };
62059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(u[0].a == 0, "");
62159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(u[0].b, ""); // expected-error {{constant expression}}
62259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(u[1].b == 1, "");
62359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold((&u[1].b)[1] == 2, ""); // expected-error {{constant expression}}
62459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(*(&(u[1].b) + 1 + 1) == 3, ""); // expected-error {{constant expression}}
62559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold((&(u[1]) + 1 + 1)->b == 3, "");
62659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
62759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
62859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
62959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithnamespace Complex {
63059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
63159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithclass complex {
63259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  int re, im;
63359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithpublic:
63459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr complex(int re = 0, int im = 0) : re(re), im(im) {}
63559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr complex(const complex &o) : re(o.re), im(o.im) {}
63659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr complex operator-() const { return complex(-re, -im); }
63759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  friend constexpr complex operator+(const complex &l, const complex &r) {
63859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return complex(l.re + r.re, l.im + r.im);
63959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
64059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  friend constexpr complex operator-(const complex &l, const complex &r) {
64159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return l + -r;
64259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
64359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  friend constexpr complex operator*(const complex &l, const complex &r) {
64459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return complex(l.re * r.re - l.im * r.im, l.re * r.im + l.im * r.re);
64559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
64659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  friend constexpr bool operator==(const complex &l, const complex &r) {
64759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return l.re == r.re && l.im == r.im;
64859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
64959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr bool operator!=(const complex &r) const {
65059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith    return re != r.re || im != r.im;
65159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  }
65259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int real() const { return re; }
65359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr int imag() const { return im; }
65459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
65559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
65659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr complex i = complex(0, 1);
65759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr complex k = (3 + 4*i) * (6 - 4*i);
65859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(complex(1,0).real() == 1, "");
65959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(complex(1,0).imag() == 0, "");
66059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(((complex)1).imag() == 0, "");
66159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(k.real() == 34, "");
66259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(k.imag() == 12, "");
66359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(k - 34 == 12*i, "");
66459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold((complex)1 == complex(1), "");
66559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold((complex)1 != complex(0, 1), "");
66659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(complex(1) == complex(1), "");
66759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(complex(1) != complex(0, 1), "");
66859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr complex makeComplex(int re, int im) { return complex(re, im); }
66959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(makeComplex(1,0) == complex(1), "");
67059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(makeComplex(1,0) != complex(0, 1), "");
67159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
67259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithclass complex_wrap : public complex {
67359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithpublic:
67459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr complex_wrap(int re, int im = 0) : complex(re, im) {}
67559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  constexpr complex_wrap(const complex_wrap &o) : complex(o) {}
67659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith};
67759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
67859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold((complex_wrap)1 == complex(1), "");
67959efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold((complex)1 != complex_wrap(0, 1), "");
68059efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(complex(1) == complex_wrap(1), "");
68159efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(complex_wrap(1) != complex(0, 1), "");
68259efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithconstexpr complex_wrap makeComplexWrap(int re, int im) {
68359efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith  return complex_wrap(re, im);
68459efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
68559efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(makeComplexWrap(1,0) == complex(1), "");
68659efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smithstatic_assert_fold(makeComplexWrap(1,0) != complex(0, 1), "");
68759efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith
68859efe266b804330f4c1f3a1b0ff783e67dd90378Richard Smith}
689