diff options
author | John McCall <rjmccall@apple.com> | 2010-02-08 19:26:07 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-02-08 19:26:07 +0000 |
commit | 4c72d3ec68b88868a75b3e6bbe5520dcefe86a95 (patch) | |
tree | b8a2e46cae017f47e5e950ac907f64941487d071 | |
parent | e228ba97c9aff14dcf788773b8af455b9d85f210 (diff) |
Fix the crash-on-invalid from PR6259.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95554 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 8 | ||||
-rw-r--r-- | test/SemaCXX/nested-name-spec.cpp | 9 |
2 files changed, 16 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 4e448d8197..abb4e786d6 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -700,7 +700,13 @@ static void DecomposeTemplateName(LookupResult &R, const UnqualifiedId &Id) { R.resolveKind(); } +/// Determines whether the given record is "fully-formed" at the given +/// location, i.e. whether a qualified lookup into it is assured of +/// getting consistent results already. static bool IsFullyFormedScope(Sema &SemaRef, CXXRecordDecl *Record) { + if (!Record->hasDefinition()) + return false; + for (CXXRecordDecl::base_class_iterator I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) { CanQualType BaseT = SemaRef.Context.getCanonicalType((*I).getType()); @@ -708,7 +714,7 @@ static bool IsFullyFormedScope(Sema &SemaRef, CXXRecordDecl *Record) { if (!BaseRT) return false; CXXRecordDecl *BaseRecord = cast<CXXRecordDecl>(BaseRT->getDecl()); - if (!BaseRecord->isDefinition() || + if (!BaseRecord->hasDefinition() || !IsFullyFormedScope(SemaRef, BaseRecord)) return false; } diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index dbbf1fecc9..8a217b3120 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -220,3 +220,12 @@ namespace test2 { int *ns::count_ptr = &count; } + +// PR6259, invalid case +namespace test3 { + // FIXME: this should really only trigger once + class A; // expected-note 2 {{forward declaration}} + void foo(const char *path) { + A::execute(path); // expected-error 2 {{incomplete type 'class test3::A' named in nested name specifier}} + } +} |