aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-09 21:23:21 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-09 21:23:21 +0000
commitfdc82ccb3f2b23a89e7002fe8238e1422b00f96a (patch)
treef189aa0a3010e0eb212970b8eadf0a8b098985ea /lib/Sema/SemaDeclCXX.cpp
parent6694ed095d6b27a2c92ec4fd63664fcd88a05749 (diff)
downloadsrc-fdc82ccb3f2b23a89e7002fe8238e1422b00f96a.tar.gz
src-fdc82ccb3f2b23a89e7002fe8238e1422b00f96a.zip
Notes
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp52
1 files changed, 47 insertions, 5 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index a650621b573a..a70e16cce18c 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)
@@ -9135,6 +9153,16 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
// invalid).
if (R.empty() &&
NameInfo.getName().getNameKind() != DeclarationName::CXXConstructorName) {
+ // HACK: Work around a bug in libstdc++'s detection of ::gets. Sometimes
+ // it will believe that glibc provides a ::gets in cases where it does not,
+ // and will try to pull it into namespace std with a using-declaration.
+ // Just ignore the using-declaration in that case.
+ auto *II = NameInfo.getName().getAsIdentifierInfo();
+ if (getLangOpts().CPlusPlus14 && II && II->isStr("gets") &&
+ CurContext->isStdNamespace() &&
+ isa<TranslationUnitDecl>(LookupContext) &&
+ getSourceManager().isInSystemHeader(UsingLoc))
+ return nullptr;
if (TypoCorrection Corrected = CorrectTypo(
R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
llvm::make_unique<UsingValidatorCCC>(
@@ -9828,9 +9856,14 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
}
// Field constructors.
- for (const auto *F : ClassDecl->fields()) {
+ for (auto *F : ClassDecl->fields()) {
if (F->hasInClassInitializer()) {
- if (Expr *E = F->getInClassInitializer())
+ Expr *E = F->getInClassInitializer();
+ if (!E)
+ // FIXME: It's a little wasteful to build and throw away a
+ // CXXDefaultInitExpr here.
+ E = BuildCXXDefaultInitExpr(Loc, F).get();
+ if (E)
ExceptSpec.CalledExpr(E);
} else if (const RecordType *RecordTy
= Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
@@ -12291,6 +12324,10 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
if (Field->getInClassInitializer())
return CXXDefaultInitExpr::Create(Context, Loc, Field);
+ // If we might have already tried and failed to instantiate, don't try again.
+ if (Field->isInvalidDecl())
+ return ExprError();
+
// Maybe we haven't instantiated the in-class initializer. Go check the
// pattern FieldDecl to see if it has one.
CXXRecordDecl *ParentRD = cast<CXXRecordDecl>(Field->getParent());
@@ -12320,8 +12357,11 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
}
if (InstantiateInClassInitializer(Loc, Field, Pattern,
- getTemplateInstantiationArgs(Field)))
+ getTemplateInstantiationArgs(Field))) {
+ // Don't diagnose this again.
+ Field->setInvalidDecl();
return ExprError();
+ }
return CXXDefaultInitExpr::Create(Context, Loc, Field);
}
@@ -12344,6 +12384,8 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
<< OutermostClass << Field;
Diag(Field->getLocEnd(), diag::note_in_class_initializer_not_yet_parsed);
+ // Don't diagnose this again.
+ Field->setInvalidDecl();
return ExprError();
}