diff options
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Modules/cxx-templates.cpp | 10 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp | 18 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/deduction.cpp | 7 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/temp_arg_template.cpp | 41 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp | 18 |
5 files changed, 64 insertions, 30 deletions
diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index 59e9136bd14..401b7704900 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -49,8 +49,14 @@ void g() { // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}} // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}} - template_param_kinds_3<Tmpl_T_T_A>(); - template_param_kinds_3<Tmpl_T_T_B>(); + // FIXME: This should be valid, but we incorrectly match the template template + // argument against both template template parameters. + template_param_kinds_3<Tmpl_T_T_A>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} + template_param_kinds_3<Tmpl_T_T_B>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} // Trigger the instantiation of a template in 'a' that uses a type defined in // 'common'. That type is not visible here. diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp index 5eee34e8097..d6374e4ce90 100644 --- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -179,9 +179,9 @@ namespace default_args_from_ctor { namespace transform_params { template<typename T, T N, template<T (*v)[N]> typename U, T (*X)[N]> - struct A { // expected-note 2{{candidate}} + struct A { template<typename V, V M, V (*Y)[M], template<V (*v)[M]> typename W> - A(U<X>, W<Y>); // expected-note {{[with V = int, M = 12, Y = &transform_params::n]}} + A(U<X>, W<Y>); static constexpr T v = N; }; @@ -189,9 +189,7 @@ namespace transform_params { int n[12]; template<int (*)[12]> struct Q {}; Q<&n> qn; - // FIXME: The class template argument deduction result here is correct, but - // we incorrectly fail to deduce arguments for the constructor! - A a(qn, qn); // expected-error {{no matching constructor for initialization of 'transform_params::A<int, 12, Q, &transform_params::n>'}} + A a(qn, qn); static_assert(a.v == 12); template<typename ...T> struct B { @@ -203,16 +201,12 @@ namespace transform_params { }; B b({1, 2, 3}, "foo", {'x', 'y', 'z', 'w'}); // ok - // This should be accepted once -std=c++1z implies - // -frelaxed-template-template-args. Without that, a template template - // parameter 'template<int, int, int> typename' cannot bind to a template - // template argument 'template<int...> typename'. - template<typename ...T> struct C { // expected-note {{candidate}} + template<typename ...T> struct C { template<T ...V, template<T...> typename X> - C(X<V...>); // expected-note {{substitution failure [with T = <int, int, int>, V = <0, 1, 2>]}} + C(X<V...>); }; template<int...> struct Y {}; - C c(Y<0, 1, 2>{}); // expected-error {{no viable constructor or deduction guide}} + C c(Y<0, 1, 2>{}); template<typename ...T> struct D { template<T ...V> D(Y<V...>); diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp index 8ac65aacd5b..74eb5a6ee58 100644 --- a/clang/test/SemaTemplate/deduction.cpp +++ b/clang/test/SemaTemplate/deduction.cpp @@ -483,16 +483,15 @@ namespace check_extended_pack { } namespace dependent_template_template_param_non_type_param_type { - template<int N> struct A { // expected-note 2{{candidate}} + template<int N> struct A { template<typename V = int, V M = 12, V (*Y)[M], template<V (*v)[M]> class W> - A(W<Y>); // expected-note {{[with V = int, M = 12, Y = &dependent_template_template_param_non_type_param_type::n]}} + A(W<Y>); }; int n[12]; template<int (*)[12]> struct Q {}; Q<&n> qn; - // FIXME: This should be accepted, but we somehow fail to deduce W. - A<0> a(qn); // expected-error {{no matching constructor for initialization}} + A<0> a(qn); } namespace dependent_list_deduction { diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp index b0df9149c6e..8f59dd724cc 100644 --- a/clang/test/SemaTemplate/temp_arg_template.cpp +++ b/clang/test/SemaTemplate/temp_arg_template.cpp @@ -102,7 +102,42 @@ void foo() { } namespace CheckDependentNonTypeParamTypes { - template<template<typename T, typename U, T v> class> struct A {}; // expected-note {{previous}} - template<typename T, typename U, U v> struct B {}; // expected-note {{different type}} - A<B> ab; // expected-error {{different template parameters}} + template<template<typename T, typename U, T v> class X> struct A { + void f() { + X<int, void*, 3> x; // expected-error {{does not refer to any declaration}} + } + void g() { + X<int, long, 3> x; + } + void h() { + // FIXME: If we accept A<B> at all, it's not obvious what should happen + // here. While parsing the template, we form + // X<unsigned char, int, (unsigned char)1234> + // but in the final instantiation do we get + // B<unsigned char, int, (int)1234> + // or + // B<unsigned char, int, (int)(unsigned char)1234> + // ? + X<unsigned char, int, 1234> x; + int check[x.value == 1234 ? 1 : -1]; + } + }; + + template<typename T, typename U, U v> struct B { // expected-note {{parameter}} + static const U value = v; + }; + + // FIXME: This should probably be rejected, but the rules are at best unclear. + A<B> ab; + + void use() { + ab.f(); // expected-note {{instantiation of}} + ab.g(); + ab.h(); + } +} + +namespace PR32185 { + template<template<typename T, T> class U> struct A {}; + template<template<typename T, T> class U> struct B : A<U> {}; } diff --git a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp index e3f228e7efb..03ef78f8cf1 100644 --- a/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp +++ b/clang/test/SemaTemplate/temp_arg_template_cxx1z.cpp @@ -78,7 +78,7 @@ namespace Auto { template<int*> struct IntPtr; TInt<Auto> ia; - TInt<AutoPtr> iap; // expected-error {{different template parameters}} + TInt<AutoPtr> iap; // FIXME: ill-formed (?) TInt<DecltypeAuto> ida; TInt<Int> ii; TInt<IntPtr> iip; // expected-error {{different template parameters}} @@ -90,18 +90,18 @@ namespace Auto { TIntPtr<IntPtr> ipip; TAuto<Auto> aa; - TAuto<AutoPtr> aap; // expected-error {{different template parameters}} - TAuto<Int> ai; // expected-error {{different template parameters}} - TAuto<IntPtr> aip; // expected-error {{different template parameters}} + TAuto<AutoPtr> aap; // FIXME: ill-formed (?) + TAuto<Int> ai; // FIXME: ill-formed (?) + TAuto<IntPtr> aip; // FIXME: ill-formed (?) TAutoPtr<Auto> apa; TAutoPtr<AutoPtr> apap; - TAutoPtr<Int> api; // expected-error {{different template parameters}} - TAutoPtr<IntPtr> apip; // expected-error {{different template parameters}} + TAutoPtr<Int> api; // FIXME: ill-formed (?) + TAutoPtr<IntPtr> apip; // FIXME: ill-formed (?) TDecltypeAuto<DecltypeAuto> dada; - TDecltypeAuto<Int> dai; // expected-error {{different template parameters}} - TDecltypeAuto<IntPtr> daip; // expected-error {{different template parameters}} + TDecltypeAuto<Int> dai; // FIXME: ill-formed (?) + TDecltypeAuto<IntPtr> daip; // FIXME: ill-formed (?) // FIXME: It's completely unclear what should happen here, but these results // seem at least plausible: @@ -111,7 +111,7 @@ namespace Auto { // parameters (such as 'user-defined-type &') that are not valid 'auto' // parameters. TDecltypeAuto<Auto> daa; - TDecltypeAuto<AutoPtr> daa; // expected-error {{different template parameters}} + TDecltypeAuto<AutoPtr> daap; // FIXME: should probably be ill-formed int n; template<auto A, decltype(A) B = &n> struct SubstFailure; |

