From: Ted Kremenek Date: Mon, 23 Mar 2009 15:42:58 +0000 (+0000) Subject: analyzer: Fix embarrassing regression in BasicStore when invalidating struct X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=693de5d7feb92c096431c98ea6ee637494bfe6fb;p=clang analyzer: Fix embarrassing regression in BasicStore when invalidating struct values passed-by-reference to unknown functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67519 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index dfc1ae81ee..b188cab888 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -218,6 +218,8 @@ public: : SymbolCounter(0), BPAlloc(bpalloc), Ctx(ctx) {} ~SymbolManager(); + + static bool canSymbolicate(QualType T); /// Make a unique symbol for MemRegion R according to its kind. SymbolRef getRegionRValueSymbol(const MemRegion* R); diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index b883f88061..01260480d1 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -525,6 +525,10 @@ Store BasicStoreManager::getInitialStore() { // Punt on static variables for now. if (VD->getStorageClass() == VarDecl::Static) continue; + + // Only handle simple types that we can symbolicate. + if (!SymbolManager::canSymbolicate(VD->getType())) + continue; // Initialize globals and parameters to symbolic values. // Initialize local variables to undefined. diff --git a/lib/Analysis/SymbolManager.cpp b/lib/Analysis/SymbolManager.cpp index 4d101f186b..efc7cd3b86 100644 --- a/lib/Analysis/SymbolManager.cpp +++ b/lib/Analysis/SymbolManager.cpp @@ -94,6 +94,10 @@ QualType SymbolRegionRValue::getType(ASTContext& C) const { SymbolManager::~SymbolManager() {} +bool SymbolManager::canSymbolicate(QualType T) { + return Loc::IsLocType(T) || T->isIntegerType(); +} + void SymbolReaper::markLive(SymbolRef sym) { TheLiving = F.Add(TheLiving, sym); TheDead = F.Remove(TheDead, sym); diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index ae777a5e26..1f4b7632bc 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -24,6 +24,19 @@ extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); - (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...; @end extern NSString * const NSConnectionReplyMode; +typedef float CGFloat; +typedef struct _NSPoint { + CGFloat x; + CGFloat y; +} NSPoint; +typedef struct _NSSize { + CGFloat width; + CGFloat height; +} NSSize; +typedef struct _NSRect { + NSPoint origin; + NSSize size; +} NSRect; // Reduced test case from crash in @interface A @end @@ -201,3 +214,14 @@ int rdar6695527(double x) { if (!x) { return 0; } return 1; } + +// - Test that we properly invalidate structs +// passed-by-reference to a function. +void pr6708148_invalidate(NSRect *x); +void pr6708148_use(NSRect x); +void pr6708148_test(void) { + NSRect x; + pr6708148_invalidate(&x); + pr6708148_use(x); // no-warning +} +