]> granicus.if.org Git - clang/commitdiff
Fix PR9572 and neighboring lurking crashers.
authorMatt Beaumont-Gay <matthewbg@google.com>
Mon, 28 Mar 2011 01:39:13 +0000 (01:39 +0000)
committerMatt Beaumont-Gay <matthewbg@google.com>
Mon, 28 Mar 2011 01:39:13 +0000 (01:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128401 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/PR9572.cpp [new file with mode: 0644]

index ee7e447641c2d2e84e52fff8010143ecfb372baf..7ae104a5423cb86acebbf198cc6a04766fa450e2 100644 (file)
@@ -2459,10 +2459,13 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
       continue;
     
     CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    if (FieldClassDecl->isInvalidDecl())
+      continue;
     if (FieldClassDecl->hasTrivialDestructor())
       continue;
 
     CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
+    assert(Dtor && "No dtor found for FieldClassDecl!");
     CheckDestructorAccess(Field->getLocation(), Dtor,
                           PDiag(diag::err_access_dtor_field)
                             << Field->getDeclName()
@@ -2483,12 +2486,16 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
     if (Base->isVirtual())
       DirectVirtualBases.insert(RT);
 
-    // Ignore trivial destructors.
     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    // If our base class is invalid, we probably can't get its dtor anyway.
+    if (BaseClassDecl->isInvalidDecl())
+      continue;
+    // Ignore trivial destructors.
     if (BaseClassDecl->hasTrivialDestructor())
       continue;
 
     CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
+    assert(Dtor && "No dtor found for BaseClassDecl!");
 
     // FIXME: caret should be on the start of the class name
     CheckDestructorAccess(Base->getSourceRange().getBegin(), Dtor,
@@ -2510,12 +2517,16 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
     if (DirectVirtualBases.count(RT))
       continue;
 
-    // Ignore trivial destructors.
     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    // If our base class is invalid, we probably can't get its dtor anyway.
+    if (BaseClassDecl->isInvalidDecl())
+      continue;
+    // Ignore trivial destructors.
     if (BaseClassDecl->hasTrivialDestructor())
       continue;
 
     CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
+    assert(Dtor && "No dtor found for BaseClassDecl!");
     CheckDestructorAccess(ClassDecl->getLocation(), Dtor,
                           PDiag(diag::err_access_dtor_vbase)
                             << VBase->getType());
diff --git a/test/SemaCXX/PR9572.cpp b/test/SemaCXX/PR9572.cpp
new file mode 100644 (file)
index 0000000..d1b7077
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class Base {
+  virtual ~Base();
+};
+struct Foo : public Base {
+  const int kBlah = 3; // expected-error{{fields can only be initialized in constructors}}
+  Foo();
+};
+struct Bar : public Foo {
+  Bar() { }
+};
+struct Baz {
+  Foo f;
+  Baz() { }
+};