diff options
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 32d51d5d412..5a188453b4f 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4337,22 +4337,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, Expr *Arg = ArgIn; QualType ArgType = Arg->getType(); - // If our parameter has pointer type, check for a null template value. - if (ParamType->isPointerType() || ParamType->isNullPtrType()) { - switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) { - case NPV_NullPointer: - S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); - Converted = TemplateArgument(ParamType, /*isNullPtr*/true); - return false; - - case NPV_Error: - return true; - - case NPV_NotNullPointer: - break; - } - } - bool AddressTaken = false; SourceLocation AddrOpLoc; if (S.getLangOpts().MicrosoftExt) { @@ -4440,6 +4424,32 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, Arg = subst->getReplacement()->IgnoreImpCasts(); } + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg); + ValueDecl *Entity = DRE ? DRE->getDecl() : nullptr; + + // If our parameter has pointer type, check for a null template value. + if (ParamType->isPointerType() || ParamType->isNullPtrType()) { + NullPointerValueKind NPV; + // dllimport'd entities aren't constant but are available inside of template + // arguments. + if (Entity && Entity->hasAttr<DLLImportAttr>()) + NPV = NPV_NotNullPointer; + else + NPV = isNullPointerValueTemplateArgument(S, Param, ParamType, ArgIn); + switch (NPV) { + case NPV_NullPointer: + S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null); + Converted = TemplateArgument(ParamType, /*isNullPtr=*/true); + return false; + + case NPV_Error: + return true; + + case NPV_NotNullPointer: + break; + } + } + // Stop checking the precise nature of the argument if it is value dependent, // it should be checked when instantiated. if (Arg->isValueDependent()) { @@ -4456,7 +4466,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, return false; } - DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg); if (!DRE) { S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref) << Arg->getSourceRange(); @@ -4464,8 +4473,6 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, return true; } - ValueDecl *Entity = DRE->getDecl(); - // Cannot refer to non-static data members if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) { S.Diag(Arg->getLocStart(), diag::err_template_arg_field) |