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 dfc1ae8..b188cab 100644
--- a/include/clang/Analysis/PathSensitive/SymbolManager.h
+++ b/include/clang/Analysis/PathSensitive/SymbolManager.h
@@ -218,6 +218,8 @@
: 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 b883f88..0126048 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -525,6 +525,10 @@
// 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 4d101f1..efc7cd3 100644
--- a/lib/Analysis/SymbolManager.cpp
+++ b/lib/Analysis/SymbolManager.cpp
@@ -94,6 +94,10 @@
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 ae777a5..1f4b763 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -24,6 +24,19 @@
- (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 <rdar://problem/6253157>
@interface A @end
@@ -201,3 +214,14 @@
if (!x) { return 0; }
return 1;
}
+
+// <rdar://problem/6708148> - 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
+}
+