diff options
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 45 | ||||
-rw-r--r-- | test/SemaCXX/PR19955.cpp | 3 |
2 files changed, 28 insertions, 20 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 32d51d5d41..5a188453b4 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/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) diff --git a/test/SemaCXX/PR19955.cpp b/test/SemaCXX/PR19955.cpp index fb1d74631b..cbbe2fe9af 100644 --- a/test/SemaCXX/PR19955.cpp +++ b/test/SemaCXX/PR19955.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple i686-win32 -fms-compatibility -verify -std=c++11 %s +// RUN: %clang_cc1 -triple i686-win32 -verify -std=c++11 %s +// RUN: %clang_cc1 -triple i686-mingw32 -verify -std=c++11 %s extern int __attribute__((dllimport)) var; constexpr int *varp = &var; // expected-error {{must be initialized by a constant expression}} |