summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-12-31 05:36:46 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-12-31 05:36:46 +0000
commit474b323a0387d4c59055300c56951d1aa2591d80 (patch)
tree691645d15b55b78aaa59a9744d92bc9de3812994 /clang/lib/Sema/SemaDeclCXX.cpp
parentbc22e26e389ef7f43e47d292c5132974bfdbedb2 (diff)
downloadbcm5719-llvm-474b323a0387d4c59055300c56951d1aa2591d80.tar.gz
bcm5719-llvm-474b323a0387d4c59055300c56951d1aa2591d80.zip
[MSVC Compat] Diagnose multiple default ctors for dllexport'd classes
The MS ABI emits a special default constructor closure thunk if a default constructor has a weird calling convention or default arguments. The MS ABI has a quirk: there can be only one such thunk because the mangling scheme does not have room for distinct manglings. We must raise a diagnostic in this eventuality. N.B. MSVC sorta gets this right. Multiple default constructors result in the default constructor closure getting emitted but they seem to get confused by which default constructors are reasonable to reference from the closure. We try to be a little more careful which results in mild differences in behavior. llvm-svn: 256661
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3f6c6b00d90..02091a7bd53 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9470,6 +9470,10 @@ static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) {
if (Class->getDescribedClassTemplate())
return;
+ CallingConv ExpectedCallingConv = S.Context.getDefaultCallingConvention(
+ /*IsVariadic=*/false, /*IsCXXMethod=*/true);
+
+ CXXConstructorDecl *LastExportedDefaultCtor = nullptr;
for (Decl *Member : Class->decls()) {
auto *CD = dyn_cast<CXXConstructorDecl>(Member);
if (!CD) {
@@ -9481,7 +9485,25 @@ static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) {
continue;
}
- for (unsigned I = 0, E = CD->getNumParams(); I != E; ++I) {
+ CallingConv ActualCallingConv =
+ CD->getType()->getAs<FunctionProtoType>()->getCallConv();
+
+ // Skip default constructors with typical calling conventions and no default
+ // arguments.
+ unsigned NumParams = CD->getNumParams();
+ if (ExpectedCallingConv == ActualCallingConv && NumParams == 0)
+ continue;
+
+ if (LastExportedDefaultCtor) {
+ S.Diag(LastExportedDefaultCtor->getLocation(),
+ diag::err_attribute_dll_ambiguous_default_ctor) << Class;
+ S.Diag(CD->getLocation(), diag::note_entity_declared_at)
+ << CD->getDeclName();
+ return;
+ }
+ LastExportedDefaultCtor = CD;
+
+ for (unsigned I = 0; I != NumParams; ++I) {
// Skip any default arguments that we've already instantiated.
if (S.Context.getDefaultArgExprForConstructor(CD, I))
continue;
OpenPOWER on IntegriCloud