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