def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">,
HelpText<"Improve modeling of the C standard library functions">,
Dependencies<[NonNullParamChecker, CallAndMessageChecker]>,
+ 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">,
DefaultBool ChecksEnabled[CK_NumCheckKinds];
CheckerNameRef CheckNames[CK_NumCheckKinds];
+ bool DisplayLoadedSummaries = false;
+
private:
Optional<Summary> findFunctionSummary(const FunctionDecl *FD,
CheckerContext &C) const;
struct AddToFunctionSummaryMap {
const ASTContext &ACtx;
FunctionSummaryMapType ⤅
- 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) {
+ }
+
// 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.
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: ";
+ FD->print(llvm::errs());
+ llvm::errs() << "\n";
+ }
return;
}
}
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.
//
}
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) {
// 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
// CHECK-NEXT: unroll-loops = false
// CHECK-NEXT: widen-loops = false
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 103
+// CHECK-NEXT: num-entries = 104
// 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()
+// 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: unsigned int fread(void *restrict, size_t, size_t, FILE *)
+// CHECK-NEXT: Loaded summary for: unsigned int 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;