[PATCH] D74473: [analyzer] StdLibraryFunctionsChecker: Use platform dependent EOF and UCharMax
Kristóf Umann via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 12 06:04:11 PST 2020
Szelethus requested changes to this revision.
Szelethus added inline comments.
This revision now requires changes to proceed.
================
Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h:67-69
+/// Try to parse the value of a defined preprocessor macro. We can only parse
+/// simple expressions that consist of an optional minus sign token and then a
+/// token for an integer. If we cannot parse the value then None is returned.
----------------
While I agree that we shouldn't have to reinvent the `Preprocessor` every time we need something macro related, I doubt that this will catch anything. I checker my system's standard library, and this is what I found:
```lang=c
#ifndef EOF
# define EOF (-1)
#endif
```
Lets go just one step further and cover the probably majority of the cases where the definition is in parentheses.
================
Comment at: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:512-517
+ const auto EOFv = [&C]() -> RangeInt {
+ if (const llvm::Optional<int> OptInt =
+ TryExpandAsInteger("EOF", C.getPreprocessor()))
+ return *OptInt;
+ return -1;
+ }();
----------------
Hah, would've never thought of doing this with a lambda. Me likey.
================
Comment at: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:571
+ .Case(
+ {ReturnValueCondition(WithinRange, {{EOFv, EOFv}, {0, UCharMax}})});
};
----------------
Huh, what's happening here exactly? Doesn't `Range` take 2 `RangeInt`s as ctor arguments? What does `{EOFv, EOFv}, {0, UCharMax}` mean in this context?
================
Comment at: clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp:114-117
+ const auto MacroIt = llvm::find_if(
+ PP.macros(), [&](const auto &K) { return K.first->getName() == Macro; });
+ if (MacroIt == PP.macro_end())
+ return llvm::None;
----------------
This seems a bit clunky even for the `Preprocessor` -- how about
```lang=c++
const auto *MacroII = PP.getIdentifierInfo(Macro);
if (!MacroII)
return;
const MacroInfo *MI = PP.getMacroInfo(MacroII);
assert(MI);
```
================
Comment at: clang/test/Analysis/std-c-library-functions-eof.c:24
+ if (y < 0) {
+ clang_analyzer_eval(y == EOF); // expected-warning{{TRUE}}
+ }
----------------
So the test is about checking whether the analyzer correctly assigned `-2` to `y`, right? Then let's check that too.
```lang=c++
clang_analyzer_eval(y == 2);
```
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D74473/new/
https://reviews.llvm.org/D74473
More information about the cfe-commits
mailing list