19b29f4fe3d0600edf6ba00d48f2d4f2b1984f247David Blaikie// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -verify -std=c++11 -fcxx-exceptions %s
2afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith// RUN: %clang_cc1 -fsyntax-only -triple x86_64-unknown-unknown -std=c++11 -fcxx-exceptions -Wno-invalid-constexpr %s -DNO_INVALID_CONSTEXPR
3839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith
4839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithnamespace StdExample {
5839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith
6839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithconstexpr int f(void *) { return 0; }
7839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithconstexpr int f(...) { return 1; }
8839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithconstexpr int g1() { return f(0); }
9839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithconstexpr int g2(int n) { return f(n); }
10839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithconstexpr int g3(int n) { return f(n*0); }
11839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith
12839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithnamespace N {
13839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith  constexpr int c = 5;
14839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith  constexpr int h() { return c; }
15839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith}
16839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithconstexpr int c = 0;
17839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smithconstexpr int g4() { return N::h(); }
18839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith
19745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(f(0) == 0, "");
20745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(f('0') == 1, "");
21745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(g1() == 0, "");
22745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(g2(0) == 1, "");
23745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(g2(1) == 1, "");
24745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(g3(0) == 1, "");
25745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(g3(1) == 1, "");
26745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(N::h() == 5, "");
27745f5147e065900267c85a5568785a1991d4838fRichard Smithstatic_assert(g4() == 5, "");
28745f5147e065900267c85a5568785a1991d4838fRichard Smith
29745f5147e065900267c85a5568785a1991d4838fRichard Smith
30745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr int f(bool b)
31745f5147e065900267c85a5568785a1991d4838fRichard Smith  { return b ? throw 0 : 0; } // ok
32745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr int f() { return throw 0, 0; } // expected-error {{constexpr function never produces a constant expression}} expected-note {{subexpression}}
33745f5147e065900267c85a5568785a1991d4838fRichard Smith
34745f5147e065900267c85a5568785a1991d4838fRichard Smithstruct B {
35745f5147e065900267c85a5568785a1991d4838fRichard Smith  constexpr B(int x) : i(0) { }
36745f5147e065900267c85a5568785a1991d4838fRichard Smith  int i;
37745f5147e065900267c85a5568785a1991d4838fRichard Smith};
38745f5147e065900267c85a5568785a1991d4838fRichard Smith
39745f5147e065900267c85a5568785a1991d4838fRichard Smithint global; // expected-note {{declared here}}
40745f5147e065900267c85a5568785a1991d4838fRichard Smith
41745f5147e065900267c85a5568785a1991d4838fRichard Smithstruct D : B {
42745f5147e065900267c85a5568785a1991d4838fRichard Smith  constexpr D() : B(global) { } // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}}
43745f5147e065900267c85a5568785a1991d4838fRichard Smith};
44745f5147e065900267c85a5568785a1991d4838fRichard Smith
45745f5147e065900267c85a5568785a1991d4838fRichard Smith}
46745f5147e065900267c85a5568785a1991d4838fRichard Smith
47745f5147e065900267c85a5568785a1991d4838fRichard Smithnamespace PotentialConstant {
48745f5147e065900267c85a5568785a1991d4838fRichard Smith
49745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr int Comma(int n) { return // expected-error {{constexpr function never produces a constant expression}}
50745f5147e065900267c85a5568785a1991d4838fRichard Smith  (void)(n * 2),
51745f5147e065900267c85a5568785a1991d4838fRichard Smith  throw 0, // expected-note {{subexpression}}
52745f5147e065900267c85a5568785a1991d4838fRichard Smith  0;
53745f5147e065900267c85a5568785a1991d4838fRichard Smith}
54745f5147e065900267c85a5568785a1991d4838fRichard Smith
5574e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithint ng; // expected-note 6{{here}}
56745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr int BinaryOp1(int n) { return n + ng; } // expected-error {{never produces}} expected-note {{read}}
57745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr int BinaryOp2(int n) { return ng + n; } // expected-error {{never produces}} expected-note {{read}}
58745f5147e065900267c85a5568785a1991d4838fRichard Smith
59745f5147e065900267c85a5568785a1991d4838fRichard Smithdouble dg; // expected-note 2{{here}}
60745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr double BinaryOp1(double d) { return d + dg; } // expected-error {{never produces}} expected-note {{read}}
61745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr double BinaryOp2(double d) { return dg + d; } // expected-error {{never produces}} expected-note {{read}}
62745f5147e065900267c85a5568785a1991d4838fRichard Smith
63745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr int Add(int a, int b, int c) { return a + b + c; }
64745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr int FunctionArgs(int a) { return Add(a, ng, a); } // expected-error {{never produces}} expected-note {{read}}
65745f5147e065900267c85a5568785a1991d4838fRichard Smith
66745f5147e065900267c85a5568785a1991d4838fRichard Smithstruct S { int a; int b; int c[2]; };
67745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr S InitList(int a) { return { a, ng }; }; // expected-error {{never produces}} expected-note {{read}}
6874e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr S InitList1a(int a) { return S{ a, ng }; }; // expected-error {{never produces}} expected-note {{read}}
69745f5147e065900267c85a5568785a1991d4838fRichard Smithconstexpr S InitList2(int a) { return { a, a, { ng } }; }; // expected-error {{never produces}} expected-note {{read}}
7074e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr S InitList3(int a) { return a ? S{ a, a } : S{ a, ng }; }; // ok
71745f5147e065900267c85a5568785a1991d4838fRichard Smith
7274e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr int LogicalAnd1(int n) { return n && (throw, 0); } // ok
7374e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr int LogicalAnd2(int n) { return 1 && (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
74745f5147e065900267c85a5568785a1991d4838fRichard Smith
7574e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr int LogicalOr1(int n) { return n || (throw, 0); } // ok
7674e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr int LogicalOr2(int n) { return 0 || (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
7774e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smith
7874e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr int Conditional1(bool b, int n) { return b ? n : ng; } // ok
7974e1ad93fa8d6347549bcb10279fdf1fbc775321Richard Smithconstexpr int Conditional2(bool b, int n) { return b ? n * ng : n + ng; } // expected-error {{never produces}} expected-note {{both arms of conditional operator are unable to produce a constant expression}}
80839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith
81f15fda02e9c8c82b4a716618f4010b9af8bff796Richard Smith// __builtin_constant_p ? : is magical, and is always a potential constant.
82f15fda02e9c8c82b4a716618f4010b9af8bff796Richard Smithconstexpr bool BcpCall(int n) {
839b29f4fe3d0600edf6ba00d48f2d4f2b1984f247David Blaikie  return __builtin_constant_p((int*)n != &n) ? (int*)n != &n : (int*)n != &n; // expected-warning 3 {{cast to 'int *' from smaller integer type 'int'}}
84f15fda02e9c8c82b4a716618f4010b9af8bff796Richard Smith}
85f15fda02e9c8c82b4a716618f4010b9af8bff796Richard Smithstatic_assert(BcpCall(0), "");
86f15fda02e9c8c82b4a716618f4010b9af8bff796Richard Smith
87d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith// DR1311: A function template which can produce a constant expression, but
88d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith// for which a particular specialization cannot, is ok.
89d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithtemplate<typename T> constexpr T cmin(T a, T b) {
90d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith  return a < b ? a : b;
91d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith}
92d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithint n = cmin(3, 5); // ok
93d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith
94d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithstruct X {
95d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith  constexpr X() {}
96d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith  bool operator<(X); // not constexpr
97d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith};
98d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith
99d79093af384ac0ea78f4237a001eae7467e06a61Richard SmithX x = cmin(X(), X()); // ok, not constexpr
100d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith
101d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith// Same with other temploids.
102d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithtemplate<typename T>
103d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithstruct Y {
104d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith  constexpr Y() {}
105840462670ba7a6bc26265a2306b35f2f0f01f51cRichard Smith  constexpr int get() { return T(); } // expected-warning {{C++1y}}
106d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith};
107d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithstruct Z { operator int(); };
108d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith
109d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithint y1 = Y<int>().get(); // ok
110d79093af384ac0ea78f4237a001eae7467e06a61Richard Smithint y2 = Y<Z>().get(); // ok
111d79093af384ac0ea78f4237a001eae7467e06a61Richard Smith
112839046a8c5f890f172b0a172ed6ec9e7d0275f2eRichard Smith}
113afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith
114afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith#ifndef NO_INVALID_CONSTEXPR
115afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smithnamespace PR14550 {
116afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  // As an "extension", we allow functions which can't produce constant
117afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  // expressions to be declared constexpr in system headers (libstdc++
118afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  // marks some functions as constexpr which use builtins which we don't
119afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  // support constant folding). Ensure that we don't mark those functions
120afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  // as invalid after suppressing the diagnostic.
121afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith# 122 "p5.cpp" 1 3
122afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  int n;
123afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  struct A {
124afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith    static constexpr int f() { return n; }
125afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  };
126afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  template<typename T> struct B {
127afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith    B() { g(T::f()); } // expected-error {{undeclared identifier 'g'}}
128afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  };
129afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith# 130 "p5.cpp" 2
130afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith  template class B<A>; // expected-note {{here}}
131afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith}
132afee0ff915b87f92e8c07c72d31c3165aacf6fa8Richard Smith#endif
133