[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