diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-28 06:27:18 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-28 06:27:18 +0000 |
commit | 15361a21e01026e74cb17011b702c7d1c881ae94 (patch) | |
tree | 76c2b63c54704b2b79c6f9059e9b5463cdb4df64 /clang/lib/Sema/SemaTemplate.cpp | |
parent | 873c275caa6d8ece36eb4f799e37ba1e6e1674bf (diff) | |
download | bcm5719-llvm-15361a21e01026e74cb17011b702c7d1c881ae94.tar.gz bcm5719-llvm-15361a21e01026e74cb17011b702c7d1c881ae94.zip |
Mark 'auto' as dependent when instantiating the type of a non-type template
parameter. Fixes failed deduction for 'auto' non-type template parameters
nested within templates.
llvm-svn: 290660
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 996a8baee1d..55421a3e0b0 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -729,8 +729,22 @@ Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, /// /// \returns the (possibly-promoted) parameter type if valid; /// otherwise, produces a diagnostic and returns a NULL type. -QualType -Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) { +QualType Sema::CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, + SourceLocation Loc) { + if (TSI->getType()->isUndeducedType()) { + // C++1z [temp.dep.expr]p3: + // An id-expression is type-dependent if it contains + // - an identifier associated by name lookup with a non-type + // template-parameter declared with a type that contains a + // placeholder type (7.1.7.4), + TSI = SubstAutoTypeSourceInfo(TSI, Context.DependentTy); + } + + return CheckNonTypeTemplateParameterType(TSI->getType(), Loc); +} + +QualType Sema::CheckNonTypeTemplateParameterType(QualType T, + SourceLocation Loc) { // We don't allow variably-modified types as the type of non-type template // parameters. if (T->isVariablyModifiedType()) { @@ -759,10 +773,6 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) { T->isDependentType() || // Allow use of auto in template parameter declarations. T->isUndeducedType()) { - if (T->isUndeducedType()) { - Diag(Loc, diag::warn_cxx14_compat_template_nontype_parm_auto_type) - << QualType(T->getContainedAutoType(), 0); - } // C++ [temp.param]p5: The top-level cv-qualifiers on the template-parameter // are ignored when determining its type. return T.getUnqualifiedType(); @@ -788,13 +798,18 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, SourceLocation EqualLoc, Expr *Default) { TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); - QualType T = TInfo->getType(); + + if (TInfo->getType()->isUndeducedType()) { + Diag(D.getIdentifierLoc(), + diag::warn_cxx14_compat_template_nontype_parm_auto_type) + << QualType(TInfo->getType()->getContainedAutoType(), 0); + } assert(S->isTemplateParamScope() && "Non-type template parameter not in template parameter scope!"); bool Invalid = false; - T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc()); + QualType T = CheckNonTypeTemplateParameterType(TInfo, D.getIdentifierLoc()); if (T.isNull()) { T = Context.IntTy; // Recover with an 'int' type. Invalid = true; |