aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-06-23 23:16:19 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-06-23 23:16:19 +0000
commita81397323cc8475ef8243f938118a9c231fb18ff (patch)
tree0e9a4f473d1baef164dcc3e31763568112835cb8
parent89b29d14bc718750d88f0846d4410910134020dd (diff)
When forming a cycle in objc's inheritance hierarchy,
diagnose it properly and don't throw clang into an infinit loop. // rdar://9653341 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133773 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDeclObjC.cpp7
-rw-r--r--test/SemaObjC/class-proto-1.m4
-rw-r--r--test/SemaObjC/forward-class-1.m15
-rw-r--r--test/SemaObjC/undef-superclass-1.m6
5 files changed, 25 insertions, 9 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c734c064e7..84aac0c14f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -330,6 +330,8 @@ def err_duplicate_class_def : Error<
"duplicate interface definition for class %0">;
def err_undef_superclass : Error<
"cannot find interface declaration for %0, superclass of %1">;
+def err_forward_superclass : Error<
+ "attempting to use the forward class %0 as superclass of %1">;
def err_no_nsconstant_string_class : Error<
"cannot find interface declaration for %0">;
def err_recursive_superclass : Error<
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index b54e2425b2..3bbe421cd1 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -491,10 +491,13 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
if (!SuperClassDecl)
Diag(SuperLoc, diag::err_undef_superclass)
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
- else if (SuperClassDecl->isForwardDecl())
- Diag(SuperLoc, diag::err_undef_superclass)
+ else if (SuperClassDecl->isForwardDecl()) {
+ Diag(SuperLoc, diag::err_forward_superclass)
<< SuperClassDecl->getDeclName() << ClassName
<< SourceRange(AtInterfaceLoc, ClassLoc);
+ Diag(SuperClassDecl->getLocation(), diag::note_forward_class);
+ SuperClassDecl = 0;
+ }
}
IDecl->setSuperClass(SuperClassDecl);
IDecl->setSuperClassLoc(SuperLoc);
diff --git a/test/SemaObjC/class-proto-1.m b/test/SemaObjC/class-proto-1.m
index 246b5002f6..8030976433 100644
--- a/test/SemaObjC/class-proto-1.m
+++ b/test/SemaObjC/class-proto-1.m
@@ -23,9 +23,9 @@
@interface E2 <p1,p2,p3> @end // expected-warning {{cannot find protocol definition for 'p3'}}
-@class U1, U2;
+@class U1, U2; // expected-note {{forward class is declared here}}
-@interface E3 : U1 @end // expected-error {{cannot find interface declaration for 'U1', superclass of 'E3'}}
+@interface E3 : U1 @end // expected-error {{attempting to use the forward class 'U1' as superclass of 'E3'}}
@interface I3 : E3 @end
diff --git a/test/SemaObjC/forward-class-1.m b/test/SemaObjC/forward-class-1.m
index ab213fb4ce..de94e884ae 100644
--- a/test/SemaObjC/forward-class-1.m
+++ b/test/SemaObjC/forward-class-1.m
@@ -1,9 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-@class FOO, BAR;
+@class FOO, BAR; // expected-note {{forward class is declared here}}
@class FOO, BAR;
-@interface INTF : FOO // expected-error {{cannot find interface declaration for 'FOO', superclass of 'INTF'}}
+@interface INTF : FOO // expected-error {{attempting to use the forward class 'FOO' as superclass of 'INTF'}}
@end
@interface FOO
@@ -45,3 +45,14 @@ typedef NSObject <XCElementP> XCElement;
@end
+// rdar://9653341
+@class B; // expected-note {{forward class is declared here}}
+@interface A : B {} // expected-error {{attempting to use the forward class 'B' as superclass of 'A'}}
+@end
+
+@interface B : A {}
+@end
+
+@implementation A @end
+@implementation B @end
+
diff --git a/test/SemaObjC/undef-superclass-1.m b/test/SemaObjC/undef-superclass-1.m
index c941f82e43..41cf1439bd 100644
--- a/test/SemaObjC/undef-superclass-1.m
+++ b/test/SemaObjC/undef-superclass-1.m
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-@class SUPER, Y;
+@class SUPER, Y; // expected-note 2 {{forward class is declared here}}
-@interface INTF :SUPER // expected-error {{cannot find interface declaration for 'SUPER', superclass of 'INTF'}}
+@interface INTF :SUPER // expected-error {{attempting to use the forward class 'SUPER' as superclass of 'INTF'}}
@end
@interface SUPER @end
@@ -13,7 +13,7 @@
@interface INTF2 : INTF1
@end
-@interface INTF3 : Y // expected-error {{cannot find interface declaration for 'Y', superclass of 'INTF3'}} \
+@interface INTF3 : Y // expected-error {{attempting to use the forward class 'Y' as superclass of 'INTF3'}} \
// expected-note{{'INTF3' declared here}}
@end