p1.cpp revision 1d238ea926bbdd04356ce475934fcd4cac654c4b
13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct notlit {
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  notlit() {}
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct notlit2 {
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  notlit2() {}
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// valid declarations
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr int i1 = 0;
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr int f1() { return 0; }
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct s1 {
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  constexpr static int mi1 = 0;
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  const static int mi2;
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr int s1::mi2 = 0;
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// invalid declarations
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// not a definition of an object
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr extern int i2; // expected-error {{constexpr variable declaration must be a definition}}
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// not a literal type
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr notlit nl1; // expected-error {{constexpr variable 'nl1' must be initialized by a constant expression}} expected-note {{non-literal type 'const notlit' cannot be used in a constant expression}}
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// function parameters
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid f2(constexpr int i) {} // expected-error {{function parameter cannot be constexpr}}
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// non-static member
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct s2 {
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  constexpr int mi1; // expected-error {{non-static data member cannot be constexpr}}
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry  static constexpr int mi2; // expected-error {{requires an initializer}}
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// typedef
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef constexpr int CI; // expected-error {{typedef cannot be constexpr}}
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// tag
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr class C1 {}; // expected-error {{class cannot be marked constexpr}}
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr struct S1 {}; // expected-error {{struct cannot be marked constexpr}}
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr union U1 {}; // expected-error {{union cannot be marked constexpr}}
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr enum E1 {}; // expected-error {{enum cannot be marked constexpr}}
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> constexpr class TC1 {}; // expected-error {{class cannot be marked constexpr}}
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> constexpr struct TS1 {}; // expected-error {{struct cannot be marked constexpr}}
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> constexpr union TU1 {}; // expected-error {{union cannot be marked constexpr}}
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass C2 {} constexpr; // expected-error {{class cannot be marked constexpr}}
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct S2 {} constexpr; // expected-error {{struct cannot be marked constexpr}}
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryunion U2 {} constexpr; // expected-error {{union cannot be marked constexpr}}
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum E2 {} constexpr; // expected-error {{enum cannot be marked constexpr}}
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// FIXME: Mark default constructors as 'constexpr' when appropriate.
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr class C3 {} c3 = C3(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr struct S3 {} s3 = S3(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr union U3 {} u3 = {};
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr enum E3 { V3 } e3 = V3;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass C4 {} constexpr c4 = C4(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct S4 {} constexpr s4 = S4(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryunion U4 {} constexpr u4 = {};
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum E4 { V4 } constexpr e4 = V4;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr int; // expected-error {{constexpr can only be used in variable and function declarations}}
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// redeclaration mismatch
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconstexpr int f3(); // expected-note {{previous declaration is here}}
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint f3(); // expected-error {{non-constexpr declaration of 'f3' follows constexpr declaration}}
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint f4(); // expected-note {{previous declaration is here}}
59constexpr int f4(); // expected-error {{constexpr declaration of 'f4' follows non-constexpr declaration}}
60template<typename T> constexpr T f5(T);
61template<typename T> constexpr T f5(T); // expected-note {{previous}}
62template<typename T> T f5(T); // expected-error {{non-constexpr declaration of 'f5' follows constexpr declaration}}
63template<typename T> T f6(T); // expected-note {{here}}
64template<typename T> constexpr T f6(T); // expected-error {{constexpr declaration of 'f6' follows non-constexpr declaration}}
65// destructor
66struct ConstexprDtor {
67  constexpr ~ConstexprDtor() = default; // expected-error {{destructor cannot be marked constexpr}}
68};
69
70// template stuff
71template <typename T> constexpr T ft(T t) { return t; }
72template <typename T> T gt(T t) { return t; }
73struct S {
74  template<typename T> constexpr T f();
75  template<typename T> T g() const;
76};
77
78// explicit specialization can differ in constepxr
79// FIXME: When checking the explicit specialization, we implicitly instantiate
80// the primary template then claim a constexpr mismatch.
81template <> notlit ft(notlit nl) { return nl; }
82template <> char ft(char c) { return c; } // desired-note {{previous}} unexpected-error {{follows constexpr declaration}} unexpected-note {{here}}
83template <> constexpr char ft(char nl); // desired-error {{constexpr declaration of 'ft<char>' follows non-constexpr declaration}}
84template <> constexpr int gt(int nl) { return nl; } // unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}}
85template <> notlit S::f() const { return notlit(); }
86template <> constexpr int S::g() { return 0; } // desired-note {{previous}} unexpected-error {{follows non-constexpr declaration}} unexpected-note {{here}}
87template <> int S::g() const; // desired-error {{non-constexpr declaration of 'g<int>' follows constexpr declaration}}
88// specializations can drop the 'constexpr' but not the implied 'const'.
89template <> char S::g() { return 0; } // expected-error {{no function template matches}}
90template <> double S::g() const { return 0; } // ok
91
92constexpr int i3 = ft(1);
93
94void test() {
95  // ignore constexpr when instantiating with non-literal
96  notlit2 nl2;
97  (void)ft(nl2);
98}
99
100// Examples from the standard:
101constexpr int square(int x); // expected-note {{declared here}}
102constexpr int bufsz = 1024;
103
104constexpr struct pixel { // expected-error {{struct cannot be marked constexpr}}
105  int x;
106  int y;
107  constexpr pixel(int);
108};
109
110constexpr pixel::pixel(int a)
111  : x(square(a)), y(square(a)) // expected-note {{undefined function 'square' cannot be used in a constant expression}}
112  { }
113
114constexpr pixel small(2); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'pixel(2)'}}
115
116constexpr int square(int x) {
117  return x * x;
118}
119
120constexpr pixel large(4);
121
122int next(constexpr int x) { // expected-error {{function parameter cannot be constexpr}}
123      return x + 1;
124}
125
126extern constexpr int memsz; // expected-error {{constexpr variable declaration must be a definition}}
127