diff options
author | Balázs Kéri <1.int32@gmail.com> | 2023-05-17 08:50:23 +0200 |
---|---|---|
committer | Balázs Kéri <balazs.keri@ericsson.com> | 2023-05-17 09:34:05 +0200 |
commit | 6012cadc400f4400c97e00da268de17e94a3f5dc (patch) | |
tree | 0ba7623befe939b62bd023e2071d4b595488a578 /clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp | |
parent | 11081a6a1dd7195fb8285e361873e706d6fb6e69 (diff) | |
download | llvm-6012cadc400f4400c97e00da268de17e94a3f5dc.zip llvm-6012cadc400f4400c97e00da268de17e94a3f5dc.tar.gz llvm-6012cadc400f4400c97e00da268de17e94a3f5dc.tar.bz2 |
[clang][analyzer] Display buffer sizes in StdCLibraryFunctionArgs checker
If a wrong (too small) buffer argument is found, the dynamic buffer size and
values of connected arguments are displayed in the warning message, if
these are simple known integer values.
Reviewed By: Szelethus
Differential Revision: https://reviews.llvm.org/D149321
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index ef85d60..1d6f97f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -105,6 +105,11 @@ class StdLibraryFunctionsChecker /// Get a string representation of an argument index. /// E.g.: (1) -> '1st arg', (2) - > '2nd arg' static void printArgDesc(ArgNo, llvm::raw_ostream &Out); + /// Print value X of the argument in form " (which is X)", + /// if the value is a fixed known value, otherwise print nothing. + /// This is used as simple explanation of values if possible. + static void printArgValueInfo(ArgNo ArgN, ProgramStateRef State, + const CallEvent &Call, llvm::raw_ostream &Out); /// Append textual description of a numeric range [RMin,RMax] to /// \p Out. static void appendInsideRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax, @@ -435,6 +440,10 @@ class StdLibraryFunctionsChecker ProgramStateRef State, const Summary &Summary, llvm::raw_ostream &Out) const override; + bool describeArgumentValue(const CallEvent &Call, ProgramStateRef State, + const Summary &Summary, + llvm::raw_ostream &Out) const override; + std::vector<ArgNo> getArgsToTrack() const override { std::vector<ArgNo> Result{ArgN}; if (SizeArgN) @@ -870,6 +879,16 @@ void StdLibraryFunctionsChecker::printArgDesc( Out << " argument"; } +void StdLibraryFunctionsChecker::printArgValueInfo(ArgNo ArgN, + ProgramStateRef State, + const CallEvent &Call, + llvm::raw_ostream &Out) { + if (const llvm::APSInt *Val = + State->getStateManager().getSValBuilder().getKnownValue( + State, getArgSVal(Call, ArgN))) + Out << " (which is " << *Val << ")"; +} + void StdLibraryFunctionsChecker::appendInsideRangeDesc(llvm::APSInt RMin, llvm::APSInt RMax, QualType ArgT, @@ -1179,13 +1198,29 @@ void StdLibraryFunctionsChecker::BufferSizeConstraint::describe( } else if (SizeArgN) { Out << "the value of the "; printArgDesc(*SizeArgN, Out); + printArgValueInfo(*SizeArgN, State, Call, Out); if (SizeMultiplierArgN) { Out << " times the "; printArgDesc(*SizeMultiplierArgN, Out); + printArgValueInfo(*SizeMultiplierArgN, State, Call, Out); } } } +bool StdLibraryFunctionsChecker::BufferSizeConstraint::describeArgumentValue( + const CallEvent &Call, ProgramStateRef State, const Summary &Summary, + llvm::raw_ostream &Out) const { + SVal BufV = getArgSVal(Call, getArgNo()); + SVal BufDynSize = getDynamicExtentWithOffset(State, BufV); + if (const llvm::APSInt *Val = + State->getStateManager().getSValBuilder().getKnownValue(State, + BufDynSize)) { + Out << "is a buffer with size " << *Val; + return true; + } + return false; +} + void StdLibraryFunctionsChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { std::optional<Summary> FoundSummary = findFunctionSummary(Call, C); |