// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s template struct A {}; template constexpr bool is_same = false; // expected-note +{{here}} template constexpr bool is_same = true; namespace String { A a; // expected-error {{does not refer to any declaration}} A b; // expected-error {{does not refer to any declaration}} } namespace Array { char arr[3]; char x; A a; A b; A c; A d; // expected-error {{refers to subobject '&arr[1]'}} A e; A f; A g; A h; // expected-error {{refers to subobject '&x + 1'}} A i; // expected-error {{not allowed in a converted constant}} A j; } namespace Function { void f(); void g() noexcept; void h(); void h(int); template void i(T...); typedef A a; typedef A a; typedef A b; typedef A b; typedef A c; typedef A c; typedef A d; typedef A d; typedef A> d; typedef A> e; // expected-error {{is not implicitly convertible}} typedef A x; // expected-error {{not allowed in a converted constant}} typedef A y; } void Func() { A a; // expected-error {{does not refer to any declaration}} } namespace LabelAddrDiff { void f() { a: b: A s; // expected-error {{label address difference}} }; } namespace Temp { struct S { int n; }; constexpr S &addr(S &&s) { return s; } A a; // expected-error {{constant}} expected-note 2{{temporary}} A b; // expected-error {{constant}} expected-note 2{{temporary}} A c; // expected-error {{constant}} expected-note 2{{temporary}} A d; // expected-error {{constant}} expected-note 2{{temporary}} } namespace std { struct type_info; } namespace RTTI { A a; // expected-error {{does not refer to any declaration}} A b; // expected-error {{does not refer to any declaration}} } namespace PtrMem { struct B { int b; }; struct C : B {}; struct D : B {}; struct E : C, D { int e; }; constexpr int B::*b = &B::b; constexpr int C::*cb = b; constexpr int D::*db = b; constexpr int E::*ecb = cb; // expected-note +{{here}} constexpr int E::*edb = db; // expected-note +{{here}} constexpr int E::*e = &E::e; constexpr int D::*de = (int D::*)e; constexpr int C::*ce = (int C::*)e; constexpr int B::*bde = (int B::*)de; // expected-note +{{here}} constexpr int B::*bce = (int B::*)ce; // expected-note +{{here}} // FIXME: This should all be accepted, but we don't yet have a representation // nor mangling for this form of template argument. using Ab = A; using Ab = A; using Abce = A; // expected-error {{not supported}} using Abde = A; // expected-error {{not supported}} static_assert(!is_same, ""); // expected-error {{undeclared}} expected-error {{must be a type}} static_assert(!is_same, ""); // expected-error {{undeclared}} expected-error {{must be a type}} static_assert(!is_same, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}} static_assert(is_same, ""); // expected-error {{undeclared}} expected-error {{not supported}} using Ae = A; using Ae = A; using Aecb = A; // expected-error {{not supported}} using Aedb = A; // expected-error {{not supported}} static_assert(!is_same, ""); // expected-error {{undeclared}} expected-error {{must be a type}} static_assert(!is_same, ""); // expected-error {{undeclared}} expected-error {{must be a type}} static_assert(!is_same, ""); // expected-error 2{{undeclared}} expected-error {{must be a type}} static_assert(is_same, ""); // expected-error {{undeclared}} expected-error {{not supported}} using An = A; using A0 = A; static_assert(is_same); } namespace DeduceDifferentType { template struct A {}; template int a(A); // expected-note {{does not have the same type}} int a_imp = a(A<3>()); // expected-error {{no matching function}} int a_exp = a<3>(A<3>()); template struct B {}; template int b(B

); // expected-error {{value of type 'int *' is not implicitly convertible to 'decltype(nullptr)'}} int b_imp = b(B()); // expected-error {{no matching function}} int b_exp = b(B()); // expected-error {{no matching function}} struct X { constexpr operator int() { return 0; } } x; template struct C {}; template int c(C); // expected-error {{value of type 'int' is not implicitly convertible to 'DeduceDifferentType::X &'}} int c_imp = c(C()); // expected-error {{no matching function}} int c_exp = c(C()); // expected-error {{no matching function}} struct Z; struct Y { constexpr operator Z&(); } y; struct Z { constexpr operator Y&() { return y; } } z; constexpr Y::operator Z&() { return z; } template struct D {}; template int d(D); // expected-note {{couldn't infer template argument 'z'}} int d_imp = d(D()); // expected-error {{no matching function}} int d_exp = d(D()); } namespace DeclMatch { template int f(); template class X { friend int f(); static int n; }; template int f() { return X::n; } int k = f(); // ok, friend } namespace PR24921 { enum E { e }; template void f(); template void f(int); template<> void f() {} } namespace Auto { namespace Basic { // simple auto template constexpr auto constant = x; // expected-note {{declared here}} auto v1 = constant<5>; auto v2 = constant; auto v3 = constant<'a'>; auto v4 = constant<2.5>; // expected-error {{cannot have type 'double'}} using T1 = decltype(v1); using T1 = int; using T2 = decltype(v2); using T2 = bool; using T3 = decltype(v3); using T3 = char; // pointers template class B { }; template class B

