[clang] 8248c2a - [analyzer][StdLibraryFunctionsChecker] Have proper weak dependencies
Gabor Marton via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 7 08:56:44 PDT 2020
Author: Gabor Marton
Date: 2020-09-07T17:56:26+02:00
New Revision: 8248c2af94975912b14e7e0cb414fcbb82c77123
URL: https://github.com/llvm/llvm-project/commit/8248c2af94975912b14e7e0cb414fcbb82c77123
DIFF: https://github.com/llvm/llvm-project/commit/8248c2af94975912b14e7e0cb414fcbb82c77123.diff
LOG: [analyzer][StdLibraryFunctionsChecker] Have proper weak dependencies
We want the generice StdLibraryFunctionsChecker to report only if there
are no specific checkers that would handle the argument constraint for a
function.
Note, the assumptions are still evaluated, even if the arguement
constraint checker is set to not report. This means that the assumptions
made in the generic StdLibraryFunctionsChecker should be an
over-approximation of the assumptions made in the specific checkers. But
most importantly, the assumptions should not contradict.
Differential Revision: https://reviews.llvm.org/D87240
Added:
clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
Modified:
clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
clang/test/Analysis/analyzer-enabled-checkers.c
Removed:
################################################################################
diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
index a444843c5006..a61af4523134 100644
--- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -349,7 +349,6 @@ let ParentPackage = APIModeling in {
def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
HelpText<"Improve modeling of the C standard library functions">,
- Dependencies<[CallAndMessageModeling]>,
CheckerOptions<[
CmdLineOption<Boolean,
"DisplayLoadedSummaries",
@@ -538,7 +537,7 @@ def StdCLibraryFunctionArgsChecker : Checker<"StdCLibraryFunctionArgs">,
"such as whether the parameter of isalpha is in the range [0, 255] "
"or is EOF.">,
Dependencies<[StdCLibraryFunctionsChecker]>,
- WeakDependencies<[NonNullParamChecker]>,
+ WeakDependencies<[CallAndMessageChecker, NonNullParamChecker, StreamChecker]>,
Documentation<NotDocumented>;
} // end "alpha.unix"
diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c
index 7c00e78c16ac..bef786a1a59b 100644
--- a/clang/test/Analysis/analyzer-enabled-checkers.c
+++ b/clang/test/Analysis/analyzer-enabled-checkers.c
@@ -6,11 +6,11 @@
// CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List
// CHECK-EMPTY:
-// CHECK-NEXT: core.CallAndMessageModeling
// CHECK-NEXT: apiModeling.StdCLibraryFunctions
// CHECK-NEXT: apiModeling.TrustNonnull
// CHECK-NEXT: apiModeling.llvm.CastValue
// CHECK-NEXT: apiModeling.llvm.ReturnValue
+// CHECK-NEXT: core.CallAndMessageModeling
// CHECK-NEXT: core.CallAndMessage
// CHECK-NEXT: core.DivideZero
// CHECK-NEXT: core.DynamicTypePropagation
diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
new file mode 100644
index 000000000000..9ad1be053851
--- /dev/null
+++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c
@@ -0,0 +1,66 @@
+// Here we test the order of the Checkers when StdCLibraryFunctionArgs is
+// enabled.
+
+// RUN: %clang --analyze %s --target=x86_64-pc-linux-gnu \
+// RUN: -Xclang -analyzer-checker=core \
+// RUN: -Xclang -analyzer-checker=apiModeling.StdCLibraryFunctions \
+// RUN: -Xclang -analyzer-config \
+// RUN: -Xclang apiModeling.StdCLibraryFunctions:ModelPOSIX=true \
+// RUN: -Xclang -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
+// RUN: -Xclang -analyzer-checker=alpha.unix.Stream \
+// RUN: -Xclang -analyzer-list-enabled-checkers \
+// RUN: -Xclang -analyzer-display-progress \
+// RUN: 2>&1 | FileCheck %s --implicit-check-not=ANALYZE \
+// RUN: --implicit-check-not=\.
+
+// CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List
+// CHECK-EMPTY:
+// CHECK-NEXT: core.CallAndMessageModeling
+// CHECK-NEXT: core.CallAndMessage
+// CHECK-NEXT: core.NonNullParamChecker
+// CHECK-NEXT: alpha.unix.Stream
+// CHECK-NEXT: apiModeling.StdCLibraryFunctions
+// CHECK-NEXT: alpha.unix.StdCLibraryFunctionArgs
+// CHECK-NEXT: apiModeling.TrustNonnull
+// CHECK-NEXT: apiModeling.llvm.CastValue
+// CHECK-NEXT: apiModeling.llvm.ReturnValue
+// CHECK-NEXT: core.DivideZero
+// CHECK-NEXT: core.DynamicTypePropagation
+// CHECK-NEXT: core.NonnilStringConstants
+// CHECK-NEXT: core.NullDereference
+// CHECK-NEXT: core.StackAddrEscapeBase
+// CHECK-NEXT: core.StackAddressEscape
+// CHECK-NEXT: core.UndefinedBinaryOperatorResult
+// CHECK-NEXT: core.VLASize
+// CHECK-NEXT: core.builtin.BuiltinFunctions
+// CHECK-NEXT: core.builtin.NoReturnFunctions
+// CHECK-NEXT: core.uninitialized.ArraySubscript
+// CHECK-NEXT: core.uninitialized.Assign
+// CHECK-NEXT: core.uninitialized.Branch
+// CHECK-NEXT: core.uninitialized.CapturedBlockVariable
+// CHECK-NEXT: core.uninitialized.UndefReturn
+// CHECK-NEXT: deadcode.DeadStores
+// CHECK-NEXT: nullability.NullabilityBase
+// CHECK-NEXT: nullability.NullPassedToNonnull
+// CHECK-NEXT: nullability.NullReturnedFromNonnull
+// CHECK-NEXT: security.insecureAPI.SecuritySyntaxChecker
+// CHECK-NEXT: security.insecureAPI.UncheckedReturn
+// CHECK-NEXT: security.insecureAPI.getpw
+// CHECK-NEXT: security.insecureAPI.gets
+// CHECK-NEXT: security.insecureAPI.mkstemp
+// CHECK-NEXT: security.insecureAPI.mktemp
+// CHECK-NEXT: security.insecureAPI.vfork
+// CHECK-NEXT: unix.API
+// CHECK-NEXT: unix.cstring.CStringModeling
+// CHECK-NEXT: unix.DynamicMemoryModeling
+// CHECK-NEXT: unix.Malloc
+// CHECK-NEXT: unix.MallocSizeof
+// CHECK-NEXT: unix.MismatchedDeallocator
+// CHECK-NEXT: unix.Vfork
+// CHECK-NEXT: unix.cstring.BadSizeArg
+// CHECK-NEXT: unix.cstring.NullArg
+
+int main() {
+ int i;
+ (void)(10 / i);
+}
diff --git a/clang/test/Analysis/std-c-library-functions-arg-weakdeps.c b/clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
new file mode 100644
index 000000000000..0ad3c277dfd7
--- /dev/null
+++ b/clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
@@ -0,0 +1,64 @@
+// Check that the more specific checkers report and not the generic
+// StdCLibraryFunctionArgs checker.
+
+// RUN: %clang_analyze_cc1 %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
+// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true \
+// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
+// RUN: -analyzer-checker=alpha.unix.Stream \
+// RUN: -triple x86_64-unknown-linux-gnu \
+// RUN: -verify
+
+
+// Make sure that all used functions have their summary loaded.
+
+// RUN: %clang_analyze_cc1 %s \
+// RUN: -analyzer-checker=core \
+// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \
+// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:ModelPOSIX=true \
+// RUN: -analyzer-checker=alpha.unix.StdCLibraryFunctionArgs \
+// RUN: -analyzer-checker=alpha.unix.Stream \
+// RUN: -analyzer-config apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries=true \
+// RUN: -triple x86_64-unknown-linux 2>&1 | FileCheck %s
+
+// CHECK: Loaded summary for: int isalnum(int)
+// CHECK: Loaded summary for: unsigned long fread(void *restrict, size_t, size_t, FILE *restrict) __attribute__((nonnull(1)))
+// CHECK: Loaded summary for: int fileno(FILE *stream)
+
+void initializeSummaryMap();
+// We analyze this function first, and the call expression inside initializes
+// the summary map. This way we force the loading of the summaries. The
+// summaries would not be loaded without this because during the first bug
+// report in WeakDependency::checkPreCall we stop further evaluation. And
+// StdLibraryFunctionsChecker lazily initializes its summary map from its
+// checkPreCall.
+void analyzeThisFirst() {
+ initializeSummaryMap();
+}
+
+typedef __typeof(sizeof(int)) size_t;
+struct FILE;
+typedef struct FILE FILE;
+
+int isalnum(int);
+size_t fread(void *restrict, size_t, size_t, FILE *restrict) __attribute__((nonnull(1)));
+int fileno(FILE *stream);
+
+void test_uninit_arg() {
+ int v;
+ int r = isalnum(v); // \
+ // expected-warning{{1st function call argument is an uninitialized value [core.CallAndMessage]}}
+ (void)r;
+}
+
+void test_notnull_arg(FILE *F) {
+ int *p = 0;
+ fread(p, sizeof(int), 5, F); // \
+ expected-warning{{Null pointer passed to 1st parameter expecting 'nonnull' [core.NonNullParamChecker]}}
+}
+
+void test_notnull_stream_arg() {
+ fileno(0); // \
+ // expected-warning{{Stream pointer might be NULL [alpha.unix.Stream]}}
+}
More information about the cfe-commits
mailing list