diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2009-11-09 19:20:36 +0000 | 
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2009-11-09 19:20:36 +0000 | 
| commit | 9cf6b59400ea7f29d650baad7e082e38ff3c8bb2 (patch) | |
| tree | e2cec96e5f6f1c2ad60914bb531135cb317325c5 | |
| parent | 36d7c5f29b32d989640b33b800d763e9a11eda1e (diff) | |
| download | bcm5719-llvm-9cf6b59400ea7f29d650baad7e082e38ff3c8bb2.tar.gz bcm5719-llvm-9cf6b59400ea7f29d650baad7e082e38ff3c8bb2.zip  | |
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.
llvm-svn: 86579
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 23 | ||||
| -rw-r--r-- | clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp | 2 | ||||
| -rw-r--r-- | clang/test/SemaCXX/default-constructor-initializers.cpp | 6 | ||||
| -rw-r--r-- | clang/test/SemaCXX/value-initialization.cpp | 2 | 
5 files changed, 27 insertions, 8 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a87bb911224..b78c3994da7 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 41f8aec815b..dd1af0b64c6 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp index 0b83a1fee0f..ad0d5062136 100644 --- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp +++ b/clang/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/clang/test/SemaCXX/default-constructor-initializers.cpp b/clang/test/SemaCXX/default-constructor-initializers.cpp index 48c90398635..6adcdca3e17 100644 --- a/clang/test/SemaCXX/default-constructor-initializers.cpp +++ b/clang/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/clang/test/SemaCXX/value-initialization.cpp b/clang/test/SemaCXX/value-initialization.cpp index 3452883697a..25d708494b1 100644 --- a/clang/test/SemaCXX/value-initialization.cpp +++ b/clang/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}}  }  | 

