summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-08-02 07:51:41 +0000
committerHans Wennborg <hans@hanshq.net>2019-08-02 07:51:41 +0000
commit044d8c486bb4fd6d445e4333475e62045bf47888 (patch)
tree62b1993fbc718887b2aee5769c18647eb6bbab2a
parent14c6dfdfe2da38653797c7070d882e7546f1c067 (diff)
downloadbcm5719-llvm-044d8c486bb4fd6d445e4333475e62045bf47888.tar.gz
bcm5719-llvm-044d8c486bb4fd6d445e4333475e62045bf47888.zip
Don't try emitting dllexported explicitly defaulted non-trivial ctors twice during explicit template instantiation definition (PR42857)
Trying to emit the definition twice triggers an assert. Differential revision: https://reviews.llvm.org/D65579 llvm-svn: 367661
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp8
-rw-r--r--clang/test/CodeGenCXX/dllexport.cpp7
2 files changed, 14 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5f90790d7ff..accca46666b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11543,7 +11543,13 @@ void Sema::ActOnFinishCXXNonNestedClass(Decl *D) {
std::swap(DelayedDllExportMemberFunctions, WorkList);
for (CXXMethodDecl *M : WorkList) {
DefineImplicitSpecialMember(*this, M, M->getLocation());
- ActOnFinishInlineFunctionDef(M);
+
+ // Pass the method to the consumer to get emitted. This is not necessary
+ // for explicit instantiation definitions, as they will get emitted
+ // anyway.
+ if (M->getParent()->getTemplateSpecializationKind() !=
+ TSK_ExplicitInstantiationDefinition)
+ ActOnFinishInlineFunctionDef(M);
}
}
}
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp
index 5d4523f2ea6..59ba6d85488 100644
--- a/clang/test/CodeGenCXX/dllexport.cpp
+++ b/clang/test/CodeGenCXX/dllexport.cpp
@@ -860,6 +860,13 @@ struct PR40006 {
};
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::PR40006"* @"??0PR40006@InClassInits@@QAE@XZ"
+// PR42857: Clang would try to emit the non-trivial explicitly defaulted
+// dllexport ctor twice when doing an explicit instantiation definition.
+struct Qux { Qux(); };
+template <typename T> struct PR42857 { __declspec(dllexport) PR42857() = default; Qux q; };
+template struct PR42857<int>;
+// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.InClassInits::PR42857"* @"??0?$PR42857@H@InClassInits@@QAE@XZ"
+
}
// We had an issue where instantiating A would force emission of B's delayed
OpenPOWER on IntegriCloud