constant-expression-cxx11.cpp revision 47a1eed1cdd36edbefc318f29be6c0f3212b0c41
1c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// RUN: %clang_cc1 -triple i686-linux -fsyntax-only -verify -std=c++11 %s
2c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
3c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// FIXME: support const T& parameters here.
4c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)//template<typename T> constexpr T id(const T &t) { return t; }
5c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)template<typename T> constexpr T id(T t) { return t; }
6c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)// FIXME: support templates here.
7c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)//template<typename T> constexpr T min(const T &a, const T &b) {
8c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)//  return a < b ? a : b;
9c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)//}
10c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)//template<typename T> constexpr T max(const T &a, const T &b) {
11c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)//  return a < b ? b : a;
12c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)//}
13c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)constexpr int min(const int &a, const int &b) { return a < b ? a : b; }
14c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)constexpr int max(const int &a, const int &b) { return a < b ? b : a; }
15c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
16c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)struct MemberZero {
17c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int zero() { return 0; }
18c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)};
19c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
20c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace TemplateArgumentConversion {
21c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  template<int n> struct IntParam {};
22c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
23c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using IntParam0 = IntParam<0>;
24c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // FIXME: This should be accepted once we do constexpr function invocation.
25c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using IntParam0 = IntParam<id(0)>; // expected-error {{not an integral constant expression}}
26c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}} expected-error {{not an integral constant expression}}
27c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
28c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace CaseStatements {
30c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  void f(int n) {
31c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    switch (n) {
32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // FIXME: Produce the 'add ()' fixit for this.
33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    case MemberZero().zero: // desired-error {{did you mean to call it with no arguments?}} expected-error {{not an integer constant expression}}
34c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // FIXME: This should be accepted once we do constexpr function invocation.
35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    case id(1): // expected-error {{not an integer constant expression}}
36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)      return;
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    }
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)extern int &Recurse1;
42c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)int &Recurse2 = Recurse1, &Recurse1 = Recurse2;
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)constexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}}
44e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
45c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace MemberEnum {
46c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  struct WithMemberEnum {
47c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    enum E { A = 42 };
48c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  } wme;
49c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // FIXME: b's initializer is not treated as a constant expression yet, but we
50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // can at least fold it.
51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr bool b = wme.A == 42;
52c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  int n[b];
53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
54c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccinamespace Recursion {
567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci  constexpr int fib(int n) { return n > 1 ? fib(n-1) + fib(n-2) : n; }
57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // FIXME: this isn't an ICE yet.
58c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_fib = int[fib(11)];
59c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_fib = int[89];
60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int gcd_inner(int a, int b) {
62c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return b == 0 ? a : gcd_inner(b, a % b);
63c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int gcd(int a, int b) {
65e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    return gcd_inner(max(a, b), min(a, b));
66c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
68c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // FIXME: this isn't an ICE yet.
69c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_gcd = int[gcd(1749237, 5628959)];
70c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_gcd = int[7];
71c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
72c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
73c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace FunctionCast {
74c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // When folding, we allow functions to be cast to different types. Such
75c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // cast functions cannot be called, even if they're constexpr.
76c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int f() { return 1; }
77c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  typedef double (*DoubleFn)();
78c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  typedef int (*IntFn)();
79c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  int a[(int)DoubleFn(f)()]; // expected-error {{variable length array}}
80c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  int b[(int)IntFn(f)()];    // ok
81c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
82c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
83c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace StaticMemberFunction {
84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  struct S {
85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static constexpr int k = 42;
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    static constexpr int f(int n) { return n * k + 2; }
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci  } s;
88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // FIXME: this isn't an ICE yet.
89c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_static_call = int[S::f(19)];
90c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int n = s.f(19);
91c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_static_call = int[s.f(19)];
92c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_static_call = int[800];
93c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
94c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
95c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace ParameterScopes {
96c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
97c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  const int k = 42;
98c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr const int &ObscureTheTruth(const int &a) { return a; }
99c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr const int &MaybeReturnJunk(bool b, const int a) {
100c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return ObscureTheTruth(b ? a : k);
101c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int n1 = MaybeReturnJunk(false, 0); // ok
103c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int n2 = MaybeReturnJunk(true, 0); // expected-error {{must be initialized by a constant expression}}
104c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int InternalReturnJunk(int n) {
106c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // FIXME: We should reject this: it never produces a constant expression.
107c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return MaybeReturnJunk(true, n);
108c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}}
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
111c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int LToR(int &n) { return n; }
112c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int GrabCallersArgument(bool which, int a, int b) {
113c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    return LToR(which ? b : a);
114c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  }
115c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int n4 = GrabCallersArgument(false, 1, 2);
116c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  constexpr int n5 = GrabCallersArgument(true, 4, 8);
117c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  // FIXME: this isn't an ICE yet.
118c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_value = int[n4 + n5];
119c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)  using check_value = int[9];
120c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
121c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)}
122c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)