summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-06-18 21:26:33 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-06-18 21:26:33 +0000
commitdd7106375c2c7de682bf2997d2ef7bb55113219f (patch)
tree6f0e0d1fceb071c8d76abf57a693734f45be2d5c
parenta721731fdd0ab07d66e1f143181c6d8de66b3188 (diff)
downloadbcm5719-llvm-dd7106375c2c7de682bf2997d2ef7bb55113219f.tar.gz
bcm5719-llvm-dd7106375c2c7de682bf2997d2ef7bb55113219f.zip
When declaring an ObjC interface decl with a @compatibility_alias alias name, change the class name to the "real" one.
If we have something like @class NewImage; @compatibility_alias OldImage NewImage; @class OldImage; the lookup for 'OldImage' will return the 'NewImage' decl ("@class NewImage"). In such a case, when creating the decl for "@class OldImage" use the real declaration name ("NewImage"), instead of the alias one ("OldImage"), otherwise we will break IdentifierResolver and redecls-chain invariants. Fixes crash of rdar://14112291. llvm-svn: 184238
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp37
-rw-r--r--clang/test/PCH/objc_import.h11
-rw-r--r--clang/test/PCH/objc_import.m15
3 files changed, 62 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 9f10b7bb7ea..526e479af08 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -459,6 +459,23 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
// Create a declaration to describe this @interface.
ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+
+ if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
+ // A previous decl with a different name is because of
+ // @compatibility_alias, for example:
+ // \code
+ // @class NewImage;
+ // @compatibility_alias OldImage NewImage;
+ // \endcode
+ // A lookup for 'OldImage' will return the 'NewImage' decl.
+ //
+ // In such a case use the real declaration name, instead of the alias one,
+ // otherwise we will break IdentifierResolver and redecls-chain invariants.
+ // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
+ // has been aliased.
+ ClassName = PrevIDecl->getIdentifier();
+ }
+
ObjCInterfaceDecl *IDecl
= ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
PrevIDecl, ClassLoc);
@@ -1938,9 +1955,27 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
// Create a declaration to describe this forward declaration.
ObjCInterfaceDecl *PrevIDecl
= dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+
+ IdentifierInfo *ClassName = IdentList[i];
+ if (PrevIDecl && PrevIDecl->getIdentifier() != ClassName) {
+ // A previous decl with a different name is because of
+ // @compatibility_alias, for example:
+ // \code
+ // @class NewImage;
+ // @compatibility_alias OldImage NewImage;
+ // \endcode
+ // A lookup for 'OldImage' will return the 'NewImage' decl.
+ //
+ // In such a case use the real declaration name, instead of the alias one,
+ // otherwise we will break IdentifierResolver and redecls-chain invariants.
+ // FIXME: If necessary, add a bit to indicate that this ObjCInterfaceDecl
+ // has been aliased.
+ ClassName = PrevIDecl->getIdentifier();
+ }
+
ObjCInterfaceDecl *IDecl
= ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
- IdentList[i], PrevIDecl, IdentLocs[i]);
+ ClassName, PrevIDecl, IdentLocs[i]);
IDecl->setAtEndRange(IdentLocs[i]);
PushOnScopeChains(IDecl, TUScope);
diff --git a/clang/test/PCH/objc_import.h b/clang/test/PCH/objc_import.h
index 8af87ab25c7..4646e16a2cd 100644
--- a/clang/test/PCH/objc_import.h
+++ b/clang/test/PCH/objc_import.h
@@ -5,3 +5,14 @@
- (void)instMethod;
@end
+@class NewID1;
+@compatibility_alias OldID1 NewID1;
+@class OldID1;
+@class OldID1;
+
+@class NewID2;
+@compatibility_alias OldID2 NewID2;
+@class OldID2;
+@interface OldID2
+-(void)meth;
+@end
diff --git a/clang/test/PCH/objc_import.m b/clang/test/PCH/objc_import.m
index c7dd805b3e4..724c8221848 100644
--- a/clang/test/PCH/objc_import.m
+++ b/clang/test/PCH/objc_import.m
@@ -15,3 +15,18 @@ void func() {
xx = [TestPCH alloc];
[xx instMethod];
}
+
+// rdar://14112291
+@class NewID1;
+void foo1(NewID1 *p);
+void bar1(OldID1 *p) {
+ foo1(p);
+}
+@class NewID2;
+void foo2(NewID2 *p) {
+ [p meth];
+}
+void bar2(OldID2 *p) {
+ foo2(p);
+ [p meth];
+}
OpenPOWER on IntegriCloud