// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z -frelaxed-template-template-args %s // expected-note@temp_arg_template_cxx1z.cpp:* 1+{{}} template typename> struct Ti; template typename> struct TPi; template typename> struct TiPi; template typename> struct TPiPi; // FIXME: Why is this not ill-formed? template typename> struct tT0; template typename> struct Tt0; template typename> struct Tt; template typename> struct TtPt; template struct i; template struct iDi; template struct ii; template struct Pi; template struct iiPi; template struct iDt; template struct it; template struct t0; template struct Pt; namespace IntParam { using ok = Pt, Ti, Ti, Ti>; using err1 = Ti; // expected-error {{different template parameters}} using err2 = Ti; // expected-error {{different template parameters}} using err3 = Ti; // expected-error {{different template parameters}} using err4 = Ti; // expected-error {{different template parameters}} } // These are accepted by the backwards-compatibility "parameter pack in // parameter matches any number of parameters in arguments" rule. namespace IntPackParam { using ok = TPi; using ok_compat = Pt, TPi, TPi, TPi>; using err1 = TPi; // expected-error {{different template parameters}} using err2 = TPi; // expected-error {{different template parameters}} using err3 = TPi; // expected-error {{different template parameters}} } namespace IntAndPackParam { using ok = TiPi; using ok_compat = Pt, TiPi, TiPi>; using err = TiPi; } namespace DependentType { using ok = Pt, tT0>; using err1 = tT0; // expected-error {{different template parameters}} using err2 = tT0; // FIXME: should this be OK? using err2a = tT0; // FIXME: should this be OK (if long long is larger than int)? using err2b = tT0; // expected-error {{different template parameters}} using err3 = tT0; // expected-error {{different template parameters}} using ok2 = Tt0; using err4 = Tt0; // expected-error {{different template parameters}} } namespace Auto { template typename T> struct TInt {}; template typename T> struct TIntPtr {}; template typename T> struct TAuto {}; template typename T> struct TAutoPtr {}; template typename T> struct TDecltypeAuto {}; template struct Auto; template struct AutoPtr; template struct DecltypeAuto; template struct Int; template struct IntPtr; TInt ia; TInt iap; // FIXME: ill-formed (?) TInt ida; TInt ii; TInt iip; // expected-error {{different template parameters}} TIntPtr ipa; TIntPtr ipap; TIntPtr ipda; TIntPtr ipi; // expected-error {{different template parameters}} TIntPtr ipip; TAuto aa; TAuto aap; // FIXME: ill-formed (?) TAuto ai; // FIXME: ill-formed (?) TAuto aip; // FIXME: ill-formed (?) TAutoPtr apa; TAutoPtr apap; TAutoPtr api; // FIXME: ill-formed (?) TAutoPtr apip; // FIXME: ill-formed (?) TDecltypeAuto dada; TDecltypeAuto dai; // FIXME: ill-formed (?) TDecltypeAuto daip; // FIXME: ill-formed (?) // FIXME: It's completely unclear what should happen here, but these results // seem at least plausible: TAuto ada; TAutoPtr apda; // Perhaps this case should be invalid, as there are valid 'decltype(auto)' // parameters (such as 'user-defined-type &') that are not valid 'auto' // parameters. TDecltypeAuto daa; TDecltypeAuto daap; // FIXME: should probably be ill-formed int n; template struct SubstFailure; TInt isf; // FIXME: this should be ill-formed TIntPtr ipsf; }