Skip to content

Commit

Permalink
[MS] Mark default args of exported default constructors as used
Browse files Browse the repository at this point in the history
Fixes a regression introduced in r291045, which would lead to link
errors. While we should no longer encounter unparsed or uninstantiated
default arguments in this codepath, we still need to call
CheckCXXDefaultArgExpr to mark the default argument expressions as
ODR-used.

llvm-svn: 291453
  • Loading branch information
rnk committed Jan 9, 2017
1 parent 6615ea8 commit 82713bf
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
22 changes: 20 additions & 2 deletions clang/lib/Sema/SemaDeclCXX.cpp
Expand Up @@ -5395,14 +5395,32 @@ static void ReferenceDllExportedMethods(Sema &S, CXXRecordDecl *Class) {
}
}

static void checkForMultipleExportedDefaultConstructors(Sema &S, CXXRecordDecl *Class) {
static void checkForMultipleExportedDefaultConstructors(Sema &S,
CXXRecordDecl *Class) {
// Only the MS ABI has default constructor closures, so we don't need to do
// this semantic checking anywhere else.
if (!S.Context.getTargetInfo().getCXXABI().isMicrosoft())
return;

CXXConstructorDecl *LastExportedDefaultCtor = nullptr;
for (Decl *Member : Class->decls()) {
// Look for exported default constructors.
auto *CD = dyn_cast<CXXConstructorDecl>(Member);
if (!CD || !CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>())
if (!CD || !CD->isDefaultConstructor())
continue;
auto *Attr = CD->getAttr<DLLExportAttr>();
if (!Attr)
continue;

// If the class is non-dependent, mark the default arguments as ODR-used so
// that we can properly codegen the constructor closure.
if (!Class->isDependentContext()) {
for (ParmVarDecl *PD : CD->parameters()) {
(void)S.CheckCXXDefaultArgExpr(Attr->getLocation(), CD, PD);
S.DiscardCleanupsInEvaluationContext();
}
}

if (LastExportedDefaultCtor) {
S.Diag(LastExportedDefaultCtor->getLocation(),
diag::err_attribute_dll_ambiguous_default_ctor)
Expand Down
19 changes: 19 additions & 0 deletions clang/test/CodeGenCXX/dllexport-ctor-closure.cpp
Expand Up @@ -61,3 +61,22 @@ struct __declspec(dllexport) NestedOuter {

// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat

struct HasDtor {
~HasDtor();
int o;
};
struct HasImplicitDtor1 { HasDtor o; };
struct HasImplicitDtor2 { HasDtor o; };
struct __declspec(dllexport) CtorClosureInline {
CtorClosureInline(const HasImplicitDtor1 &v = {}) {}
};
struct __declspec(dllexport) CtorClosureOutOfLine {
CtorClosureOutOfLine(const HasImplicitDtor2 &v = {});
};
CtorClosureOutOfLine::CtorClosureOutOfLine(const HasImplicitDtor2 &v) {}

// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorClosureInline@@QAEXXZ"
// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??1HasImplicitDtor1@@QAE@XZ"
// CHECK-LABEL: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorClosureOutOfLine@@QAEXXZ"
// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??1HasImplicitDtor2@@QAE@XZ"

0 comments on commit 82713bf

Please sign in to comment.