diff options
author | Devin Coughlin <dcoughlin@apple.com> | 2016-04-01 03:24:13 +0000 |
---|---|---|
committer | Devin Coughlin <dcoughlin@apple.com> | 2016-04-01 03:24:13 +0000 |
commit | c239dd13493c94c03156e5da100ee2256ee829e1 (patch) | |
tree | 23a11aa8440e95cf8fd0c8cddd9739720e9ad977 /clang/lib/StaticAnalyzer/Core/CallEvent.cpp | |
parent | 85fb9e058ed74ad9b4fe919056d1d6874f398b39 (diff) | |
download | bcm5719-llvm-c239dd13493c94c03156e5da100ee2256ee829e1.tar.gz bcm5719-llvm-c239dd13493c94c03156e5da100ee2256ee829e1.zip |
[analyzer] Prefer accessor method in extension over category in CallEvent.
In ObjCMethodCall:getRuntimeDefinition(), if the method is an accessor in a
category, and it doesn't have a self declaration, first try to find the method
in a class extension. This works around a bug in Sema where multiple accessors
are synthesized for properties in class extensions that are redeclared in a
category. The implicit parameters are not filled in for the method on the
category, which causes a crash when trying to synthesize a getter for the
property in BodyFarm. The Sema bug is tracked as rdar://problem/25481164.
rdar://problem/25056531
llvm-svn: 265103
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CallEvent.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index 2c7b5302dd6..626775846bb 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -958,8 +958,30 @@ RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const { // even if we don't actually have an implementation. if (!*Val) if (const ObjCMethodDecl *CompileTimeMD = E->getMethodDecl()) - if (CompileTimeMD->isPropertyAccessor()) - Val = IDecl->lookupInstanceMethod(Sel); + if (CompileTimeMD->isPropertyAccessor()) { + if (!CompileTimeMD->getSelfDecl() && + isa<ObjCCategoryDecl>(CompileTimeMD->getDeclContext())) { + // If the method is an accessor in a category, and it doesn't + // have a self declaration, first + // try to find the method in a class extension. This + // works around a bug in Sema where multiple accessors + // are synthesized for properties in class + // extensions that are redeclared in a category and the + // the implicit parameters are not filled in for + // the method on the category. + // This ensures we find the accessor in the extension, which + // has the implicit parameters filled in. + auto *ID = CompileTimeMD->getClassInterface(); + for (auto *CatDecl : ID->visible_extensions()) { + Val = CatDecl->getMethod(Sel, + CompileTimeMD->isInstanceMethod()); + if (*Val) + break; + } + } + if (!*Val) + Val = IDecl->lookupInstanceMethod(Sel); + } } const ObjCMethodDecl *MD = Val.getValue(); |