diff --git a/clang/include/clang/Analysis/PathSensitive/SymbolManager.h b/clang/include/clang/Analysis/PathSensitive/SymbolManager.h index dfc1ae81ee64..b188cab888d7 100644 --- a/clang/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/clang/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/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index b883f8806141..01260480d192 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/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/clang/lib/Analysis/SymbolManager.cpp b/clang/lib/Analysis/SymbolManager.cpp index 4d101f186bd5..efc7cd3b86f2 100644 --- a/clang/lib/Analysis/SymbolManager.cpp +++ b/clang/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/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index ae777a5e2668..1f4b7632bc74 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/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 +} +