{ }; // expected-note {{matches}} template class B { }; template int &f(B b); // expected-note {{candidate}} template float &f(B b); // expected-note {{candidate}} int a, *b = &a; int &r = f(B<&a>()); float &s = f(B<&b>()); // pointers to members template struct B

{}; template struct B

{}; template char &f(B b); // expected-note {{candidate}} template short &f(B b); // expected-note {{candidate}} struct X { int n; int *p; int **pp; typedef int a, b; }; auto t = f(B<&X::n>()); // expected-error {{no match}} char &u = f(B<&X::p>()); short &v = f(B<&X::pp>()); // A case where we need to do auto-deduction, and check whether the // resulting dependent types match during partial ordering. These // templates are not ordered due to the mismatching function parameter. template struct B {}; // expected-note {{matches}} template struct B {}; // expected-note {{matches}} int **g(X, int); B<&g> bg; // expected-error {{ambiguous}} } namespace Chained { // chained template argument deduction template struct C { }; template struct D; template struct D> { using Q = T; }; using DQ = long; using DQ = D>::Q; // chained template argument deduction from an array bound template struct E; template struct E { using Q = T; }; using EQ = E::Q; using EQ = decltype(sizeof 0); template struct F; template int foo(F *) = delete; // expected-note {{explicitly deleted}} void foo(void *); // expected-note {{candidate function}} void bar(F<0> *p) { foo(p); // expected-error {{deleted function}} } } namespace ArrayToPointer { constexpr char s[] = "test"; template struct S { }; S p; } namespace DecltypeAuto { template struct A { }; template struct DA { }; template struct R { }; auto n = 0; // expected-note + {{declared here}} A a; // expected-error {{not a constant}} expected-note {{non-const variable 'n'}} DA da1; // expected-error {{not a constant}} expected-note {{non-const variable 'n'}} DA<(n)> da2; R r; } namespace Decomposition { // Types of deduced non-type template arguments must match exactly, so // partial ordering fails in both directions here. template struct Any; template struct Any { typedef int Int; }; // expected-note 3{{match}} template struct Any { typedef int Short; }; // expected-note 3{{match}} Any<0>::Int is_int; // expected-error {{ambiguous}} Any<(short)0>::Short is_short; // expected-error {{ambiguous}} Any<(char)0>::Short is_char; // expected-error {{ambiguous}} template struct NestedAny; template struct NestedAny<0, N>; // expected-note 3{{match}} template struct NestedAny<0, N> { typedef int Int; }; // expected-note 3{{match}} template struct NestedAny<0, N> { typedef int Short; }; // expected-note 3{{match}} NestedAny<0, 0>::Int nested_int; // expected-error {{ambiguous}} NestedAny<0, (short)0>::Short nested_short; // expected-error {{ambiguous}} NestedAny<0, (char)0>::Short nested_char; // expected-error {{ambiguous}} double foo(int, bool); template struct fn_result_type; template struct fn_result_type { using type = R; }; using R1 = fn_result_type::type; using R1 = double; template struct fn_result_type_partial_order; template struct fn_result_type_partial_order<0, f>; template struct fn_result_type_partial_order<0, f> {}; fn_result_type_partial_order<0, foo> frtpo; } namespace Variadic { template struct value_list { }; using size_t = decltype(sizeof 0); template struct nth_element; template constexpr auto nth_element_v = nth_element::value; template struct nth_element> { static constexpr auto value = nth_element>::value; }; template struct nth_element<0, value_list> { static constexpr auto value = v0; }; static_assert(nth_element_v<2, value_list<'a', 27U, false>> == false, "value mismatch"); } } namespace Nested { template struct A { template struct B; template struct B

; template struct B

{ using pointee = decltype(+**P); }; template struct B

{ using param = T; }; template struct B

{ using param2 = U; }; }; using Int = int; int *n; using Int = A::B<&n>::pointee; void f(int); using Int = A::B<&f>::param; void g(int, int); using Int = A::B<&g>::param2; }