aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-11-09 19:20:36 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-11-09 19:20:36 +0000
commit80c30dad6c6fca077293125a96f464b6c8857171 (patch)
tree27678863327e4c0547b2c3351480043c7c5178f9
parent0f8716b7bb25d61a82f699b3975167451f7b5a68 (diff)
Add additional note to mark the cause of synthesized constructors. Mark
declaration invalid if the constructor can't be properly built. Addresses remaining review comments from Fariborz for r86500. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86579 91177308-0d34-0410-b5e6-96231b3b80d8
-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}}
}