diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4e448d81976c..abb4e786d6c4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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(BaseRT->getDecl()); - if (!BaseRecord->isDefinition() || + if (!BaseRecord->hasDefinition() || !IsFullyFormedScope(SemaRef, BaseRecord)) return false; } diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp index dbbf1fecc9f3..8a217b312088 100644 --- a/clang/test/SemaCXX/nested-name-spec.cpp +++ b/clang/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}} + } +}