r290792 - [c++17] Implement P0522R0 as written. This allows a template template argument

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sun Jan 1 18:49:21 PST 2017


Thanks both of you, r290807.

On 1 January 2017 at 07:28, Erik Pilkington <erik.pilkington at gmail.com>
wrote:

>
> > On Dec 31, 2016, at 4:41 PM, Richard Smith via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
> >
> > Author: rsmith
> > Date: Sat Dec 31 15:41:23 2016
> > New Revision: 290792
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=290792&view=rev
> > Log:
> > [c++17] Implement P0522R0 as written. This allows a template template
> argument
> > to be specified for a template template parameter whenever the parameter
> is at
> > least as specialized as the argument (when there's an obvious and correct
> > mapping from uses of the parameter to uses of the argument). For
> example, a
> > template with more parameters can be passed to a template template
> parameter
> > with fewer, if those trailing parameters have default arguments.
> >
> > This is disabled by default, despite being a DR resolution, as it's
> fairly
> > broken in its current state: there are no partial ordering rules to cope
> with
> > template template parameters that have different parameter lists,
> meaning that
> > code that attempts to decompose template-ids based on arity can hit
> unavoidable
> > ambiguity issues.
> >
> > The diagnostics produced on a non-matching argument are also pretty bad
> right
> > now, but I aim to improve them in a subsequent commit.
> >
> > Added:
> >    cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp
> > Modified:
> >    cfe/trunk/include/clang/Basic/LangOptions.def
> >    cfe/trunk/include/clang/Driver/Options.td
> >    cfe/trunk/include/clang/Sema/Sema.h
> >    cfe/trunk/lib/Driver/Tools.cpp
> >    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> >    cfe/trunk/lib/Sema/SemaTemplate.cpp
> >    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
> >    cfe/trunk/test/SemaTemplate/temp_arg_template.cpp
> >    cfe/trunk/www/cxx_status.html
> >
> > Modified: cfe/trunk/include/clang/Basic/LangOptions.def
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Basic/LangOptions.def?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/include/clang/Basic/LangOptions.def (original)
> > +++ cfe/trunk/include/clang/Basic/LangOptions.def Sat Dec 31 15:41:23
> 2016
> > @@ -134,6 +134,7 @@ LANGOPT(NoBuiltin         , 1, 0, "disab
> > LANGOPT(NoMathBuiltin     , 1, 0, "disable math builtin functions")
> > LANGOPT(GNUAsm            , 1, 1, "GNU-style inline assembly")
> > LANGOPT(CoroutinesTS      , 1, 0, "C++ coroutines TS")
> > +LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of
> tempalte template arguments")
> >
> > BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static
> initializers")
> > LANGOPT(POSIXThreads      , 1, 0, "POSIX thread support")
> >
> > Modified: cfe/trunk/include/clang/Driver/Options.td
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Driver/Options.td?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/include/clang/Driver/Options.td (original)
> > +++ cfe/trunk/include/clang/Driver/Options.td Sat Dec 31 15:41:23 2016
> > @@ -1088,6 +1088,11 @@ def fapplication_extension : Flag<["-"],
> >   HelpText<"Restrict code to those available for App Extensions">;
> > def fno_application_extension : Flag<["-"], "fno-application-extension">,
> >   Group<f_Group>;
> > +def frelaxed_template_template_args : Flag<["-"],
> "frelaxed-template-template-args">,
> > +  Flags<[CC1Option]>, HelpText<"Enable C++17 relaxed template template
> argument matching">,
> > +  Group<f_Group>;
> > +def fno_relaxed_template_template_args : Flag<["-"],
> "fno-relaxed-template-template-args">,
> > +  Group<f_Group>;
> > def fsized_deallocation : Flag<["-"], "fsized-deallocation">,
> Flags<[CC1Option]>,
> >   HelpText<"Enable C++14 sized global deallocation functions">,
> Group<f_Group>;
> > def fno_sized_deallocation: Flag<["-"], "fno-sized-deallocation">,
> Group<f_Group>;
> >
> > Modified: cfe/trunk/include/clang/Sema/Sema.h
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
> clang/Sema/Sema.h?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/include/clang/Sema/Sema.h (original)
> > +++ cfe/trunk/include/clang/Sema/Sema.h Sat Dec 31 15:41:23 2016
> > @@ -6719,6 +6719,9 @@ public:
> >   bool isMoreSpecializedThanPrimary(VarTemplatePartialSpecializationDecl
> *T,
> >                                     sema::TemplateDeductionInfo &Info);
> >
> > +  bool isTemplateTemplateParameterAtLeastAsSpecializedAs(
> > +      TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc);
> > +
> >   void MarkUsedTemplateParameters(const TemplateArgumentList
> &TemplateArgs,
> >                                   bool OnlyDeduced,
> >                                   unsigned Depth,
> >
> > Modified: cfe/trunk/lib/Driver/Tools.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/
> Tools.cpp?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/lib/Driver/Tools.cpp (original)
> > +++ cfe/trunk/lib/Driver/Tools.cpp Sat Dec 31 15:41:23 2016
> > @@ -6020,6 +6020,13 @@ void Clang::ConstructJob(Compilation &C,
> >                     options::OPT_fno_assume_sane_operator_new))
> >     CmdArgs.push_back("-fno-assume-sane-operator-new");
> >
> > +  // -frelaxed-template-template-args is off by default, as it is a
> severe
> > +  // breaking change until a corresponding change to template partial
> ordering
> > +  // is provided.
> > +  if (Args.hasFlag(options::OPT_frelaxed_template_template_args,
> > +                   options::OPT_fno_relaxed_template_template_args,
> false))
> > +    CmdArgs.push_back("-frelaxed-template-template-args");
> > +
> >   // -fsized-deallocation is off by default, as it is an ABI-breaking
> change for
> >   // most platforms.
> >   if (Args.hasFlag(options::OPT_fsized_deallocation,
> >
> > Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/
> Frontend/CompilerInvocation.cpp?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
> > +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Sat Dec 31 15:41:23
> 2016
> > @@ -1960,6 +1960,8 @@ static void ParseLangArgs(LangOptions &O
> >   if (!Opts.NoBuiltin)
> >     getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
> >   Opts.NoMathBuiltin = Args.hasArg(OPT_fno_math_builtin);
> > +  Opts.RelaxedTemplateTemplateArgs =
> > +      Args.hasArg(OPT_frelaxed_template_template_args);
> >   Opts.SizedDeallocation = Args.hasArg(OPT_fsized_deallocation);
> >   Opts.AlignedAllocation =
> >       Args.hasFlag(OPT_faligned_allocation, OPT_fno_aligned_allocation,
> >
> > Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaTemplate.cpp?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sat Dec 31 15:41:23 2016
> > @@ -5585,6 +5585,10 @@ ExprResult Sema::CheckTemplateArgument(N
> >   return Arg;
> > }
> >
> > +static void DiagnoseTemplateParameterListArityMismatch(
> > +    Sema &S, TemplateParameterList *New, TemplateParameterList *Old,
> > +    Sema::TemplateParameterListEqualKind Kind, SourceLocation
> TemplateArgLoc);
> > +
> > /// \brief Check a template argument against its corresponding
> > /// template template parameter.
> > ///
> > @@ -5601,6 +5605,9 @@ bool Sema::CheckTemplateArgument(Templat
> >     return false;
> >   }
> >
> > +  if (Template->isInvalidDecl())
> > +    return true;
> > +
> >   // C++0x [temp.arg.template]p1:
> >   //   A template-argument for a template template-parameter shall be
> >   //   the name of a class template or an alias template, expressed as an
> > @@ -5628,6 +5635,25 @@ bool Sema::CheckTemplateArgument(Templat
> >   if (Param->isExpandedParameterPack())
> >     Params = Param->getExpansionTemplateParameters(ArgumentPackIndex);
> >
> > +  // C++1z [temp.arg.template]p3: (DR 150)
> > +  //   A template-argument matches a template template-parameter P when
> P
> > +  //   is at least as specialized as the template-argument A.
> > +  if (getLangOpts().RelaxedTemplateTemplateArgs) {
> > +    // Quick check for the common case:
> > +    //   If P contains a parameter pack, then A [...] matches P if each
> of A's
> > +    //   template parameters matches the corresponding template
> parameter in
> > +    //   the template-parameter-list of P.
> > +    if (TemplateParameterListsAreEqual(
> > +            Template->getTemplateParameters(), Params, false,
> > +            TPL_TemplateTemplateArgumentMatch, Arg.getLocation()))
> > +      return false;
> > +
> > +    if (isTemplateTemplateParameterAtLeastAsSpecializedAs(Params,
> Template,
> > +
> Arg.getLocation()))
> > +      return false;
> > +    // FIXME: Produce better diagnostics for deduction failures.
> > +  }
> > +
> >   return !TemplateParameterListsAreEqual(Template->
> getTemplateParameters(),
> >                                          Params,
> >                                          true,
> > @@ -5839,7 +5865,7 @@ static bool MatchTemplateParameterKind(S
> >     return false;
> >   }
> >
> > -  // Check that both are parameter packs are neither are parameter
> packs.
> > +  // Check that both are parameter packs or neither are parameter packs.
> >   // However, if we are matching a template template argument to a
> >   // template template parameter, the template template parameter can
> have
> >   // a parameter pack where the template template argument does not.
> >
> > Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/
> SemaTemplateDeduction.cpp?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sat Dec 31 15:41:23
> 2016
> > @@ -1898,11 +1898,11 @@ DeduceTemplateArguments(Sema &S, Templat
> >         return NumberOfArgumentsMustMatch ? Sema::TDK_TooFewArguments
> >                                           : Sema::TDK_Success;
> >
> > -      if (Args[ArgIdx].isPackExpansion()) {
> > -        // FIXME: We follow the logic of C++0x [temp.deduct.type]p22
> here,
> > -        // but applied to pack expansions that are template arguments.
> > +      // C++1z [temp.deduct.type]p9:
> > +      //   During partial ordering, if Ai was originally a pack
> expansion [and]
> > +      //   Pi is not a pack expansion, template argument deduction
> fails.
> > +      if (Args[ArgIdx].isPackExpansion())
> >         return Sema::TDK_MiscellaneousDeductionFailure;
> > -      }
> >
> >       // Perform deduction for this Pi/Ai pair.
> >       if (Sema::TemplateDeductionResult Result
> > @@ -1965,7 +1965,8 @@ DeduceTemplateArguments(Sema &S,
> >                         TemplateDeductionInfo &Info,
> >                         SmallVectorImpl<DeducedTemplateArgument>
> &Deduced) {
> >   return DeduceTemplateArguments(S, TemplateParams, ParamList.asArray(),
> > -                                 ArgList.asArray(), Info, Deduced,
> false);
> > +                                 ArgList.asArray(), Info, Deduced,
> > +                                 /*NumberOfArgumentsMustMatch*/false);
> > }
> >
> > /// \brief Determine whether two template arguments are the same.
> > @@ -4581,13 +4582,13 @@ UnresolvedSetIterator Sema::getMostSpeci
> > /// Determine whether one partial specialization, P1, is at least as
> > /// specialized than another, P2.
> > ///
> > -/// \tparam PartialSpecializationDecl The kind of P2, which must be a
> > -/// {Class,Var}Template{PartialSpecialization,}Decl.
> > +/// \tparam TemplateLikeDecl The kind of P2, which must be a
> > +/// TemplateDecl or {Class,Var}TemplatePartialSpecializationDecl.
> > /// \param T1 The injected-class-name of P1 (faked for a variable
> template).
> > /// \param T2 The injected-class-name of P2 (faked for a variable
> template).
> > -template<typename PartialSpecializationDecl>
> > +template<typename TemplateLikeDecl>
> > static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2,
> > -                                     PartialSpecializationDecl *P2,
> > +                                     TemplateLikeDecl *P2,
> >                                      TemplateDeductionInfo &Info) {
> >   // C++ [temp.class.order]p1:
> >   //   For two class template partial specializations, the first is at
> least as
> > @@ -4729,6 +4730,72 @@ bool Sema::isMoreSpecializedThanPrimary(
> >   return true;
> > }
> >
> > +bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
> > +     TemplateParameterList *P, TemplateDecl *AArg, SourceLocation Loc) {
> > +  // C++1z [temp.arg.template]p4: (DR 150)
> > +  //   A template template-parameter P is at least as specialized as a
> > +  //   template template-argument A if, given the following rewrite to
> two
> > +  //   function templates...
> > +
> > +  // Rather than synthesize function templates, we merely perform the
> > +  // equivalent partial ordering by performing deduction directly on
> > +  // the template parameter lists of the template template parameters.
> > +  //
> > +  //   Given an invented class template X with the template parameter
> list of
> > +  //   A (including default arguments):
> > +  TemplateName X = Context.getCanonicalTemplateName(
> TemplateName(AArg));
> > +  TemplateParameterList *A = AArg->getTemplateParameters();
> > +
> > +  //    - Each function template has a single function parameter whose
> type is
> > +  //      a specialization of X with template arguments corresponding
> to the
> > +  //      template parameters from the respective function template
> > +  SmallVector<TemplateArgument, 8> AArgs;
> > +  Context.getInjectedTemplateArgs(A, AArgs);
> > +
> > +  // Check P's arguments against A's parameter list. This will fill in
> default
> > +  // template arguments as needed. AArgs are already correct by
> construction.
> > +  // We can't just use CheckTemplateIdType because that will expand
> alias
> > +  // templates.
> > +  SmallVector<TemplateArgument, 4> PArgs;
> > +  {
> > +    SFINAETrap Trap(*this);
> > +
> > +    Context.getInjectedTemplateArgs(P, PArgs);
> > +    TemplateArgumentListInfo PArgList(P->getLAngleLoc(),
> P->getRAngleLoc());
> > +    for (unsigned I = 0, N = P->size(); I != N; ++I) {
> > +      // Unwrap packs that getInjectedTemplateArgs wrapped around pack
> > +      // expansions, to form an "as written" argument list.
> > +      TemplateArgument Arg = PArgs[I];
> > +      if (Arg.getKind() == TemplateArgument::Pack) {
> > +        assert(Arg.pack_size() == 1 && Arg.pack_begin()->
> isPackExpansion());
> > +        Arg = *Arg.pack_begin();
> > +      }
> > +      PArgList.addArgument(getTrivialTemplateArgumentLoc(
> > +          Arg, QualType(), P->getParam(I)->getLocation()));
> > +    }
> > +    PArgs.clear();
> > +
> > +    // C++1z [temp.arg.template]p3:
> > +    //   If the rewrite produces an invalid type, then P is not at
> least as
> > +    //   specialized as A.
> > +    if (CheckTemplateArgumentList(AArg, Loc, PArgList, false, PArgs) ||
> > +        Trap.hasErrorOccurred())
> > +      return false;
> > +  }
> > +
> > +  QualType AType = Context.getTemplateSpecializationType(X, AArgs);
> > +  QualType PType = Context.getTemplateSpecializationType(X, PArgs);
> > +
> > +  SmallVector<DeducedTemplateArgument, 4> Deduced;
> > +  Deduced.resize(A->size());
>
> Looks like Deduced is unused here!
>
> > +
> > +  //   ... the function template corresponding to P is at least as
> specialized
> > +  //   as the function template corresponding to A according to the
> partial
> > +  //   ordering rules for function templates.
> > +  TemplateDeductionInfo Info(Loc, A->getDepth());
> > +  return isAtLeastAsSpecializedAs(*this, PType, AType, AArg, Info);
> > +}
> > +
> > static void
> > MarkUsedTemplateParameters(ASTContext &Ctx,
> >                            const TemplateArgument &TemplateArg,
> >
> > Modified: cfe/trunk/test/SemaTemplate/temp_arg_template.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaTemplate/temp_arg_template.cpp?rev=290792&r1=
> 290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/test/SemaTemplate/temp_arg_template.cpp (original)
> > +++ cfe/trunk/test/SemaTemplate/temp_arg_template.cpp Sat Dec 31
> 15:41:23 2016
> > @@ -6,11 +6,12 @@ template<template<typename T> class X> s
> >
> > template<template<typename T, int I> class X> struct B; //
> expected-note{{previous template template parameter is here}}
> >
> > -template<template<int I> class X> struct C;  // expected-note{{previous
> non-type template parameter with type 'int' is here}}
> > +template<template<int I> class X> struct C;  // expected-note
> 2{{previous non-type template parameter with type 'int' is here}}
> >
> > template<class> struct X; // expected-note{{too few template parameters
> in template template argument}}
> > template<int N> struct Y; // expected-note{{template parameter has a
> different kind in template argument}}
> > template<long N> struct Ylong; // expected-note{{template non-type
> parameter has a different type 'long' in template argument}}
> > +template<const int &N> struct Yref; // expected-note{{template non-type
> parameter has a different type 'const int &' in template argument}}
> >
> > namespace N {
> >   template<class> struct Z;
> > @@ -27,6 +28,7 @@ A<TooMany> *a5; // expected-error{{templ
> > B<X> *a6; // expected-error{{template template argument has different
> template parameters than its corresponding template template parameter}}
> > C<Y> *a7;
> > C<Ylong> *a8; // expected-error{{template template argument has
> different template parameters than its corresponding template template
> parameter}}
> > +C<Yref> *a9; // expected-error{{template template argument has
> different template parameters than its corresponding template template
> parameter}}
> >
> > template<typename T> void f(int);
> >
> >
> > Added: cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaTemplate/temp_arg_template_cxx1z.cpp?rev=290792&view=auto
> > ============================================================
> ==================
> > --- cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp (added)
> > +++ cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp Sat Dec 31
> 15:41:23 2016
> > @@ -0,0 +1,102 @@
> > +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z
> -frelaxed-template-template-args %s
> > +
> > +// expected-note at temp_arg_template_cxx1z.cpp:* 1+{{}}
> > +
> > +template<template<int> typename> struct Ti;
> > +template<template<int...> typename> struct TPi;
> > +template<template<int, int...> typename> struct TiPi;
> > +template<template<int..., int...> typename> struct TPiPi; // FIXME: Why
> is this not ill-formed?
> > +
> > +template<typename T, template<T> typename> struct tT0;
> > +template<template<typename T, T> typename> struct Tt0;
> > +
> > +template<template<typename> typename> struct Tt;
> > +template<template<typename, typename...> typename> struct TtPt;
> > +
> > +template<int> struct i;
> > +template<int, int = 0> struct iDi;
> > +template<int, int> struct ii;
> > +template<int...> struct Pi;
> > +template<int, int, int...> struct iiPi;
> > +
> > +template<int, typename = int> struct iDt;
> > +template<int, typename> struct it;
> > +
> > +template<typename T, T v> struct t0;
> > +
> > +template<typename...> struct Pt;
> > +
> > +namespace IntParam {
> > +  using ok = Pt<Ti<i>,
> > +        Ti<iDi>,
> > +        Ti<Pi>,
> > +        Ti<iDt>>;
> > +  using err1 = Ti<ii>; // expected-error {{different template
> parameters}}
> > +  using err2 = Ti<iiPi>; // expected-error {{different template
> parameters}}
> > +  using err3 = Ti<t0>; // expected-error {{different template
> parameters}}
> > +  using err4 = Ti<it>; // 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<Pi>;
> > +  using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>;
> > +  using err1 = TPi<t0>; // expected-error {{different template
> parameters}}
> > +  using err2 = TPi<iDt>; // expected-error {{different template
> parameters}}
> > +  using err3 = TPi<it>; // expected-error {{different template
> parameters}}
> > +}
> > +
> > +namespace IntAndPackParam {
> > +  using ok = TiPi<Pi>;
> > +  using ok_compat = Pt<TiPi<ii>, TiPi<iDi>, TiPi<iiPi>>;
> > +  using err = TiPi<iDi>;
> > +}
> > +
> > +namespace DependentType {
> > +  using ok = Pt<tT0<int, i>, tT0<int, iDi>>;
> > +  using err1 = tT0<int, ii>; // expected-error {{different template
> parameters}}
> > +  using err2 = tT0<short, i>; // FIXME: should this be OK?
> > +  using err2a = tT0<long long, i>; // FIXME: should this be OK (if long
> long is larger than int)?
> > +  using err2b = tT0<void*, i>; // expected-error {{different template
> parameters}}
> > +  using err3 = tT0<short, t0>; // expected-error {{different template
> parameters}}
> > +
> > +  using ok2 = Tt0<t0>;
> > +  using err4 = Tt0<it>; // expected-error {{different template
> parameters}}
> > +}
> > +
> > +namespace Auto {
> > +  template<template<int> typename T> struct TInt {};
> > +  template<template<int*> typename T> struct TIntPtr {};
> > +  template<template<auto> typename T> struct TAuto {};
> > +  template<template<auto*> typename T> struct TAutoPtr {};
> > +  template<auto> struct Auto;
> > +  template<auto*> struct AutoPtr;
> > +  template<int> struct Int;
> > +  template<int*> struct IntPtr;
> > +
> > +  TInt<Auto> ia;
> > +  TInt<AutoPtr> iap; // FIXME: ill-formed
> > +  TInt<Int> ii;
> > +  TInt<IntPtr> iip; // expected-error {{different template parameters}}
> > +
> > +  TIntPtr<Auto> ipa;
> > +  TIntPtr<AutoPtr> ipap;
> > +  TIntPtr<Int> ipi; // expected-error {{different template parameters}}
> > +  TIntPtr<IntPtr> ipip;
> > +
> > +  TAuto<Auto> aa;
> > +  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; // FIXME: ill-formed
> > +  TAutoPtr<IntPtr> apip; // FIXME: ill-formed
> > +
> > +  int n;
> > +  template<auto A, decltype(A) B = &n> struct SubstFailure;
> > +  TInt<SubstFailure> isf; // expected-error {{different template
> parameters}}
> > +  TIntPtr<SubstFailure> ipsf; // expected-error {{different template
> parameters}}
> > +}
> >
> > Modified: cfe/trunk/www/cxx_status.html
> > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_
> status.html?rev=290792&r1=290791&r2=290792&view=diff
> > ============================================================
> ==================
> > --- cfe/trunk/www/cxx_status.html (original)
> > +++ cfe/trunk/www/cxx_status.html Sat Dec 31 15:41:23 2016
> > @@ -733,7 +733,7 @@ as the draft C++1z standard evolves.
> >     <tr>
> >       <td>Matching template template parameters to compatible
> arguments</td>
> >       <td><a href="http://wg21.link/p0522r0">P0522R0</a></td>
> > -      <td class="none" align="center">No <a href="#p0522">(12)</a></td>
> > +      <td class="partial" align="center">Partial <a
> href="#p0522">(12)</a></td>
> >     </tr>
> >     <tr>
> >       <td>Removing deprecated dynamic exception specifications</td>
> > @@ -763,8 +763,12 @@ left to right in the callee. As a result
> > functions using expression syntax are no longer guaranteed to be
> destroyed in
> > reverse construction order in that ABI.
> > </span><br>
> > -<span id="p0522">(12): This is the resolution to a Defect Report, so
> will be
> > -applied to all language versions.
> > +<span id="p0522">(12): Despite being the the resolution to a Defect
> Report, this
> > +feature is disabled by default in all language versions, and can be
> enabled
> > +explicitly with the flag <tt>-frelaxed-template-template-args</tt>.
> The change
> > +to the standard lacks a corresponding change for template partial
> ordering,
> > +resulting in ambiguity errors for reasonable and previously-valid code.
> This
> > +issue is expected to be rectified soon.
> > </span>
> > </p>
> > </details>
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170101/9c31dc77/attachment-0001.html>


More information about the cfe-commits mailing list