forked from OSchip/llvm-project
[dllexport] Avoid assert for explicitly defaulted methods in explicit instantiation definitions (PR47683)
Clang was asserting due to attempting to codegen such methods twice. Differential revision: https://reviews.llvm.org/D90849
This commit is contained in:
parent
f9265de8c6
commit
b9d36540a8
clang
|
@ -5895,13 +5895,22 @@ static void ReferenceDllExportedMembers(Sema &S, CXXRecordDecl *Class) {
|
|||
|
||||
// The function will be passed to the consumer when its definition is
|
||||
// encountered.
|
||||
} else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() ||
|
||||
} else if (MD->isExplicitlyDefaulted()) {
|
||||
// Synthesize and instantiate explicitly defaulted methods.
|
||||
S.MarkFunctionReferenced(Class->getLocation(), MD);
|
||||
|
||||
if (TSK != TSK_ExplicitInstantiationDefinition) {
|
||||
// Except for explicit instantiation defs, we will not see the
|
||||
// definition again later, so pass it to the consumer now.
|
||||
S.Consumer.HandleTopLevelDecl(DeclGroupRef(MD));
|
||||
}
|
||||
} else if (!MD->isTrivial() ||
|
||||
MD->isCopyAssignmentOperator() ||
|
||||
MD->isMoveAssignmentOperator()) {
|
||||
// Synthesize and instantiate non-trivial implicit methods, explicitly
|
||||
// defaulted methods, and the copy and move assignment operators. The
|
||||
// latter are exported even if they are trivial, because the address of
|
||||
// an operator can be taken and should compare equal across libraries.
|
||||
// Synthesize and instantiate non-trivial implicit methods, and the copy
|
||||
// and move assignment operators. The latter are exported even if they
|
||||
// are trivial, because the address of an operator can be taken and
|
||||
// should compare equal across libraries.
|
||||
S.MarkFunctionReferenced(Class->getLocation(), MD);
|
||||
|
||||
// There is no later point when we will see the definition of this
|
||||
|
|
|
@ -915,6 +915,36 @@ template<> template<> void ExportedClassTemplate2<int>::baz<int>() {}
|
|||
// M32-DAG: define dso_local x86_thiscallcc void @"??$baz@H@?$ExportedClassTemplate2@H@pr34849@@QAEXXZ"
|
||||
}
|
||||
|
||||
namespace pr47683 {
|
||||
struct X { X() {} };
|
||||
|
||||
template <typename> struct S {
|
||||
S() = default;
|
||||
X x;
|
||||
};
|
||||
template struct __declspec(dllexport) S<int>;
|
||||
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.pr47683::S"* @"??0?$S@H@pr47683@@QAE@XZ"
|
||||
|
||||
template <typename> struct T {
|
||||
T() = default;
|
||||
X x;
|
||||
};
|
||||
extern template struct T<int>;
|
||||
template struct __declspec(dllexport) T<int>;
|
||||
// Don't assert about multiple codegen for explicitly defaulted method in explicit instantiation def.
|
||||
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.pr47683::T"* @"??0?$T@H@pr47683@@QAE@XZ"
|
||||
|
||||
template <typename> struct U {
|
||||
U();
|
||||
X x;
|
||||
};
|
||||
template <typename T> U<T>::U() = default;
|
||||
extern template struct U<int>;
|
||||
template struct __declspec(dllexport) U<int>;
|
||||
// Same as T, but with out-of-line ctor.
|
||||
// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc %"struct.pr47683::U"* @"??0?$U@H@pr47683@@QAE@XZ"
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Classes with template base classes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue