1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -frelaxed-template-template-args %s 2 3 // expected-note@temp_arg_template_cxx1z.cpp:* 1+{{}} 4 5 template<template<int> typename> struct Ti; 6 template<template<int...> typename> struct TPi; 7 template<template<int, int...> typename> struct TiPi; 8 template<template<int..., int...> typename> struct TPiPi; // FIXME: Why is this not ill-formed? 9 10 template<typename T, template<T> typename> struct tT0; 11 template<template<typename T, T> typename> struct Tt0; 12 13 template<template<typename> typename> struct Tt; 14 template<template<typename, typename...> typename> struct TtPt; 15 16 template<int> struct i; 17 template<int, int = 0> struct iDi; 18 template<int, int> struct ii; 19 template<int...> struct Pi; 20 template<int, int, int...> struct iiPi; 21 22 template<int, typename = int> struct iDt; 23 template<int, typename> struct it; 24 25 template<typename T, T v> struct t0; 26 27 template<typename...> struct Pt; 28 29 namespace IntParam { 30 using ok = Pt<Ti<i>, 31 Ti<iDi>, 32 Ti<Pi>, 33 Ti<iDt>>; 34 using err1 = Ti<ii>; // expected-error {{different template parameters}} 35 using err2 = Ti<iiPi>; // expected-error {{different template parameters}} 36 using err3 = Ti<t0>; // expected-error {{different template parameters}} 37 using err4 = Ti<it>; // expected-error {{different template parameters}} 38 } 39 40 // These are accepted by the backwards-compatibility "parameter pack in 41 // parameter matches any number of parameters in arguments" rule. 42 namespace IntPackParam { 43 using ok = TPi<Pi>; 44 using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>; 45 using err1 = TPi<t0>; // expected-error {{different template parameters}} 46 using err2 = TPi<iDt>; // expected-error {{different template parameters}} 47 using err3 = TPi<it>; // expected-error {{different template parameters}} 48 } 49 50 namespace IntAndPackParam { 51 using ok = TiPi<Pi>; 52 using ok_compat = Pt<TiPi<ii>, TiPi<iDi>, TiPi<iiPi>>; 53 using err = TiPi<iDi>; 54 } 55 56 namespace DependentType { 57 using ok = Pt<tT0<int, i>, tT0<int, iDi>>; 58 using err1 = tT0<int, ii>; // expected-error {{different template parameters}} 59 using err2 = tT0<short, i>; // FIXME: should this be OK? 60 using err2a = tT0<long long, i>; // FIXME: should this be OK (if long long is larger than int)? 61 using err2b = tT0<void*, i>; // expected-error {{different template parameters}} 62 using err3 = tT0<short, t0>; // expected-error {{different template parameters}} 63 64 using ok2 = Tt0<t0>; 65 using err4 = Tt0<it>; // expected-error {{different template parameters}} 66 } 67 68 namespace Auto { 69 template<template<int> typename T> struct TInt {}; 70 template<template<int*> typename T> struct TIntPtr {}; 71 template<template<auto> typename T> struct TAuto {}; 72 template<template<auto*> typename T> struct TAutoPtr {}; 73 template<template<decltype(auto)> typename T> struct TDecltypeAuto {}; 74 template<auto> struct Auto; 75 template<auto*> struct AutoPtr; 76 template<decltype(auto)> struct DecltypeAuto; 77 template<int> struct Int; 78 template<int*> struct IntPtr; 79 80 TInt<Auto> ia; 81 TInt<AutoPtr> iap; // FIXME: ill-formed (?) 82 TInt<DecltypeAuto> ida; 83 TInt<Int> ii; 84 TInt<IntPtr> iip; // expected-error {{different template parameters}} 85 86 TIntPtr<Auto> ipa; 87 TIntPtr<AutoPtr> ipap; 88 TIntPtr<DecltypeAuto> ipda; 89 TIntPtr<Int> ipi; // expected-error {{different template parameters}} 90 TIntPtr<IntPtr> ipip; 91 92 TAuto<Auto> aa; 93 TAuto<AutoPtr> aap; // FIXME: ill-formed (?) 94 TAuto<Int> ai; // FIXME: ill-formed (?) 95 TAuto<IntPtr> aip; // FIXME: ill-formed (?) 96 97 TAutoPtr<Auto> apa; 98 TAutoPtr<AutoPtr> apap; 99 TAutoPtr<Int> api; // FIXME: ill-formed (?) 100 TAutoPtr<IntPtr> apip; // FIXME: ill-formed (?) 101 102 TDecltypeAuto<DecltypeAuto> dada; 103 TDecltypeAuto<Int> dai; // FIXME: ill-formed (?) 104 TDecltypeAuto<IntPtr> daip; // FIXME: ill-formed (?) 105 106 // FIXME: It's completely unclear what should happen here, but these results 107 // seem at least plausible: 108 TAuto<DecltypeAuto> ada; 109 TAutoPtr<DecltypeAuto> apda; 110 // Perhaps this case should be invalid, as there are valid 'decltype(auto)' 111 // parameters (such as 'user-defined-type &') that are not valid 'auto' 112 // parameters. 113 TDecltypeAuto<Auto> daa; 114 TDecltypeAuto<AutoPtr> daap; // FIXME: should probably be ill-formed 115 116 int n; 117 template<auto A, decltype(A) B = &n> struct SubstFailure; 118 TInt<SubstFailure> isf; // FIXME: this should be ill-formed 119 TIntPtr<SubstFailure> ipsf; 120 } 121