forked from OSchip/llvm-project
[ms][dll] #27212: Generating of implicit special members should take into account MSVC compatibility version
Clang creates implicit move constructor/assign operator in all cases if there is std=c++11. But MSVC supports such generation starting from version 1900 only. As result we have some binary incompatibility. Differential Revision: http://reviews.llvm.org/D19156 Patch by Andrew V. Tischenko llvm-svn: 269400
This commit is contained in:
parent
7e5e8684fb
commit
41581528a5
|
@ -4774,7 +4774,6 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
|
|||
|
||||
// The class is either imported or exported.
|
||||
const bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
|
||||
const bool ClassImported = !ClassExported;
|
||||
|
||||
TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind();
|
||||
|
||||
|
@ -4809,9 +4808,12 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
|
|||
if (!Context.getTargetInfo().getCXXABI().isMicrosoft())
|
||||
continue;
|
||||
|
||||
// MSVC versions before 2015 don't export the move assignment operators,
|
||||
// so don't attempt to import them if we have a definition.
|
||||
if (ClassImported && MD->isMoveAssignmentOperator() &&
|
||||
// MSVC versions before 2015 don't export the move assignment operators
|
||||
// and move constructor, so don't attempt to import/export them if
|
||||
// we have a definition.
|
||||
auto *CXXC = dyn_cast<CXXConstructorDecl>(MD);
|
||||
if ((MD->isMoveAssignmentOperator() ||
|
||||
(CXXC && CXXC->isMoveConstructor())) &&
|
||||
!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s
|
||||
// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 %s
|
||||
// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 %s
|
||||
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2015 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2013 %s
|
||||
|
||||
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s
|
||||
|
||||
|
@ -528,6 +532,8 @@ struct SomeTemplate {
|
|||
SomeTemplate(T o = T()) : o(o) {}
|
||||
T o;
|
||||
};
|
||||
// MSVC2015-DAG: define weak_odr dllexport {{.+}} @"\01??4?$SomeTemplate@H@@Q{{.+}}@$$Q{{.+}}@@Z"
|
||||
// MSVC2013-DAG: define weak_odr dllexport {{.+}} @"\01??4?$SomeTemplate@H@@Q{{.+}}0@A{{.+}}0@@Z"
|
||||
struct __declspec(dllexport) InheritFromTemplate : SomeTemplate<int> {};
|
||||
|
||||
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
|
||||
|
@ -616,7 +622,8 @@ struct __declspec(dllexport) X : public virtual W {};
|
|||
|
||||
struct __declspec(dllexport) Y {
|
||||
// Move assignment operator:
|
||||
// M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
|
||||
// MSVC2015-DAG: define weak_odr dllexport {{.+}} @"\01??4Y@@Q{{.+}}@$$Q{{.+}}@@Z"
|
||||
// MSVC2013-DAG: define weak_odr dllexport {{.+}} @"\01??4Y@@Q{{.+}}0@A{{.+}}0@@Z"
|
||||
|
||||
int x;
|
||||
};
|
||||
|
@ -947,3 +954,13 @@ struct __declspec(dllexport) LayerTreeImpl {
|
|||
};
|
||||
// M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.LayerTreeImpl::ElementLayers"* @"\01??0ElementLayers@LayerTreeImpl@@QAE@XZ"
|
||||
// M64-DAG: define weak_odr dllexport %"struct.LayerTreeImpl::ElementLayers"* @"\01??0ElementLayers@LayerTreeImpl@@QEAA@XZ"
|
||||
|
||||
class __declspec(dllexport) ACE_Shared_Object {
|
||||
public:
|
||||
virtual ~ACE_Shared_Object();
|
||||
};
|
||||
class __declspec(dllexport) ACE_Service_Object : public ACE_Shared_Object {};
|
||||
// Implicit move constructor declaration.
|
||||
// MSVC2015-DAG: define weak_odr dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
|
||||
// The declarations should not be exported.
|
||||
// MSVC2013-NOT: define weak_odr dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
|
||||
|
|
Loading…
Reference in New Issue