Skip to content

Commit 9d6a615

Browse files
author
Balazs Benics
committed
[analyzer] Prevent misuses of -analyze-function
Sometimes when I pass the mentioned option I forget about passing the parameter list for c++ sources. It would be also useful newcomers to learn about this. This patch introduces some logic checking common misuses involving `-analyze-function`. Reviewed-By: martong Differential Revision: https://reviews.llvm.org/D118690
1 parent e0e6f3a commit 9d6a615

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,28 @@ static bool fileContainsString(StringRef Substring, ASTContext &C) {
501501
return Buffer.contains(Substring);
502502
}
503503

504+
static void reportAnalyzerFunctionMisuse(const AnalyzerOptions &Opts,
505+
const ASTContext &Ctx) {
506+
llvm::errs() << "Every top-level function was skipped.\n";
507+
508+
if (!Opts.AnalyzerDisplayProgress)
509+
llvm::errs() << "Pass the -analyzer-display-progress for tracking which "
510+
"functions are analyzed.\n";
511+
512+
bool HasBrackets =
513+
Opts.AnalyzeSpecificFunction.find("(") != std::string::npos;
514+
515+
if (Ctx.getLangOpts().CPlusPlus && !HasBrackets) {
516+
llvm::errs()
517+
<< "For analyzing C++ code you need to pass the function parameter "
518+
"list: -analyze-function=\"foobar(int, _Bool)\"\n";
519+
} else if (!Ctx.getLangOpts().CPlusPlus && HasBrackets) {
520+
llvm::errs() << "For analyzing C code you shouldn't pass the function "
521+
"parameter list, only the name of the function: "
522+
"-analyze-function=foobar\n";
523+
}
524+
}
525+
504526
void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) {
505527
BugReporter BR(*Mgr);
506528
TranslationUnitDecl *TU = C.getTranslationUnitDecl();
@@ -537,6 +559,14 @@ void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) {
537559

538560
BR.FlushReports();
539561
RecVisitorBR = nullptr;
562+
563+
// If the user wanted to analyze a specific function and the number of basic
564+
// blocks analyzed is zero, than the user might not specified the function
565+
// name correctly.
566+
// FIXME: The user might have analyzed the requested function in Syntax mode,
567+
// but we are unaware of that.
568+
if (!Opts->AnalyzeSpecificFunction.empty() && NumFunctionsAnalyzed == 0)
569+
reportAnalyzerFunctionMisuse(*Opts, *Ctx);
540570
}
541571

542572
void AnalysisConsumer::reportAnalyzerProgress(StringRef S) {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
int fizzbuzz(int x, bool y) {
2+
return x + y;
3+
}
4+
5+
// C++ but not uses parentheses in the '-analyze-function' option.
6+
//
7+
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
8+
// RUN: -analyze-function='missing_fn' -x c++ \
9+
// RUN: 2>&1 %s | FileCheck %s -check-prefix=CHECK-CXX
10+
//
11+
// CHECK-CXX: Every top-level function was skipped.
12+
// CHECK-CXX-NEXT: Pass the -analyzer-display-progress for tracking which functions are analyzed.
13+
// CHECK-CXX-NEXT: For analyzing C++ code you need to pass the function parameter list: -analyze-function="foobar(int, _Bool)"
14+
15+
// C but uses parentheses in the '-analyze-function' option.
16+
//
17+
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
18+
// RUN: -analyze-function='missing_fn()' -x c -Dbool=_Bool \
19+
// RUN: 2>&1 %s | FileCheck %s -check-prefix=CHECK-C
20+
//
21+
// CHECK-C: Every top-level function was skipped.
22+
// CHECK-C-NEXT: Pass the -analyzer-display-progress for tracking which functions are analyzed.
23+
// CHECK-C-NEXT: For analyzing C code you shouldn't pass the function parameter list, only the name of the function: -analyze-function=foobar
24+
25+
// The user passed the '-analyzer-display-progress' option, we don't need to advocate it.
26+
//
27+
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
28+
// RUN: -analyze-function=missing_fn \
29+
// RUN: -analyzer-display-progress -x c -Dbool=_Bool \
30+
// RUN: 2>&1 %s | FileCheck %s -check-prefix=CHECK-DONT-ADVOCATE-DISPLAY-PROGRESS
31+
//
32+
// CHECK-DONT-ADVOCATE-DISPLAY-PROGRESS: Every top-level function was skipped.
33+
// CHECK-DONT-ADVOCATE-DISPLAY-PROGRESS-NOT: Pass the -analyzer-display-progress
34+
35+
// The user passed the '-analyze-function' option but that doesn't mach to any declaration.
36+
//
37+
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
38+
// RUN: -analyze-function='missing_fn()' -x c++ \
39+
// RUN: 2>&1 %s | FileCheck %s -check-prefix=CHECK-ADVOCATE-DISPLAY-PROGRESS
40+
//
41+
// CHECK-ADVOCATE-DISPLAY-PROGRESS: Every top-level function was skipped.
42+
// CHECK-ADVOCATE-DISPLAY-PROGRESS-NEXT: Pass the -analyzer-display-progress for tracking which functions are analyzed.
43+
// CHECK-ADVOCATE-DISPLAY-PROGRESS-NOT: For analyzing
44+
45+
// The user passed the '-analyze-function' option and that matches on a
46+
// declaration in C++ mode.
47+
//
48+
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
49+
// RUN: -analyze-function='fizzbuzz(int, _Bool)' -x c++ \
50+
// RUN: 2>&1 %s | FileCheck %s -check-prefix=CHECK-EMPTY --allow-empty
51+
//
52+
// Expected empty standard output.
53+
// CHECK-EMPTY-NOT: Every top-level function was skipped.
54+
55+
// The user passed the '-analyze-function' option and that matches on a
56+
// declaration in C mode.
57+
//
58+
// RUN: %clang_analyze_cc1 -analyzer-checker=core \
59+
// RUN: -analyze-function='fizzbuzz' -x c -Dbool=_Bool \
60+
// RUN: 2>&1 %s | FileCheck %s -check-prefix=CHECK-EMPTY2 --allow-empty
61+
//
62+
// Expected empty standard output.
63+
// CHECK-EMPTY2-NOT: Every top-level function was skipped.
64+
65+
// Same as the previous but syntax mode only.
66+
// FIXME: This should have empty standard output.
67+
//
68+
// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config ipa=none \
69+
// RUN: -analyze-function='fizzbuzz(int, _Bool)' -x c++ \
70+
// RUN: 2>&1 %s | FileCheck %s -check-prefix=CHECK-EMPTY3 --allow-empty
71+
//
72+
// FIXME: This should have empty standard output.
73+
// CHECK-EMPTY3: Every top-level function was skipped.
74+
// CHECK-EMPTY3-NEXT: Pass the -analyzer-display-progress for tracking which functions are analyzed.

0 commit comments

Comments
 (0)