From 5794ef695010e81dad3b2eead1f777268b1449f9 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 14 Feb 2011 17:59:23 +0000 Subject: [PATCH] Fix edge case where we don't cull warnings in IdempotentOperationsChecker due to incomplete analysis of loops. llvm-svn: 125495 --- .../Checkers/IdempotentOperationChecker.cpp | 7 ++++++- .../idempotent-operations-limited-loops.c | 20 ++++++------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp index 92ce2c313e80..0b8ebfd285cf 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp @@ -578,7 +578,12 @@ IdempotentOperationChecker::pathWasCompletelyAnalyzed(const CFG *cfg, // The destination block on the BlockEdge is the first block that was not // analyzed. If we can reach this block from the aborted block, then this // block was not completely analyzed. - if (CRA->isReachable(BE.getDst(), CB)) + // + // Also explicitly check if the current block is the destination block. + // While technically reachable, it means we aborted the analysis on + // a path that included that block. + const CFGBlock *destBlock = BE.getDst(); + if (destBlock == CB || CRA->isReachable(destBlock, CB)) return false; } diff --git a/clang/test/Analysis/idempotent-operations-limited-loops.c b/clang/test/Analysis/idempotent-operations-limited-loops.c index e3043ee014ac..8e65197ab2ba 100644 --- a/clang/test/Analysis/idempotent-operations-limited-loops.c +++ b/clang/test/Analysis/idempotent-operations-limited-loops.c @@ -1,7 +1,11 @@ -void always_warning() { int *p = 0; *p = 0xDEADBEEF; } +// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations -analyzer-max-loop 3 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations -analyzer-max-loop 4 -verify %s +// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations %s -verify -// FIXME: False positive due to loop unrolling. This should be fixed. +void always_warning() { int *p = 0; *p = 0xDEADBEEF; } // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} +// This test case previously caused a bogus idempotent operation warning +// due to us not properly culling warnings due to incomplete analysis of loops. int pr8403() { int i; @@ -15,15 +19,3 @@ int pr8403() return 0; } -// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations -analyzer-max-loop 3 %s 2>&1 | FileCheck --check-prefix=Loops3 %s -// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations -analyzer-max-loop 4 %s 2>&1 | FileCheck --check-prefix=Loops4 %s -// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-check-objc-mem -analyzer-check-idempotent-operations %s 2>&1 | FileCheck --check-prefix=LoopsDefault %s - -// CHECK-Loops3: :1:37: warning: Dereference of null pointer -// CHECK-Loops3: :11:27: warning: The left operand to '+' is always 0 -// CHECK-Loops3: 2 warnings generated -// CHECK-Loops4: :1:37: warning: Dereference of null pointer -// CHECK-Loops4: 1 warning generated. -// CHECK-LoopsDefault: :1:37: warning: Dereference of null pointer -// CHECK-LoopsDefault: 1 warning generated. -