]> granicus.if.org Git - clang/commitdiff
ObjectiveC: fix a seg fault when deserialing redeclaration of ObjCMethodDecl.
authorManman Ren <manman.ren@gmail.com>
Mon, 3 Oct 2016 21:26:46 +0000 (21:26 +0000)
committerManman Ren <manman.ren@gmail.com>
Mon, 3 Oct 2016 21:26:46 +0000 (21:26 +0000)
The deserialization of redeclartion can cause seg fault since getCanonicalDecl
of the redeclaration returns the lookup result on the ObjCContainerDecl,
which can be null if FindExternalVisibleDeclsByName is not done updating
the lookup results.

The fix is to return the redeclaration itself as the canonical decl. Note that
the handling for redeclaration of ObjCMethodDecl is not in line with other
redeclarables.

rdar://28488466

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@283145 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/DeclObjC.cpp
test/Modules/Inputs/objc-method-redecl.h [new file with mode: 0644]
test/Modules/objc-method-redecl.m [new file with mode: 0644]

index 47e032a2e540dcd9d4b2d378b943d3892786876b..fdbac00fc9426aeaf042a77de61174f94cfcff12 100644 (file)
@@ -897,9 +897,13 @@ ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
         return MD;
   }
 
-  if (isRedeclaration())
-    return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
-                                                    isInstanceMethod());
+  if (isRedeclaration()) {
+    // It is possible that we have not done deserializing the ObjCMethod yet.
+    ObjCMethodDecl *MD =
+        cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
+                                                 isInstanceMethod());
+    return MD ? MD : this;
+  }
 
   return this;
 }
diff --git a/test/Modules/Inputs/objc-method-redecl.h b/test/Modules/Inputs/objc-method-redecl.h
new file mode 100644 (file)
index 0000000..95c6533
--- /dev/null
@@ -0,0 +1,4 @@
+@interface T
+- (void)test;
+- (void)test;
+@end
diff --git a/test/Modules/objc-method-redecl.m b/test/Modules/objc-method-redecl.m
new file mode 100644 (file)
index 0000000..f7acda5
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c-header -emit-pch %S/Inputs/objc-method-redecl.h -o %t.pch -Wno-objc-root-class
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c -include-pch %t.pch %s -verify -Wno-objc-root-class
+// expected-no-diagnostics
+
+@implementation T
+- (void)test {
+}
+@end