szepet created this revision. szepet added reviewers: NoQ, dcoughlin, xazax.hun. Herald added subscribers: dkrupp, a.sidorin, rnkovacs, baloghadamsoftware, whisperity.
The checker marks the locations where the analyzer creates sinks. However, it can happen that the sink was created because of a loop which does not contain condition statement, only breaks in the body. The `exhausted block` is the block which should contain the condition but empty, in this case. This change only emits this marking in order to avoid the undefined behavior. Repository: rC Clang https://reviews.llvm.org/D42266 Files: lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp test/Analysis/analyzer-stats.c Index: test/Analysis/analyzer-stats.c =================================================================== --- test/Analysis/analyzer-stats.c +++ test/Analysis/analyzer-stats.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks -analyzer-max-loop 4 %s int foo(); @@ -12,3 +12,19 @@ a /= 4; return a; } + + +int sink() // expected-warning-re{{sink -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 1 | Exhausted Block: yes | Empty WorkList: yes}} +{ + for (int i = 0; i < 10; ++i) // expected-warning {{(sink): The analyzer generated a sink at this point}} + ++i; + + return 0; +} + +int emptyConditionLoop() // expected-warning-re{{emptyConditionLoop -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 0 | Exhausted Block: yes | Empty WorkList: yes}} +{ + int num = 1; + for (;;) + num++; +} Index: lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp +++ lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp @@ -122,6 +122,8 @@ E = CE.blocks_exhausted_end(); I != E; ++I) { const BlockEdge &BE = I->first; const CFGBlock *Exit = BE.getDst(); + if (Exit->empty()) + continue; const CFGElement &CE = Exit->front(); if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) { SmallString<128> bufI;
Index: test/Analysis/analyzer-stats.c =================================================================== --- test/Analysis/analyzer-stats.c +++ test/Analysis/analyzer-stats.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks -analyzer-max-loop 4 %s int foo(); @@ -12,3 +12,19 @@ a /= 4; return a; } + + +int sink() // expected-warning-re{{sink -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 1 | Exhausted Block: yes | Empty WorkList: yes}} +{ + for (int i = 0; i < 10; ++i) // expected-warning {{(sink): The analyzer generated a sink at this point}} + ++i; + + return 0; +} + +int emptyConditionLoop() // expected-warning-re{{emptyConditionLoop -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 0 | Exhausted Block: yes | Empty WorkList: yes}} +{ + int num = 1; + for (;;) + num++; +} Index: lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp +++ lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp @@ -122,6 +122,8 @@ E = CE.blocks_exhausted_end(); I != E; ++I) { const BlockEdge &BE = I->first; const CFGBlock *Exit = BE.getDst(); + if (Exit->empty()) + continue; const CFGElement &CE = Exit->front(); if (Optional<CFGStmt> CS = CE.getAs<CFGStmt>()) { SmallString<128> bufI;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits