1// RUN: %clang_cc1 -std=c++11 -verify %s 2// 3// Note: [class.inhctor] was removed by P0136R1. This tests the new behavior 4// for the wording that used to be there. 5 6template<int> struct X {}; 7 8// Constructor characteristics are: 9// - the template parameter list 10// - the parameter-type-list 11// - absence or presence of explicit 12// - absence or presence of constexpr 13struct A { 14 A(X<0>) {} // expected-note 4{{here}} 15 constexpr A(X<1>) {} 16 explicit A(X<2>) {} // expected-note 6{{here}} 17 explicit constexpr A(X<3>) {} // expected-note 4{{here}} 18}; 19 20A a0 { X<0>{} }; 21A a0i = { X<0>{} }; 22constexpr A a0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 23constexpr A a0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 24 25A a1 { X<1>{} }; 26A a1i = { X<1>{} }; 27constexpr A a1c { X<1>{} }; 28constexpr A a1ic = { X<1>{} }; 29 30A a2 { X<2>{} }; 31A a2i = { X<2>{} }; // expected-error {{constructor is explicit}} 32constexpr A a2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 33constexpr A a2ic = { X<2>{} }; // expected-error {{constructor is explicit}} 34 35A a3 { X<3>{} }; 36A a3i = { X<3>{} }; // expected-error {{constructor is explicit}} 37constexpr A a3c { X<3>{} }; 38constexpr A a3ic = { X<3>{} }; // expected-error {{constructor is explicit}} 39 40 41struct B : A { 42 using A::A; 43}; 44 45B b0 { X<0>{} }; 46B b0i = { X<0>{} }; 47constexpr B b0c { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 48constexpr B b0ic = { X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 49 50B b1 { X<1>{} }; 51B b1i = { X<1>{} }; 52constexpr B b1c { X<1>{} }; 53constexpr B b1ic = { X<1>{} }; 54 55B b2 { X<2>{} }; 56B b2i = { X<2>{} }; // expected-error {{constructor is explicit}} 57constexpr B b2c { X<2>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 58constexpr B b2ic = { X<2>{} }; // expected-error {{constructor is explicit}} 59 60B b3 { X<3>{} }; 61B b3i = { X<3>{} }; // expected-error {{constructor is explicit}} 62constexpr B b3c { X<3>{} }; 63constexpr B b3ic = { X<3>{} }; // expected-error {{constructor is explicit}} 64 65 66// 'constexpr' is OK even if the constructor doesn't obey the constraints. 67struct NonLiteral { NonLiteral(); }; 68struct NonConstexpr { NonConstexpr(); constexpr NonConstexpr(int); }; 69struct Constexpr { constexpr Constexpr(int) {} }; 70 71struct BothNonLiteral : NonLiteral, Constexpr { using Constexpr::Constexpr; }; // expected-note {{base class 'NonLiteral' of non-literal type}} 72constexpr BothNonLiteral bothNL{42}; // expected-error {{constexpr variable cannot have non-literal type 'const BothNonLiteral'}} 73 74// FIXME: This diagnostic is not very good. We should explain that the problem is that base class NonConstexpr cannot be initialized. 75struct BothNonConstexpr 76 : NonConstexpr, 77 Constexpr { 78 using Constexpr::Constexpr; // expected-note {{here}} 79}; 80constexpr BothNonConstexpr bothNC{42}; // expected-error {{must be initialized by a constant expression}} expected-note {{inherited from base class 'Constexpr'}} 81 82 83struct ConstexprEval { 84 constexpr ConstexprEval(int a, const char *p) : k(p[a]) {} 85 char k; 86}; 87struct ConstexprEval2 { 88 char k2 = 'x'; 89}; 90struct ConstexprEval3 : ConstexprEval, ConstexprEval2 { 91 using ConstexprEval::ConstexprEval; 92}; 93constexpr ConstexprEval3 ce{4, "foobar"}; 94static_assert(ce.k == 'a', ""); 95static_assert(ce.k2 == 'x', ""); 96 97 98struct TemplateCtors { // expected-note 2{{candidate constructor (the implicit}} 99 constexpr TemplateCtors() {} // expected-note {{candidate inherited constructor}} 100 template<template<int> class T> TemplateCtors(X<0>, T<0>); // expected-note {{here}} expected-note {{candidate inherited constructor}} 101 template<int N> TemplateCtors(X<1>, X<N>); // expected-note {{here}} expected-note {{candidate inherited constructor}} 102 template<typename T> TemplateCtors(X<2>, T); // expected-note {{here}} expected-note {{candidate inherited constructor}} 103 104 template<typename T = int> TemplateCtors(int, int = 0, int = 0); 105}; 106 107struct UsingTemplateCtors : TemplateCtors { // expected-note 2{{candidate constructor (the implicit}} 108 using TemplateCtors::TemplateCtors; // expected-note 6{{inherited here}} 109 110 constexpr UsingTemplateCtors(X<0>, X<0>) {} // expected-note {{not viable}} 111 constexpr UsingTemplateCtors(X<1>, X<1>) {} // expected-note {{not viable}} 112 constexpr UsingTemplateCtors(X<2>, X<2>) {} // expected-note {{not viable}} 113 114 template<int = 0> constexpr UsingTemplateCtors(int) {} // expected-note {{not viable}} 115 template<typename T = void> constexpr UsingTemplateCtors(int, int) {} // expected-note {{not viable}} 116 template<typename T, typename U> constexpr UsingTemplateCtors(int, int, int) {} // expected-note {{couldn't infer}} 117}; 118 119template<int> struct Y {}; 120constexpr UsingTemplateCtors uct1{ X<0>{}, X<0>{} }; 121constexpr UsingTemplateCtors uct2{ X<0>{}, Y<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 122constexpr UsingTemplateCtors uct3{ X<1>{}, X<0>{} }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 123constexpr UsingTemplateCtors uct4{ X<1>{}, X<1>{} }; 124constexpr UsingTemplateCtors uct5{ X<2>{}, 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr}} 125constexpr UsingTemplateCtors uct6{ X<2>{}, X<2>{} }; 126 127constexpr UsingTemplateCtors utc7{ 0 }; // ok 128constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok 129// FIXME: The standard says that UsingTemplateCtors' (int, int, int) constructor 130// hides the one from TemplateCtors, even though the template parameter lists 131// don't match. It's not clear that that's *really* the intent, and it's not 132// what other compilers do. 133constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{no matching constructor}} 134