From 6d0e6ce200aa06b06f0e9b493ed365bbe2982cee Mon Sep 17 00:00:00 2001 From: Tom Care Date: Fri, 27 Aug 2010 22:46:32 +0000 Subject: [PATCH] Enabled relaxed LiveVariables analysis in the path-sensitive engine to increase the coverage of bugs. Primarily affects IdempotentOperationChecker. - Migrated a temporarily separated test back to its original file (bug has been fixed, null-deref-ps-temp.c -> null-deref-ps.c) - Changed SymbolManager to use relaxed LiveVariables - Updated several test cases that the IdempotentOperationChecker class now flags - Added test case to test relaxed LiveVariables use by the IdempotentOperationChecker git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112312 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Checker/SymbolManager.cpp | 6 ++++-- test/Analysis/func.c | 2 +- test/Analysis/idempotent-operations.c | 14 ++++++++++++ test/Analysis/misc-ps-region-store.m | 4 ++-- test/Analysis/misc-ps.m | 2 +- test/Analysis/null-deref-ps-temp.c | 31 --------------------------- test/Analysis/null-deref-ps.c | 21 +++++++++++++++++- 7 files changed, 42 insertions(+), 38 deletions(-) delete mode 100644 test/Analysis/null-deref-ps-temp.c diff --git a/lib/Checker/SymbolManager.cpp b/lib/Checker/SymbolManager.cpp index 7ab356d473..3b1bb6d98d 100644 --- a/lib/Checker/SymbolManager.cpp +++ b/lib/Checker/SymbolManager.cpp @@ -324,7 +324,8 @@ bool SymbolReaper::isLive(SymbolRef sym) { } bool SymbolReaper::isLive(const Stmt* ExprVal) const { - return LCtx->getLiveVariables()->isLive(Loc, ExprVal); + return LCtx->getAnalysisContext()->getRelaxedLiveVariables()-> + isLive(Loc, ExprVal); } bool SymbolReaper::isLive(const VarRegion *VR) const { @@ -332,7 +333,8 @@ bool SymbolReaper::isLive(const VarRegion *VR) const { const StackFrameContext *CurrentContext = LCtx->getCurrentStackFrame(); if (VarContext == CurrentContext) - return LCtx->getLiveVariables()->isLive(Loc, VR->getDecl()); + return LCtx->getAnalysisContext()->getRelaxedLiveVariables()-> + isLive(Loc, VR->getDecl()); return VarContext->isParentOf(CurrentContext); } diff --git a/test/Analysis/func.c b/test/Analysis/func.c index 53c873df55..a7e84615fd 100644 --- a/test/Analysis/func.c +++ b/test/Analysis/func.c @@ -4,7 +4,7 @@ void f(void) { void (*p)(void); p = f; - p = &f; + p = &f; // expected-warning{{Assigned value is always the same as the existing value}} p(); (*p)(); } diff --git a/test/Analysis/idempotent-operations.c b/test/Analysis/idempotent-operations.c index 09df6dece0..debff0efff 100644 --- a/test/Analysis/idempotent-operations.c +++ b/test/Analysis/idempotent-operations.c @@ -78,6 +78,20 @@ void bailout() { } } +// Relaxed liveness - check that we don't kill liveness at assignments +typedef unsigned uintptr_t; +void kill_at_assign() { + short array[2]; + uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion}} + short *p = x; // expected-warning{{incompatible integer to pointer conversion}} + + // The following branch should be infeasible. + if (!(p = &array[0])) { // expected-warning{{Assigned value is always the same as the existing value}} + p = 0; + *p = 1; // no-warning + } +} + // False positive tests unsigned false1() { diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 9c2add0167..d46437388d 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -253,7 +253,7 @@ void rdar_7249327(unsigned int A[2*32]) { a = A; b = B; - n = *a++; + n = *a++; // expected-warning{{Assigned value is always the same as the existing value}} if (n) x += *b++; // no-warning } @@ -708,7 +708,7 @@ int pr5857(char *src) { long long *z = (long long *) (intptr_t) src; long long w = 0; int n = 0; - for (n = 0; n < y; ++n) { + for (n = 0; n < y; ++n) { // expected-warning{{Assigned value is always the same as the existing value}} // Previously we crashed analyzing this statement. w = *z++; } diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index ced0853574..1aa80bd89f 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -458,7 +458,7 @@ void rdar_7062158_2() { // ElementRegion is created. unsigned char test_array_index_bitwidth(const unsigned char *p) { unsigned short i = 0; - for (i = 0; i < 2; i++) p = &p[i]; + for (i = 0; i < 2; i++) p = &p[i]; // expected-warning{{Assigned value is always the same as the existing value}} return p[i+1]; } diff --git a/test/Analysis/null-deref-ps-temp.c b/test/Analysis/null-deref-ps-temp.c deleted file mode 100644 index 90b6ed3398..0000000000 --- a/test/Analysis/null-deref-ps-temp.c +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-no-purge-dead -verify %s -Wreturn-type - -// This is a temporary file to isolate a test case that would cause a failure -// only some of the time in null-deref-ps.c. The idempotent operations checker -// has revealed a bug on line 18 ('=' instead of '==') when the -// -analyzer-no-purge-dead flag is passed to cc1. Some fundamental design -// changes are needed to make this work without the -analyzer-no-purge-dead flag -// and this test will be integrated back into the main file when this happens. - -typedef unsigned uintptr_t; - -int f4_b() { - short array[2]; - uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion}} - short *p = x; // expected-warning{{incompatible integer to pointer conversion}} - - // The following branch should be infeasible. - if (!(p = &array[0])) { // expected-warning{{Assigned value is always the same as the existing value}} - p = 0; - *p = 1; // no-warning - } - - if (p) { - *p = 5; // no-warning - p = 0; - } - else return; // expected-warning {{non-void function 'f4_b' should return a value}} - - *p += 10; // expected-warning{{Dereference of null pointer}} - return 0; -} diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c index 356e2b4d0f..d0e4f61521 100644 --- a/test/Analysis/null-deref-ps.c +++ b/test/Analysis/null-deref-ps.c @@ -60,7 +60,26 @@ int f4(int *p) { return *q; // expected-warning{{Dereference of null pointer (loaded from variable 'q')}} } -// Placeholder for f4_b, temporarily moved to null-deref-ps-temp.c +int f4_b() { + short array[2]; + uintptr_t x = array; // expected-warning{{incompatible pointer to integer conversion}} + short *p = x; // expected-warning{{incompatible integer to pointer conversion}} + + // The following branch should be infeasible. + if (!(p == &array[0])) { + p = 0; + *p = 1; // no-warning + } + + if (p) { + *p = 5; // no-warning + p = 0; + } + else return; // expected-warning {{non-void function 'f4_b' should return a value}} + + *p += 10; // expected-warning{{Dereference of null pointer}} + return 0; +} int f5() { -- 2.40.0