On 20 Jul 2016 1:25 p.m., "Matthias Gehre" <m.ge...@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()); > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits