From 9ae66a47586ba3dcc68f303bc4dfc67c02952848 Mon Sep 17 00:00:00 2001 From: Jordan Rose <jordan_rose@apple.com> Date: Tue, 14 Jan 2014 17:29:06 +0000 Subject: [PATCH] [analyzer] Use synthesized ASTs for property getters when available. This allows the analyzer to handle properties with C++ class type, finishing up the FIXME from r198953. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199226 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/BodyFarm.cpp | 24 ++++++++++++++++++------ test/Analysis/properties.mm | 12 ++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp index a6567ade52f..373f5d1ffa7 100644 --- a/lib/Analysis/BodyFarm.cpp +++ b/lib/Analysis/BodyFarm.cpp @@ -393,16 +393,28 @@ static Stmt *createObjCPropertyGetter(ASTContext &Ctx, return 0; if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak) return 0; + + const ObjCImplementationDecl *ImplDecl = + IVar->getContainingInterface()->getImplementation(); + if (ImplDecl) { + typedef ObjCImplementationDecl::propimpl_iterator propimpl_iterator; + for (propimpl_iterator I = ImplDecl->propimpl_begin(), + E = ImplDecl->propimpl_end(); + I != E; ++I) { + if (I->getPropertyDecl() != Prop) + continue; + + if (I->getGetterCXXConstructor()) { + ASTMaker M(Ctx); + return M.makeReturn(I->getGetterCXXConstructor()); + } + } + } + if (IVar->getType().getCanonicalType() != Prop->getType().getNonReferenceType().getCanonicalType()) return 0; - // C++ records require copy constructors, so we can't just synthesize an AST. - // FIXME: Use ObjCPropertyImplDecl's already-synthesized AST. Currently it's - // not in a form the analyzer can use. - if (Prop->getType()->getAsCXXRecordDecl()) - return 0; - ASTMaker M(Ctx); const VarDecl *selfVar = Prop->getGetterMethodDecl()->getSelfDecl(); diff --git a/test/Analysis/properties.mm b/test/Analysis/properties.mm index dd44219856f..57aacd4f9d2 100644 --- a/test/Analysis/properties.mm +++ b/test/Analysis/properties.mm @@ -42,21 +42,21 @@ struct IntWrapperStruct { @end void testConsistencyStruct(StructWrapper *w) { - clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}} int origValue = w.inner.value; if (origValue != 42) return; - clang_analyzer_eval(w.inner.value == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}} } class CustomCopy { public: CustomCopy() : value(0) {} - CustomCopy(const CustomCopy &other) { - clang_analyzer_checkInlined(false); + CustomCopy(const CustomCopy &other) : value(other.value) { + clang_analyzer_checkInlined(true); // expected-warning{{TRUE}} } int value; }; @@ -70,11 +70,11 @@ public: @end void testConsistencyCustomCopy(CustomCopyWrapper *w) { - clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}} int origValue = w.inner.value; if (origValue != 42) return; - clang_analyzer_eval(w.inner.value == 42); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}} } -- GitLab