summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2017-03-09 00:01:10 +0000
committerAnna Zaks <ganna@apple.com>2017-03-09 00:01:10 +0000
commit37faed97c1b234592c87aaac6f33003ebe0ff708 (patch)
treed713abdc3f89203802f7e32eef70d4aff14376a1
parentd4e43ae22a83e34079625fc64bedc25463a00de9 (diff)
downloadbcm5719-llvm-37faed97c1b234592c87aaac6f33003ebe0ff708.tar.gz
bcm5719-llvm-37faed97c1b234592c87aaac6f33003ebe0ff708.zip
[analyzer] Improve usability of ExprInspectionChecker
Some of the magic functions take arguments of arbitrary type. However, for semantic correctness, the compiler still requires a declaration of these functions with the correct type. Since C does not have argument-type-overloaded function, this made those functions hard to use in C code. Improve this situation by allowing arbitrary suffixes in the affected magic functions' names, thus allowing the user to create different declarations for different types. A patch by Keno Fischer! Differential Revision: https://reviews.llvm.org/D30589 llvm-svn: 297325
-rw-r--r--clang/docs/analyzer/DebugChecks.rst8
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp4
-rw-r--r--clang/test/Analysis/explain-svals.c25
3 files changed, 34 insertions, 3 deletions
diff --git a/clang/docs/analyzer/DebugChecks.rst b/clang/docs/analyzer/DebugChecks.rst
index ecf11ca0f13..880dcfc9609 100644
--- a/clang/docs/analyzer/DebugChecks.rst
+++ b/clang/docs/analyzer/DebugChecks.rst
@@ -178,15 +178,21 @@ ExprInspection checks
This function explains the value of its argument in a human-readable manner
in the warning message. You can make as many overrides of its prototype
in the test code as necessary to explain various integral, pointer,
- or even record-type values.
+ or even record-type values. To simplify usage in C code (where overloading
+ the function declaration is not allowed), you may append an arbitrary suffix
+ to the function name, without affecting functionality.
Example usage::
void clang_analyzer_explain(int);
void clang_analyzer_explain(void *);
+ // Useful in C code
+ void clang_analyzer_explain_int(int);
+
void foo(int param, void *ptr) {
clang_analyzer_explain(param); // expected-warning{{argument 'param'}}
+ clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}}
if (!ptr)
clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index fe48a942236..32040e71163 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -72,8 +72,8 @@ bool ExprInspectionChecker::evalCall(const CallExpr *CE,
&ExprInspectionChecker::analyzerWarnIfReached)
.Case("clang_analyzer_warnOnDeadSymbol",
&ExprInspectionChecker::analyzerWarnOnDeadSymbol)
- .Case("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain)
- .Case("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump)
+ .StartsWith("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain)
+ .StartsWith("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump)
.Case("clang_analyzer_getExtent", &ExprInspectionChecker::analyzerGetExtent)
.Case("clang_analyzer_printState",
&ExprInspectionChecker::analyzerPrintState)
diff --git a/clang/test/Analysis/explain-svals.c b/clang/test/Analysis/explain-svals.c
new file mode 100644
index 00000000000..f1540bbe2de
--- /dev/null
+++ b/clang/test/Analysis/explain-svals.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
+
+struct S {
+ int z;
+};
+
+void clang_analyzer_explain_int(int);
+void clang_analyzer_explain_voidp(void *);
+void clang_analyzer_explain_S(struct S);
+
+int glob;
+
+void test_1(int param, void *ptr) {
+ clang_analyzer_explain_voidp(&glob); // expected-warning-re{{{{^pointer to global variable 'glob'$}}}}
+ clang_analyzer_explain_int(param); // expected-warning-re{{{{^argument 'param'$}}}}
+ clang_analyzer_explain_voidp(ptr); // expected-warning-re{{{{^argument 'ptr'$}}}}
+ if (param == 42)
+ clang_analyzer_explain_int(param); // expected-warning-re{{{{^signed 32-bit integer '42'$}}}}
+}
+
+void test_2(struct S s) {
+ clang_analyzer_explain_S(s); //expected-warning-re{{{{^lazily frozen compound value of parameter 's'$}}}}
+ clang_analyzer_explain_voidp(&s); // expected-warning-re{{{{^pointer to parameter 's'$}}}}
+ clang_analyzer_explain_int(s.z); // expected-warning-re{{{{^initial value of field 'z' of parameter 's'$}}}}
+}
OpenPOWER on IntegriCloud