p3.cpp revision 745f5147e065900267c85a5568785a1991d4838f
1// RUN: %clang_cc1 -verify -std=c++11 %s 2 3namespace N { 4 typedef char C; 5} 6 7namespace M { 8 typedef double D; 9} 10 11struct NonLiteral { // expected-note 4{{no constexpr constructors}} 12 NonLiteral() {} 13 NonLiteral(int) {} 14}; 15struct Literal { 16 constexpr Literal() {} 17 operator int() const { return 0; } 18}; 19 20struct S { 21 virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}} 22}; 23struct SS : S { 24 int ImplicitlyVirtual() const; 25}; 26 27// Note, the wording applies constraints to the definition of constexpr 28// functions, but we intentionally apply all that we can to the declaration 29// instead. See DR1360. 30 31// The definition of a constexpr function shall satisfy the following 32// constraints: 33struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}} 34 constexpr T(); // expected-error {{non-literal type 'T' cannot have constexpr members}} 35 36 // - it shall not be virtual; 37 virtual constexpr int ExplicitlyVirtual(); // expected-error {{virtual function cannot be constexpr}} 38 39 constexpr int ImplicitlyVirtual(); // expected-error {{virtual function cannot be constexpr}} 40 41 // - its return type shall be a literal type; 42 constexpr NonLiteral NonLiteralReturn(); // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} 43 constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}} 44 typedef NonLiteral F(); 45 constexpr F NonLiteralReturn2; // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} 46 47 // - each of its parameter types shall be a literal type; 48 constexpr int NonLiteralParam(NonLiteral); // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} 49 typedef int G(NonLiteral); 50 constexpr G NonLiteralParam2; // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} 51 52 // - its function-body shall be = delete, = default, 53 constexpr int Deleted() = delete; 54 // It's not possible for the function-body to legally be "= default" here. 55 // Other than constructors, only the copy- and move-assignment operators and 56 // destructor can be defaulted. Destructors can't be constexpr since they 57 // don't have a literal return type. Defaulted assignment operators can't be 58 // constexpr since they can't be const. 59 constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} 60}; 61struct U { 62 constexpr U SelfReturn(); 63 constexpr int SelfParam(U); 64}; 65 66struct V : virtual U { // expected-note {{here}} 67 constexpr int F(); // expected-error {{constexpr member function not allowed in struct with virtual base class}} 68}; 69 70// or a compound-statememt that contains only 71constexpr int AllowedStmts() { 72 // - null statements 73 ; 74 75 // - static_assert-declarations 76 static_assert(true, "the impossible happened!"); 77 78 // - typedef declarations and alias-declarations that do not define classes 79 // or enumerations 80 typedef int I; 81 typedef struct S T; 82 using J = int; 83 using K = int[sizeof(I) + sizeof(J)]; 84 // Note, the standard requires we reject this. 85 struct U; 86 87 // - using-declarations 88 using N::C; 89 90 // - using-directives 91 using namespace N; 92 93 // - and exactly one return statement 94 return sizeof(K) + sizeof(C) + sizeof(K); 95} 96constexpr int ForStmt() { 97 for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}} 98 return 0; 99} 100constexpr int VarDecl() { 101 constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}} 102 return 0; 103} 104constexpr int FuncDecl() { 105 constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}} 106 return ForwardDecl(42); 107} 108constexpr int ClassDecl1() { 109 typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}} 110 return 0; 111} 112constexpr int ClassDecl2() { 113 using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}} 114 return 0; 115} 116constexpr int ClassDecl3() { 117 struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}} 118 return 0; 119} 120constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} 121constexpr int MultiReturn() { 122 return 0; // expected-note {{return statement}} 123 return 0; // expected-error {{multiple return statements in constexpr function}} 124} 125 126// - every constructor call and implicit conversion used in initializing the 127// return value shall be one of those allowed in a constant expression. 128// 129// We implement the proposed resolution of DR1364 and ignore this bullet. 130// However, we implement the spirit of the check as part of the p5 checking that 131// a constexpr function must be able to produce a constant expression. 132namespace DR1364 { 133 constexpr int f(int k) { 134 return k; // ok, even though lvalue-to-rvalue conversion of a function 135 // parameter is not allowed in a constant expression. 136 } 137 int kGlobal; // expected-note {{here}} 138 constexpr int f() { // expected-error {{constexpr function never produces a constant expression}} 139 return kGlobal; // expected-note {{read of non-const}} 140 } 141} 142