aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDeclCXX.cpp23
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp2
-rw-r--r--test/SemaCXX/default-constructor-initializers.cpp6
-rw-r--r--test/SemaCXX/value-initialization.cpp2
5 files changed, 27 insertions, 8 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index a87bb91122..b78c3994da 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -433,6 +433,8 @@ def err_implicit_object_parameter_init : Error<
def note_field_decl : Note<"member is declared here">;
def note_previous_class_decl : Note<
"%0 declared here">;
+def note_ctor_synthesized_at : Note<
+ "implicit default constructor for %0 first required here">;
def err_missing_default_ctor : Error<
"%select{|implicit default }0constructor for %1 must explicitly initialize "
"the %select{base class|member}2 %3 which does not have a default "
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 41f8aec815..dd1af0b64c 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1186,7 +1186,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
NumArgs, C, IdLoc, RParenLoc);
}
-void
+bool
Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
CXXBaseOrMemberInitializer **Initializers,
unsigned NumInitializers,
@@ -1197,6 +1197,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*> AllBaseFields;
bool HasDependentBaseInit = false;
+ bool HadError = false;
for (unsigned i = 0; i < NumInitializers; i++) {
CXXBaseOrMemberInitializer *Member = Initializers[i];
@@ -1258,6 +1259,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< 0 << VBase->getType();
Diag(VBaseDecl->getLocation(), diag::note_previous_class_decl)
<< Context.getTagDeclType(VBaseDecl);
+ HadError = true;
continue;
}
@@ -1307,6 +1309,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< 0 << Base->getType();
Diag(BaseDecl->getLocation(), diag::note_previous_class_decl)
<< Context.getTagDeclType(BaseDecl);
+ HadError = true;
continue;
}
@@ -1378,6 +1381,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
Diag(Field->getLocation(), diag::note_field_decl);
Diag(RT->getDecl()->getLocation(), diag::note_previous_class_decl)
<< Context.getTagDeclType(RT->getDecl());
+ HadError = true;
continue;
}
@@ -1399,6 +1403,7 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
<< 1 << (*Field)->getDeclName();
Diag((*Field)->getLocation(), diag::note_declared_at);
+ HadError = true;
}
}
else if (FT->isReferenceType()) {
@@ -1406,12 +1411,14 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
<< (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
<< 0 << (*Field)->getDeclName();
Diag((*Field)->getLocation(), diag::note_declared_at);
+ HadError = true;
}
else if (FT.isConstQualified()) {
Diag(Constructor->getLocation(), diag::err_unintialized_member_in_ctor)
<< (int)IsImplicitConstructor << Context.getTagDeclType(ClassDecl)
<< 1 << (*Field)->getDeclName();
Diag((*Field)->getLocation(), diag::note_declared_at);
+ HadError = true;
}
}
@@ -1425,6 +1432,8 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
for (unsigned Idx = 0; Idx < NumInitializers; ++Idx)
baseOrMemberInitializers[Idx] = AllToInit[Idx];
}
+
+ return HadError;
}
static void *GetKeyForTopLevelField(FieldDecl *Field) {
@@ -2957,9 +2966,17 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
!Constructor->isUsed()) &&
"DefineImplicitDefaultConstructor - call it for implicit default ctor");
- SetBaseOrMemberInitializers(Constructor, 0, 0, true);
+ CXXRecordDecl *ClassDecl
+ = cast<CXXRecordDecl>(Constructor->getDeclContext());
+ assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor");
- Constructor->setUsed();
+ if (SetBaseOrMemberInitializers(Constructor, 0, 0, true)) {
+ Diag(CurrentLocation, diag::note_ctor_synthesized_at)
+ << Context.getTagDeclType(ClassDecl);
+ Constructor->setInvalidDecl();
+ } else {
+ Constructor->setUsed();
+ }
return;
}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
index 0b83a1fee0..ad0d506213 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
@@ -26,7 +26,7 @@ IntHolder &test_X_IntHolderInt(X<IntHolder, int> xih) {
xih.g(); // okay
xih.f(); // expected-note{{instantiation}}
- X<IntHolder, int>::Inner inner;
+ X<IntHolder, int>::Inner inner; // expected-note {{first required here}}
return X<IntHolder, int>::value; // expected-note{{instantiation}}
}
diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp
index 48c9039863..6adcdca3e1 100644
--- a/test/SemaCXX/default-constructor-initializers.cpp
+++ b/test/SemaCXX/default-constructor-initializers.cpp
@@ -11,7 +11,7 @@ struct X2 : X1 { // expected-note {{'struct X2' declared here}} \
struct X3 : public X2 { // expected-error {{must explicitly initialize the base class 'struct X2'}}
};
-X3 x3;
+X3 x3; // expected-note {{first required here}}
struct X4 { // expected-error {{must explicitly initialize the member 'x2'}} \
@@ -20,7 +20,7 @@ struct X4 { // expected-error {{must explicitly initialize the member 'x2'}} \
X2 & rx2; // expected-note {{declared at}}
};
-X4 x4;
+X4 x4; // expected-note {{first required here}}
struct Y1 { // has no implicit default constructor
@@ -52,5 +52,5 @@ struct Z1 { // expected-error {{must explicitly initialize the reference member
volatile int v1;
};
-Z1 z1;
+Z1 z1; // expected-note {{first required here}}
diff --git a/test/SemaCXX/value-initialization.cpp b/test/SemaCXX/value-initialization.cpp
index 3452883697..25d708494b 100644
--- a/test/SemaCXX/value-initialization.cpp
+++ b/test/SemaCXX/value-initialization.cpp
@@ -6,5 +6,5 @@ struct A { // expected-error {{implicit default constructor for 'struct A' must
};
int main () {
- (void)A();
+ (void)A(); // expected-note {{first required here}}
}