From: Ted Kremenek Date: Wed, 12 Sep 2012 06:22:18 +0000 (+0000) Subject: Fix regression where "looping back to the head of" PathDiagnosticEvents X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f57a2aa02c0578c5bd834fec0d44c16ad9908620;p=clang Fix regression where "looping back to the head of" PathDiagnosticEvents were not emitted. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163683 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 80ece9a3b0..46acea78a8 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1248,20 +1248,15 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, } } - const CFGBlock &Blk = *BE->getSrc(); - const Stmt *Term = Blk.getTerminator(); - // Are we jumping to the head of a loop? Add a special diagnostic. - if (const Stmt *Loop = BE->getDst()->getLoopTarget()) { + if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) { PathDiagnosticLocation L(Loop, SM, PDB.LC); const CompoundStmt *CS = NULL; - if (!Term) { - if (const ForStmt *FS = dyn_cast(Loop)) - CS = dyn_cast(FS->getBody()); - else if (const WhileStmt *WS = dyn_cast(Loop)) - CS = dyn_cast(WS->getBody()); - } + if (const ForStmt *FS = dyn_cast(Loop)) + CS = dyn_cast(FS->getBody()); + else if (const WhileStmt *WS = dyn_cast(Loop)) + CS = dyn_cast(WS->getBody()); PathDiagnosticEventPiece *p = new PathDiagnosticEventPiece(L, @@ -1277,8 +1272,8 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, EB.addEdge(BL); } } - - if (Term) + + if (const Stmt *Term = BE->getSrc()->getTerminator()) EB.addContext(Term); break; diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m index 07cf7bf6ed..74923acca7 100644 --- a/test/Analysis/plist-output.m +++ b/test/Analysis/plist-output.m @@ -79,6 +79,16 @@ int test_cond_assign() { } @end +// Test that loops are documented in the path. +void rdar12280665() { + for (unsigned i = 0; i < 2; ++i) { + if (i == 1) { + int *p = 0; + *p = 0xDEADBEEF; // expected-warning {{dereference}} + } + } +} + // CHECK: diagnostics // CHECK-NEXT: // CHECK-NEXT: @@ -111,7 +121,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: message -// CHECK-NEXT: Variable 'p' initialized to a null pointer value +// CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -174,7 +184,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') @@ -254,7 +264,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Null pointer value stored to 'p' // CHECK-NEXT: message -// CHECK-NEXT: Null pointer value stored to 'p' +// CHECK-NEXT: Null pointer value stored to 'p' // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -317,7 +327,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') @@ -397,7 +407,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Variable 'q' initialized to a null pointer value // CHECK-NEXT: message -// CHECK-NEXT: Variable 'q' initialized to a null pointer value +// CHECK-NEXT: Variable 'q' initialized to a null pointer value // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -460,7 +470,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'q') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'q') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'q') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'q') @@ -540,7 +550,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Assuming 'p' is null // CHECK-NEXT: message -// CHECK-NEXT: Assuming 'p' is null +// CHECK-NEXT: Assuming 'p' is null // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindevent @@ -569,7 +579,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Assuming pointer value is null // CHECK-NEXT: message -// CHECK-NEXT: Assuming pointer value is null +// CHECK-NEXT: Assuming pointer value is null // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -632,7 +642,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') @@ -712,7 +722,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Assuming 'q' is null // CHECK-NEXT: message -// CHECK-NEXT: Assuming 'q' is null +// CHECK-NEXT: Assuming 'q' is null // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -775,7 +785,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: message -// CHECK-NEXT: Variable 'p' initialized to a null pointer value +// CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -838,7 +848,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') @@ -952,7 +962,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from field 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from field 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from field 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from field 'p') @@ -1032,7 +1042,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Assuming 'a' is not equal to 0 // CHECK-NEXT: message -// CHECK-NEXT: Assuming 'a' is not equal to 0 +// CHECK-NEXT: Assuming 'a' is not equal to 0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -1129,7 +1139,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Assuming 'b' is equal to 0 // CHECK-NEXT: message -// CHECK-NEXT: Assuming 'b' is equal to 0 +// CHECK-NEXT: Assuming 'b' is equal to 0 // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -1192,7 +1202,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: message -// CHECK-NEXT: Variable 'p' initialized to a null pointer value +// CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -1255,7 +1265,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') @@ -1369,7 +1379,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Value assigned to 'p' // CHECK-NEXT: message -// CHECK-NEXT: Value assigned to 'p' +// CHECK-NEXT: Value assigned to 'p' // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindevent @@ -1398,7 +1408,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Assuming 'p' is null // CHECK-NEXT: message -// CHECK-NEXT: Assuming 'p' is null +// CHECK-NEXT: Assuming 'p' is null // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindevent @@ -1427,7 +1437,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Assuming pointer value is null // CHECK-NEXT: message -// CHECK-NEXT: Assuming pointer value is null +// CHECK-NEXT: Assuming pointer value is null // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -1524,7 +1534,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') @@ -1604,7 +1614,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: message -// CHECK-NEXT: Variable 'p' initialized to a null pointer value +// CHECK-NEXT: Variable 'p' initialized to a null pointer value // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: kindcontrol @@ -1667,7 +1677,7 @@ int test_cond_assign() { // CHECK-NEXT: extended_message // CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: message -// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') // CHECK-NEXT: // CHECK-NEXT: // CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') @@ -1683,4 +1693,312 @@ int test_cond_assign() { // CHECK-NEXT: file0 // CHECK-NEXT: // CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: path +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col4 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col4 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line89 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line89 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line89 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line89 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Looping back to the head of the loop +// CHECK-NEXT: message +// CHECK-NEXT: Looping back to the head of the loop +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line84 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col4 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col4 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line85 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line86 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line86 +// CHECK-NEXT: col7 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line86 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line86 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line86 +// CHECK-NEXT: col10 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Variable 'p' initialized to a null pointer value +// CHECK-NEXT: message +// CHECK-NEXT: Variable 'p' initialized to a null pointer value +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line86 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line86 +// CHECK-NEXT: col7 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line87 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line87 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line87 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line87 +// CHECK-NEXT: col6 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line87 +// CHECK-NEXT: col6 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: message +// CHECK-NEXT: Dereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: descriptionDereference of null pointer (loaded from variable 'p') +// CHECK-NEXT: categoryLogic error +// CHECK-NEXT: typeDereference of null pointer +// CHECK-NEXT: issue_context_kindfunction +// CHECK-NEXT: issue_contextrdar12280665 +// CHECK-NEXT: issue_hash4 +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line87 +// CHECK-NEXT: col5 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: // CHECK-NEXT: