aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaExpr.cpp8
-rw-r--r--test/SemaCXX/nested-name-spec.cpp9
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}}
+ }
+}