[PATCH] D22587: [ASTContext] Fix part of DR224 for nontype template arguments

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 21 09:51:04 PDT 2016


On 20 Jul 2016 1:25 p.m., "Matthias Gehre" <M.Gehre at gmx.de> wrote:
>
> mgehre created this revision.
> mgehre added reviewers: klimek, aaron.ballman, rsmith.
> mgehre added a subscriber: cfe-commits.
>
> Look through expressions to determine if a nontype template argument has
been given the value of the template parameter.
>
> https://reviews.llvm.org/D22587
>
> Files:
>   lib/AST/ASTContext.cpp
>   test/CXX/drs/dr2xx.cpp
>
> Index: test/CXX/drs/dr2xx.cpp
> ===================================================================
> --- test/CXX/drs/dr2xx.cpp
> +++ test/CXX/drs/dr2xx.cpp
> @@ -275,9 +275,9 @@
>        static const int my_I = I;
>        static const int my_I2 = I+0;
>        static const int my_I3 = my_I;
> -      B<my_T1, T2, my_I>::type b3; // FIXME: expected-error {{missing
'typename'}}
> +      B<my_T1, T2, my_I>::type b3;
>        B<my_T1, T2, my_I2>::type b4; // expected-error {{missing
'typename'}}
> -      B<my_T1, T2, my_I3>::type b5; // FIXME: expected-error {{missing
'typename'}}
> +      B<my_T1, T2, my_I3>::type b5;
>      };
>    }
>
> Index: lib/AST/ASTContext.cpp
> ===================================================================
> --- lib/AST/ASTContext.cpp
> +++ lib/AST/ASTContext.cpp
> @@ -4448,8 +4448,26 @@
>      case TemplateArgument::Null:
>        return Arg;
>
> -    case TemplateArgument::Expression:
> +    case TemplateArgument::Expression: {
> +      // Look through variable declarations that have been initialized
to a non-type template
> +      // parameter, see 14.6.2.1 [temp.dep.type]:
> +      // [...], the argument must have been given the value of
> +      // the template parameter and not an expression involving the
template parameter.
> +      auto *E = Arg.getAsExpr()->IgnoreImpCasts();

Are all implicit casts really OK here? If the parameter is narrowed, the
value could change. Perhaps we should only walk through lvalue-to-rvalue
conversions here. What about parentheses, should we skip those?

> +      while(auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(E)) {
> +        auto *D = DeclRef->getDecl();
> +        if (isa<NonTypeTemplateParmDecl>(D))
> +          return TemplateArgument(DeclRef);
> +
> +        auto *VD = dyn_cast<VarDecl>(D);
> +        if (!VD)
> +          break;
> +        E = VD->getInit();
> +        if (E)
> +          E = E->IgnoreImpCasts();
> +      }
>        return Arg;
> +    }
>
>      case TemplateArgument::Declaration: {
>        ValueDecl *D =
cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160721/ef6143c9/attachment-0001.html>


More information about the cfe-commits mailing list