diff options
author | Reid Kleckner <rnk@google.com> | 2017-01-09 17:27:17 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2017-01-09 17:27:17 +0000 |
commit | 0982ba044f48b8d0658cdd7ceeacee0b7a614a88 (patch) | |
tree | 1a672af24d4943829e76f3e3eb67dd51b45c39a0 /lib/Sema/SemaDeclCXX.cpp | |
parent | f912c0c031592a6b92b02e86a6b9eee4842b316f (diff) |
[MS] Mark default args of exported default constructors as used
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291453 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 02b73e9113..a70e16cce1 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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) |