martong updated this revision to Diff 260687.
martong added a comment.

- Handle and test the display of signatures


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78118/new/

https://reviews.llvm.org/D78118

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  clang/test/Analysis/analyzer-config.c
  clang/test/Analysis/std-c-library-functions.c

Index: clang/test/Analysis/std-c-library-functions.c
===================================================================
--- clang/test/Analysis/std-c-library-functions.c
+++ clang/test/Analysis/std-c-library-functions.c
@@ -30,6 +30,35 @@
 // RUN:   -triple thumbv7-a15-linux \
 // RUN:   -verify
 
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=apiModeling.StdCLibraryFunctions \
+// RUN:   -analyzer-config apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries=true \
+// RUN:   -analyzer-checker=debug.ExprInspection \
+// RUN:   -analyzer-config eagerly-assume=false \
+// RUN:   -triple i686-unknown-linux 2>&1 | FileCheck %s
+
+// CHECK: Loaded summary for int isalnum(int)
+// CHECK-NEXT: Loaded summary for int isalpha(int)
+// CHECK-NEXT: Loaded summary for int isascii(int)
+// CHECK-NEXT: Loaded summary for int isblank(int)
+// CHECK-NEXT: Loaded summary for int isdigit(int)
+// CHECK-NEXT: Loaded summary for int isgraph(int)
+// CHECK-NEXT: Loaded summary for int islower(int)
+// CHECK-NEXT: Loaded summary for int isprint(int)
+// CHECK-NEXT: Loaded summary for int ispunct(int)
+// CHECK-NEXT: Loaded summary for int isspace(int)
+// CHECK-NEXT: Loaded summary for int isupper(int)
+// CHECK-NEXT: Loaded summary for int isxdigit(int)
+// CHECK-NEXT: Loaded summary for int getc(FILE *)
+// CHECK-NEXT: Loaded summary for int fgetc(FILE *)
+// CHECK-NEXT: Loaded summary for int getchar(void)
+// CHECK-NEXT: Loaded summary for ssize_t read(int, void *, size_t)
+// CHECK-NEXT: Loaded summary for ssize_t write(int, const void *, size_t)
+// CHECK-NEXT: Loaded summary for size_t fread(void *restrict, size_t, size_t, FILE *)
+// CHECK-NEXT: Loaded summary for size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict)
+// CHECK-NEXT: Loaded summary for ssize_t getline(char **, size_t *, FILE *)
+
 void clang_analyzer_eval(int);
 
 int glob;
Index: clang/test/Analysis/analyzer-config.c
===================================================================
--- clang/test/Analysis/analyzer-config.c
+++ clang/test/Analysis/analyzer-config.c
@@ -11,6 +11,7 @@
 // CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtExec = 0x04
 // CHECK-NEXT: alpha.security.MmapWriteExec:MmapProtRead = 0x01
 // CHECK-NEXT: alpha.security.taint.TaintPropagation:Config = ""
+// CHECK-NEXT: apiModeling.StdCLibraryFunctions:DisplayLoadedSummaries = false
 // CHECK-NEXT: apply-fixits = false
 // CHECK-NEXT: avoid-suppressing-null-argument-paths = false
 // CHECK-NEXT: c++-allocator-inlining = true
@@ -106,4 +107,4 @@
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 103
+// CHECK-NEXT: num-entries = 104
Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -300,6 +300,8 @@
   DefaultBool ChecksEnabled[CK_NumCheckKinds];
   CheckerNameRef CheckNames[CK_NumCheckKinds];
 
+  bool DisplayLoadedSummaries = false;
+
 private:
   Optional<Summary> findFunctionSummary(const FunctionDecl *FD,
                                         CheckerContext &C) const;
@@ -639,8 +641,28 @@
   struct AddToFunctionSummaryMap {
     const ASTContext &ACtx;
     FunctionSummaryMapType &Map;
-    AddToFunctionSummaryMap(const ASTContext &ACtx, FunctionSummaryMapType &FSM)
-        : ACtx(ACtx), Map(FSM) {}
+    bool DisplayLoadedSummaries;
+    AddToFunctionSummaryMap(const ASTContext &ACtx, FunctionSummaryMapType &FSM,
+                            bool DisplayLoadedSummaries)
+        : ACtx(ACtx), Map(FSM), DisplayLoadedSummaries(DisplayLoadedSummaries) {
+    }
+
+    // Get the declaration of a function proto as written in the source file.
+    StringRef ToString(const FunctionDecl *FD) {
+      const auto &SM = ACtx.getSourceManager();
+      const SourceRange &R = FD->getSourceRange();
+      if (!FD->hasBody() // We don't want to print the whole body, only the
+                         // prototype.
+          && R.isValid()) {
+        const auto Len = SM.getDecomposedSpellingLoc(R.getEnd()).second -
+                         SM.getDecomposedSpellingLoc(R.getBegin()).second +
+                         1; // End points to the last char in the location.
+        return StringRef(SM.getCharacterData(R.getBegin()), Len);
+      } else {
+        return FD->getIdentifier()->getName();
+      }
+    }
+
     // Add a summary to a FunctionDecl found by lookup. The lookup is performed
     // by the given Name, and in the global scope. The summary will be attached
     // to the found FunctionDecl only if the signatures match.
@@ -655,6 +677,8 @@
             auto Res = Map.insert({FD->getCanonicalDecl(), S});
             assert(Res.second && "Function already has a summary set!");
             (void)Res;
+            if (DisplayLoadedSummaries)
+              llvm::errs() << "Loaded summary for " << ToString(FD) << "\n";
             return;
           }
         }
@@ -665,7 +689,7 @@
       for (const Summary &S : Summaries)
         operator()(Name, S);
     }
-  } addToFunctionSummaryMap(ACtx, FunctionSummaryMap);
+  } addToFunctionSummaryMap(ACtx, FunctionSummaryMap, DisplayLoadedSummaries);
 
   // We are finally ready to define specifications for all supported functions.
   //
@@ -937,7 +961,10 @@
 }
 
 void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {
-  mgr.registerChecker<StdLibraryFunctionsChecker>();
+  auto *Checker = mgr.registerChecker<StdLibraryFunctionsChecker>();
+  Checker->DisplayLoadedSummaries =
+      mgr.getAnalyzerOptions().getCheckerBooleanOption(
+          Checker, "DisplayLoadedSummaries");
 }
 
 bool ento::shouldRegisterStdCLibraryFunctionsChecker(const CheckerManager &mgr) {
Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
===================================================================
--- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -293,6 +293,14 @@
 
 def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
   HelpText<"Improve modeling of the C standard library functions">,
+  CheckerOptions<[
+    CmdLineOption<Boolean,
+                  "DisplayLoadedSummaries",
+                  "If set to true, the checker displays the found summaries "
+                  "for the given translation unit.",
+                  "false",
+                  Released>
+  ]>,
   Documentation<NotDocumented>;
 
 def StdCLibraryFunctionArgsChecker : Checker<"StdCLibraryFunctionArgs">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to