diff options
author | Matt Beaumont-Gay <matthewbg@google.com> | 2011-03-28 01:39:13 +0000 |
---|---|---|
committer | Matt Beaumont-Gay <matthewbg@google.com> | 2011-03-28 01:39:13 +0000 |
commit | 3334b0b13ad3bf568a16cda29434b18d084f6dcb (patch) | |
tree | 3ed0aceb7bee768fe65e3898e4f4e630c624dc09 | |
parent | 1d71cbf21ad8882192d0d88a76f0243b7cf490c9 (diff) |
Fix PR9572 and neighboring lurking crashers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128401 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 15 | ||||
-rw-r--r-- | test/SemaCXX/PR9572.cpp | 15 |
2 files changed, 28 insertions, 2 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index ee7e447641..7ae104a542 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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 index 0000000000..d1b70778d0 --- /dev/null +++ b/test/SemaCXX/PR9572.cpp @@ -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() { } +}; |