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(); + while(auto *DeclRef = dyn_cast_or_null(E)) { + auto *D = DeclRef->getDecl(); + if (isa(D)) + return TemplateArgument(DeclRef); + + auto *VD = dyn_cast(D); + if (!VD) + break; + E = VD->getInit(); + if (E) + E = E->IgnoreImpCasts(); + } return Arg; + } case TemplateArgument::Declaration: { ValueDecl *D = cast(Arg.getAsDecl()->getCanonicalDecl()); 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::type b3; // FIXME: expected-error {{missing 'typename'}} + B::type b3; B::type b4; // expected-error {{missing 'typename'}} - B::type b5; // FIXME: expected-error {{missing 'typename'}} + B::type b5; }; }