p6.cpp revision 762bb9d0ad20320b9f97a841dce57ba5e8e48b07
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 {
12  NonLiteral() {}
13  NonLiteral(int) {}
14  operator int() const { return 0; }
15};
16struct Literal {
17  constexpr Literal() {}
18  operator int() const { return 0; }
19};
20
21struct S {
22  virtual int ImplicitlyVirtual();
23};
24struct T {};
25
26template<typename T> struct ImplicitVirtualFromDependentBase : T {
27  constexpr int ImplicitlyVirtual() { return 0; }
28};
29
30// FIXME: Can't test this until we have function invocation substitution
31#if 0
32constexpr int a = ImplicitVirtualFromDependentBase<S>().ImplicitlyVirtual(); // desired-error {{not a constant expression}}
33constexpr int b = ImplicitVirtualFromDependentBase<T>().ImplicitlyVirtual(); // ok
34#endif
35
36template<typename R> struct ConstexprMember {
37  constexpr R F() { return 0; }
38};
39// FIXME: Can't test this until we have function invocation substitution
40#if 0
41constexpr int c = ConstexprMember<int>().F(); // ok
42constexpr int d = ConstexprMember<NonLiteral>().F(); // desired-error {{not a constant expression}}
43#endif
44
45template<typename ...P> struct ConstexprCtor { // expected-note 2{{no constexpr constructors}}
46  constexpr ConstexprCtor(P...); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}} \
47                                    expected-note {{constructor template instantiation is not constexpr because 2nd parameter type 'NonLiteral' is not a literal type}}
48};
49constexpr ConstexprCtor<> f1(); // ok
50constexpr ConstexprCtor<int> f2(); // ok
51constexpr ConstexprCtor<NonLiteral> f3(); // expected-error {{not a literal type}}
52constexpr ConstexprCtor<int, NonLiteral> f4(); // expected-error {{not a literal type}}
53
54struct VirtBase : virtual S {}; // expected-note {{here}}
55
56namespace TemplateVBase {
57  template<typename T> struct T1 : virtual Literal { // expected-note {{here}}
58    constexpr T1(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
59  };
60
61  template<typename T> struct T2 : virtual T { // expected-note {{struct with virtual base class is not a literal type}} expected-note {{here}}
62    // FIXME: This is ill-formed (no diagnostic required).
63    // We should diagnose it now rather than waiting until instantiation.
64    constexpr T2(); // desired-error {{constexpr constructor not allowed in class with virtual base classes}}
65  };
66  constexpr T2<Literal> g2(); // expected-error {{not a literal type}}
67
68  template<typename T> class T3 : public T { // expected-note {{class with virtual base class is not a literal type}}
69  public:
70    constexpr T3() {}
71  };
72  constexpr T3<Literal> g3(); // ok
73  constexpr T3<VirtBase> g4(); // expected-error {{not a literal type}}
74}
75