Stephen Hines | 0e2c34f | 2015-03-23 12:09:02 -0700 | [diff] [blame^] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s |
| 2 | |
| 3 | template<typename T, T val> struct A {}; |
| 4 | |
| 5 | template<typename T, typename U> constexpr bool is_same = false; // expected-note +{{here}} |
| 6 | template<typename T> constexpr bool is_same<T, T> = true; |
| 7 | |
| 8 | namespace String { |
| 9 | A<const char*, "test"> a; // expected-error {{does not refer to any declaration}} |
| 10 | A<const char (&)[5], "test"> b; // expected-error {{does not refer to any declaration}} |
| 11 | } |
| 12 | |
| 13 | namespace Array { |
| 14 | char arr[3]; |
| 15 | char x; |
| 16 | A<const char*, arr> a; |
| 17 | A<const char(&)[3], arr> b; |
| 18 | A<const char*, &arr[0]> c; |
| 19 | A<const char*, &arr[1]> d; // expected-error {{refers to subobject '&arr[1]'}} |
| 20 | A<const char*, (&arr)[0]> e; |
| 21 | A<const char*, &x> f; |
| 22 | A<const char*, &(&x)[0]> g; |
| 23 | A<const char*, &(&x)[1]> h; // expected-error {{refers to subobject '&x + 1'}} |
| 24 | A<const char*, 0> i; // expected-error {{not allowed in a converted constant}} |
| 25 | A<const char*, nullptr> j; |
| 26 | } |
| 27 | |
| 28 | namespace Function { |
| 29 | void f(); |
| 30 | void g() noexcept; |
| 31 | void h(); |
| 32 | void h(int); |
| 33 | template<typename...T> void i(T...); |
| 34 | typedef A<void (*)(), f> a; |
| 35 | typedef A<void (*)(), &f> a; |
| 36 | typedef A<void (*)(), g> b; |
| 37 | typedef A<void (*)(), &g> b; |
| 38 | typedef A<void (*)(), h> c; |
| 39 | typedef A<void (*)(), &h> c; |
| 40 | typedef A<void (*)(), i> d; |
| 41 | typedef A<void (*)(), &i> d; |
| 42 | typedef A<void (*)(), i<>> d; |
| 43 | typedef A<void (*)(), i<int>> e; // expected-error {{is not implicitly convertible}} |
| 44 | |
| 45 | typedef A<void (*)(), 0> x; // expected-error {{not allowed in a converted constant}} |
| 46 | typedef A<void (*)(), nullptr> y; |
| 47 | } |
| 48 | |
| 49 | void Func() { |
| 50 | A<const char*, __func__> a; // expected-error {{does not refer to any declaration}} |
| 51 | } |
| 52 | |
| 53 | namespace LabelAddrDiff { |
| 54 | void f() { |
| 55 | a: b: A<int, __builtin_constant_p(true) ? (__INTPTR_TYPE__)&&b - (__INTPTR_TYPE__)&&a : 0> s; // expected-error {{label address difference}} |
| 56 | }; |
| 57 | } |
| 58 | |
| 59 | namespace Temp { |
| 60 | struct S { int n; }; |
| 61 | constexpr S &addr(S &&s) { return s; } |
| 62 | A<S &, addr({})> a; // expected-error {{constant}} expected-note 2{{temporary}} |
| 63 | A<S *, &addr({})> b; // expected-error {{constant}} expected-note 2{{temporary}} |
| 64 | A<int &, addr({}).n> c; // expected-error {{constant}} expected-note 2{{temporary}} |
| 65 | A<int *, &addr({}).n> d; // expected-error {{constant}} expected-note 2{{temporary}} |
| 66 | } |
| 67 | |
| 68 | namespace std { struct type_info; } |
| 69 | |
| 70 | namespace RTTI { |
| 71 | A<const std::type_info&, typeid(int)> a; // expected-error {{does not refer to any declaration}} |
| 72 | A<const std::type_info*, &typeid(int)> b; // expected-error {{does not refer to any declaration}} |
| 73 | } |
| 74 | |
| 75 | namespace PtrMem { |
| 76 | struct B { int b; }; |
| 77 | struct C : B {}; |
| 78 | struct D : B {}; |
| 79 | struct E : C, D { int e; }; |
| 80 | |
| 81 | constexpr int B::*b = &B::b; |
| 82 | constexpr int C::*cb = b; |
| 83 | constexpr int D::*db = b; |
| 84 | constexpr int E::*ecb = cb; // expected-note +{{here}} |
| 85 | constexpr int E::*edb = db; // expected-note +{{here}} |
| 86 | |
| 87 | constexpr int E::*e = &E::e; |
| 88 | constexpr int D::*de = (int D::*)e; |
| 89 | constexpr int C::*ce = (int C::*)e; |
| 90 | constexpr int B::*bde = (int B::*)de; // expected-note +{{here}} |
| 91 | constexpr int B::*bce = (int B::*)ce; // expected-note +{{here}} |
| 92 | |
| 93 | // FIXME: This should all be accepted, but we don't yet have a representation |
| 94 | // nor mangling for this form of template argument. |
| 95 | using Ab = A<int B::*, b>; |
| 96 | using Ab = A<int B::*, &B::b>; |
| 97 | using Abce = A<int B::*, bce>; // expected-error {{not supported}} |
| 98 | using Abde = A<int B::*, bde>; // expected-error {{not supported}} |
| 99 | static_assert(!is_same<Ab, Abce>, ""); // expected-error {{undeclared}} expected-error {{must be a type}} |
| 100 | static_assert(!is_same<Ab, Abde>, ""); // expected-error {{undeclared}} expected-error {{must be a type}} |
| 101 | static_assert(!is_same<Abce, Abde>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}} |
| 102 | static_assert(is_same<Abce, A<int B::*, (int B::*)(int C::*)&E::e>, ""); // expected-error {{undeclared}} expected-error {{not supported}} |
| 103 | |
| 104 | using Ae = A<int E::*, e>; |
| 105 | using Ae = A<int E::*, &E::e>; |
| 106 | using Aecb = A<int E::*, ecb>; // expected-error {{not supported}} |
| 107 | using Aedb = A<int E::*, edb>; // expected-error {{not supported}} |
| 108 | static_assert(!is_same<Ae, Aecb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}} |
| 109 | static_assert(!is_same<Ae, Aedb>, ""); // expected-error {{undeclared}} expected-error {{must be a type}} |
| 110 | static_assert(!is_same<Aecb, Aedb>, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}} |
| 111 | static_assert(is_same<Aecb, A<int E::*, (int E::*)(int C::*)&B::b>, ""); // expected-error {{undeclared}} expected-error {{not supported}} |
| 112 | |
| 113 | using An = A<int E::*, nullptr>; |
| 114 | using A0 = A<int E::*, (int E::*)0>; |
| 115 | static_assert(is_same<An, A0>); |
| 116 | } |
| 117 | |
| 118 | namespace DeduceDifferentType { |
| 119 | template<int N> struct A {}; |
| 120 | template<long N> int a(A<N>); // expected-note {{does not have the same type}} |
| 121 | int a_imp = a(A<3>()); // expected-error {{no matching function}} |
| 122 | int a_exp = a<3>(A<3>()); |
| 123 | |
| 124 | template<decltype(nullptr)> struct B {}; |
| 125 | template<int *P> int b(B<P>); // expected-note {{could not match}} expected-note {{not implicitly convertible}} |
| 126 | int b_imp = b(B<nullptr>()); // expected-error {{no matching function}} |
| 127 | int b_exp = b<nullptr>(B<nullptr>()); // expected-error {{no matching function}} |
| 128 | |
| 129 | struct X { constexpr operator int() { return 0; } } x; |
| 130 | template<X &> struct C {}; |
| 131 | template<int N> int c(C<N>); // expected-note {{does not have the same type}} expected-note {{not implicitly convertible}} |
| 132 | int c_imp = c(C<x>()); // expected-error {{no matching function}} |
| 133 | int c_exp = c<x>(C<x>()); // expected-error {{no matching function}} |
| 134 | |
| 135 | struct Z; |
| 136 | struct Y { constexpr operator Z&(); } y; |
| 137 | struct Z { constexpr operator Y&() { return y; } } z; |
| 138 | constexpr Y::operator Z&() { return z; } |
| 139 | template<Y &> struct D {}; |
| 140 | template<Z &z> int d(D<z>); // expected-note {{does not have the same type}} |
| 141 | int d_imp = d(D<y>()); // expected-error {{no matching function}} |
| 142 | int d_exp = d<y>(D<y>()); |
| 143 | } |
| 144 | |
| 145 | namespace DeclMatch { |
| 146 | template<typename T, T> int f(); |
| 147 | template<typename T> class X { friend int f<T, 0>(); static int n; }; |
| 148 | template<typename T, T> int f() { return X<T>::n; } |
| 149 | int k = f<int, 0>(); // ok, friend |
| 150 | } |