summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-11-03 14:24:45 +0000
committerHans Wennborg <hans@hanshq.net>2014-11-03 14:24:45 +0000
commit606bd6dcc547cf2f9fd7387321db79419bf60041 (patch)
tree2acc1255fba6da316a5ec54f4a502cd7ec669fab /clang/lib
parent42bce8f69db28b6b39453ecfbf8da6fc45fb14bf (diff)
downloadbcm5719-llvm-606bd6dcc547cf2f9fd7387321db79419bf60041.tar.gz
bcm5719-llvm-606bd6dcc547cf2f9fd7387321db79419bf60041.zip
Don't dllimport inline functions when targeting MinGW (PR21366)
It turns out that MinGW never dllimports of exports inline functions. This means that code compiled with Clang would fail to link with MinGW-compiled libraries since we might try to import functions that are not imported. To fix this, make Clang never dllimport inline functions when targeting MinGW. llvm-svn: 221154
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp8
-rw-r--r--clang/lib/Sema/SemaDecl.cpp8
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp10
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp27
4 files changed, 44 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 426237711ec..7ecd95ea204 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2003,6 +2003,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
else if (D->hasAttr<DLLExportAttr>())
GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
+ else
+ GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
if (Linkage == llvm::GlobalVariable::CommonLinkage)
// common vars aren't constant even if declared const.
@@ -2338,6 +2340,12 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
// declarations).
auto *Fn = cast<llvm::Function>(GV);
setFunctionLinkage(GD, Fn);
+ if (D->hasAttr<DLLImportAttr>())
+ GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
+ else if (D->hasAttr<DLLExportAttr>())
+ GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
+ else
+ GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
// FIXME: this is redundant with part of setFunctionDefinitionAttributes
setGlobalVisibility(Fn, D);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 734a01e2e30..fe5981121fe 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5185,6 +5185,14 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
OldDecl->dropAttr<DLLImportAttr>();
NewDecl->dropAttr<DLLImportAttr>();
+ } else if (IsInline && OldImportAttr &&
+ !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ // In MinGW, seeing a function declared inline drops the dllimport attribute.
+ OldDecl->dropAttr<DLLImportAttr>();
+ NewDecl->dropAttr<DLLImportAttr>();
+ S.Diag(NewDecl->getLocation(),
+ diag::warn_dllimport_dropped_from_inline_function)
+ << NewDecl << OldImportAttr;
}
}
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index f6a89d73c5e..1b04e52f150 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3999,6 +3999,16 @@ static void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) {
return;
}
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->isInlined() && A.getKind() == AttributeList::AT_DLLImport &&
+ !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ // MinGW doesn't allow dllimport on inline functions.
+ S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
+ << A.getName();
+ return;
+ }
+ }
+
unsigned Index = A.getAttributeSpellingListIndex();
Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport
? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index e7171831f63..031edf1515b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4655,7 +4655,9 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
// Don't inherit dll attribute until the template is instantiated.
return;
- bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
+ // The class is either imported or exported.
+ const bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
+ const bool ClassImported = !ClassExported;
// Force declaration of implicit members so they can inherit the attribute.
S.ForceDeclarationOfImplicitMembers(Class);
@@ -4674,15 +4676,22 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
if (!VD && !MD)
continue;
- // Don't process deleted methods.
- if (MD && MD->isDeleted())
- continue;
+ if (MD) {
+ // Don't process deleted methods.
+ if (MD->isDeleted())
+ continue;
- if (MD && MD->isMoveAssignmentOperator() && !ClassExported &&
- MD->isInlined()) {
- // Current MSVC versions don't export the move assignment operators, so
- // don't attempt to import them if we have a definition.
- continue;
+ if (MD->isMoveAssignmentOperator() && ClassImported && MD->isInlined()) {
+ // Current MSVC versions don't export the move assignment operators, so
+ // don't attempt to import them if we have a definition.
+ continue;
+ }
+
+ if (MD->isInlined() && ClassImported &&
+ !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ // MinGW does not import inline functions.
+ continue;
+ }
}
if (!getDLLAttr(Member)) {
OpenPOWER on IntegriCloud