summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-06-26 07:48:46 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-06-26 07:48:46 +0000
commita7e2b09e84da88716b148b4042164e7b321aa13d (patch)
tree2056c8d18b73953f55c356fa9076129c63314174
parentbbd68e1f187894ba4562dcf4aaf9acd65f3cf5d0 (diff)
downloadclang-a7e2b09e84da88716b148b4042164e7b321aa13d.tar.gz
clang-a7e2b09e84da88716b148b4042164e7b321aa13d.tar.bz2
clang-a7e2b09e84da88716b148b4042164e7b321aa13d.tar.xz
Sema: Allow dllimport entities in template args for mingw
Previously dllimport variables inside of template arguments relied on not using the C++11 codepath when -fms-compatibility was set. While this allowed us to achieve compatibility with MSVC, it did so at the expense of MingW. Instead, try to use the DeclRefExpr we dig out of the template argument. If it has the dllimport attribute, accept it and skip the C++11 null-pointer check. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211766 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplate.cpp45
-rw-r--r--test/SemaCXX/PR19955.cpp3
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}}