brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 9bb3f0c Raw
134 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -verify %s2//3// Note: [class.inhctor] was removed by P0136R1. This tests the new behavior4// for the wording that used to be there.5 6template<int> struct X {};7 8// Constructor characteristics are:9//   - the template parameter list10//   - the parameter-type-list11//   - absence or presence of explicit12//   - absence or presence of constexpr13struct 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 BothNonConstexpr76    : 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() {}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 3{{candidate constructor (the implicit}}108  using TemplateCtors::TemplateCtors; // expected-note 5{{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 }; // ok128constexpr UsingTemplateCtors utc8{ 0, 0 }; // ok129// FIXME: The standard says that UsingTemplateCtors' (int, int, int) constructor130// hides the one from TemplateCtors, even though the template parameter lists131// don't match. It's not clear that that's *really* the intent, and it's not132// what other compilers do.133constexpr UsingTemplateCtors utc9{ 0, 0, 0 }; // expected-error {{no matching constructor}}134