Author: szelethus Date: Fri Jul 5 07:00:08 2019 New Revision: 365208 URL: http://llvm.org/viewvc/llvm-project?rev=365208&view=rev Log: [analyzer] Add a debug analyzer config to place an event for each tracked condition
Differential Revision: https://reviews.llvm.org/D63642 Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp cfe/trunk/test/Analysis/analyzer-config.c cfe/trunk/test/Analysis/track-control-dependency-conditions.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def?rev=365208&r1=365207&r2=365208&view=diff ============================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def Fri Jul 5 07:00:08 2019 @@ -296,6 +296,10 @@ ANALYZER_OPTION(bool, ShouldTrackConditi "an already tracked variable.", false) +ANALYZER_OPTION(bool, ShouldTrackConditionsDebug, "track-conditions-debug", + "Whether to place an event at each tracked condition.", + false) + //===----------------------------------------------------------------------===// // Unsinged analyzer options. //===----------------------------------------------------------------------===// Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=365208&r1=365207&r2=365208&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Jul 5 07:00:08 2019 @@ -467,6 +467,10 @@ static void parseAnalyzerConfigs(Analyze if (!Diags) return; + if (AnOpts.ShouldTrackConditionsDebug && !AnOpts.ShouldTrackConditions) + Diags->Report(diag::err_analyzer_config_invalid_input) + << "track-conditions-debug" << "'track-conditions' to also be enabled"; + if (!AnOpts.CTUDir.empty() && !llvm::sys::fs::is_directory(AnOpts.CTUDir)) Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir" << "a filename"; Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=365208&r1=365207&r2=365208&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Fri Jul 5 07:00:08 2019 @@ -1667,6 +1667,26 @@ static CFGBlock *GetRelevantBlock(const return nullptr; } +static std::shared_ptr<PathDiagnosticEventPiece> +constructDebugPieceForTrackedCondition(const Expr *Cond, + const ExplodedNode *N, + BugReporterContext &BRC) { + + if (BRC.getAnalyzerOptions().AnalysisDiagOpt == PD_NONE || + !BRC.getAnalyzerOptions().ShouldTrackConditionsDebug) + return nullptr; + + std::string ConditionText = Lexer::getSourceText( + CharSourceRange::getTokenRange(Cond->getSourceRange()), + BRC.getSourceManager(), + BRC.getASTContext().getLangOpts()); + + return std::make_shared<PathDiagnosticEventPiece>( + PathDiagnosticLocation::createBegin( + Cond, BRC.getSourceManager(), N->getLocationContext()), + (Twine() + "Tracking condition '" + ConditionText + "'").str()); +} + std::shared_ptr<PathDiagnosticPiece> TrackControlDependencyCondBRVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, @@ -1695,6 +1715,7 @@ TrackControlDependencyCondBRVisitor::Vis if (BR.addTrackedCondition(N)) { bugreporter::trackExpressionValue( N, Condition, BR, /*EnableNullFPSuppression=*/false); + return constructDebugPieceForTrackedCondition(Condition, N, BRC); } } } Modified: cfe/trunk/test/Analysis/analyzer-config.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.c?rev=365208&r1=365207&r2=365208&view=diff ============================================================================== --- cfe/trunk/test/Analysis/analyzer-config.c (original) +++ cfe/trunk/test/Analysis/analyzer-config.c Fri Jul 5 07:00:08 2019 @@ -85,8 +85,9 @@ // CHECK-NEXT: suppress-inlined-defensive-checks = true // CHECK-NEXT: suppress-null-return-paths = true // CHECK-NEXT: track-conditions = false +// CHECK-NEXT: track-conditions-debug = false // CHECK-NEXT: unix.DynamicMemoryModeling:Optimistic = false // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 86 +// CHECK-NEXT: num-entries = 87 Modified: cfe/trunk/test/Analysis/track-control-dependency-conditions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/track-control-dependency-conditions.cpp?rev=365208&r1=365207&r2=365208&view=diff ============================================================================== --- cfe/trunk/test/Analysis/track-control-dependency-conditions.cpp (original) +++ cfe/trunk/test/Analysis/track-control-dependency-conditions.cpp Fri Jul 5 07:00:08 2019 @@ -3,7 +3,23 @@ // RUN: -analyzer-config track-conditions=true \ // RUN: -analyzer-output=text \ // RUN: -analyzer-checker=core + +// RUN: not %clang_analyze_cc1 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config track-conditions-debug=true \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-INVALID-DEBUG + +// CHECK-INVALID-DEBUG: (frontend): invalid input for analyzer-config option +// CHECK-INVALID-DEBUG-SAME: 'track-conditions-debug', that expects +// CHECK-INVALID-DEBUG-SAME: 'track-conditions' to also be enabled // +// RUN: %clang_analyze_cc1 %s \ +// RUN: -verify=expected,tracking,debug \ +// RUN: -analyzer-config track-conditions=true \ +// RUN: -analyzer-config track-conditions-debug=true \ +// RUN: -analyzer-output=text \ +// RUN: -analyzer-checker=core + // RUN: %clang_analyze_cc1 %s -verify \ // RUN: -analyzer-output=text \ // RUN: -analyzer-checker=core @@ -30,6 +46,8 @@ void test() { if (flag) // expected-note {{Assuming 'flag' is not equal to 0}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} + *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -59,6 +77,8 @@ void test() { if (flag) // expected-note {{Assuming 'flag' is not equal to 0}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} + *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -85,8 +105,11 @@ void test() { if (bar) // expected-note {{Assuming 'bar' is not equal to 0}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'bar'}} if (flag) // expected-note {{Assuming 'flag' is not equal to 0}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} + *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -107,7 +130,7 @@ void test() { if (int flag = foo()) // tracking-note{{Calling 'foo'}} // tracking-note@-1{{Returning from 'foo'}} // tracking-note@-2{{'flag' initialized here}} - + // debug-note@-3{{Tracking condition 'flag'}} // expected-note@-4{{Assuming 'flag' is not equal to 0}} // expected-note@-5{{Taking true branch}} @@ -129,7 +152,7 @@ void test() { if (ConvertsToBool()) // tracking-note@-1 {{Calling 'ConvertsToBool::operator bool'}} // tracking-note@-2{{Returning from 'ConvertsToBool::operator bool'}} - + // debug-note@-3{{Tracking condition 'ConvertsToBool()'}} // expected-note@-4{{Assuming the condition is true}} // expected-note@-5{{Taking true branch}} *x = 5; // expected-warning{{Dereference of null pointer}} @@ -150,8 +173,9 @@ void i(int *ptr) { if (!flipCoin()) // tracking-note@-1{{Calling 'flipCoin'}} // tracking-note@-2{{Returning from 'flipCoin'}} - // expected-note@-3{{Assuming the condition is true}} - // expected-note@-4{{Taking true branch}} + // debug-note@-3{{Tracking condition '!flipCoin()'}} + // expected-note@-4{{Assuming the condition is true}} + // expected-note@-5{{Taking true branch}} *ptr = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -163,6 +187,7 @@ bool coin(); bool flipCoin() { if (coin()) // tracking-note{{Assuming the condition is false}} // tracking-note@-1{{Taking false branch}} + // debug-note@-2{{Tracking condition 'coin()'}} return true; return coin(); // tracking-note{{Returning value}} } @@ -174,8 +199,9 @@ void i(int *ptr) { if (!flipCoin()) // tracking-note@-1{{Calling 'flipCoin'}} // tracking-note@-2{{Returning from 'flipCoin'}} - // expected-note@-3{{Assuming the condition is true}} - // expected-note@-4{{Taking true branch}} + // debug-note@-3{{Tracking condition '!flipCoin()'}} + // expected-note@-4{{Assuming the condition is true}} + // expected-note@-5{{Taking true branch}} *ptr = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -189,6 +215,7 @@ void f() { int *x = 0; // expected-note{{'x' initialized to a null pointer value}} if (flag) // expected-note{{Assuming 'flag' is not equal to 0}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -205,6 +232,7 @@ void f(int y) { int *x = 0; // expected-note{{'x' initialized to a null pointer value}} if (flag) // expected-note{{'flag' is 1}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -229,6 +257,7 @@ void f(int y) { if (flag) // expected-note{{'flag' is 1}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -252,6 +281,7 @@ void f(int flag) { if (flag) // expected-note{{'flag' is not equal to 0}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } @@ -278,6 +308,7 @@ void f(int flag) { if (flag) // expected-note{{'flag' is not equal to 0}} // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} *x = 5; // expected-warning{{Dereference of null pointer}} // expected-note@-1{{Dereference of null pointer}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits