From b6b81d1047aeec4f15b90ca1b9d4d7fcff154f7d Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 17 Oct 2008 17:24:14 +0000 Subject: [PATCH] "Implement" GRExprEngine::VisitLValue for ObjCPropertyRefExpr. This is only a bandid; we need to properly handle properties by using locv/nonloc objects and specially handling property assignments in the transfer function for BinaryOperator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57693 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/GRExprEngine.cpp | 15 +++++++++++++++ test/Analysis/ObjCProperties.m | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 test/Analysis/ObjCProperties.m diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index d8ab4b1275..bdf42e99c5 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -431,6 +431,21 @@ void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) { case Stmt::MemberExprClass: VisitMemberExpr(cast(Ex), Pred, Dst, true); return; + + case Stmt::ObjCPropertyRefExprClass: + // FIXME: Property assignments are lvalues, but not really "locations". + // e.g.: self.x = something; + // Here the "self.x" really can translate to a method call (setter) when + // the assignment is made. Moreover, the entire assignment expression + // evaluate to whatever "something" is, not calling the "getter" for + // the property (which would make sense since it can have side effects). + // We'll probably treat this as a location, but not one that we can + // take the address of. Perhaps we need a new SVal class for cases + // like thsis? + // Note that we have a similar problem for bitfields, since they don't + // have "locations" in the sense that we can take their address. + Dst.Add(Pred); + return; } } diff --git a/test/Analysis/ObjCProperties.m b/test/Analysis/ObjCProperties.m new file mode 100644 index 0000000000..03eefc23fe --- /dev/null +++ b/test/Analysis/ObjCProperties.m @@ -0,0 +1,20 @@ +// RUN: clang -checker-simple %s -verify + +// The point of this test cases is to exercise properties in the static +// analyzer + +@interface MyClass { +@private + id _X; +} +- (id)initWithY:(id)Y; +@property(copy, readonly) id X; +@end + +@implementation MyClass +@synthesize X = _X; +- (id)initWithY:(id)Y { + self.X = Y; + return self; +} +@end -- 2.40.0