diff options
author | YexuanXiao <bizwen@nykz.org> | 2025-07-18 09:45:57 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-17 22:45:57 -0300 |
commit | c27e283cfbca2bd22f34592430e98ee76ed60ad8 (patch) | |
tree | 5f8e23eeadff53a72e3871720737c84771dcbc2c /clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | |
parent | baa291bfb58e73a253669b86ac604cf8e6792b6c (diff) | |
download | llvm-c27e283cfbca2bd22f34592430e98ee76ed60ad8.zip llvm-c27e283cfbca2bd22f34592430e98ee76ed60ad8.tar.gz llvm-c27e283cfbca2bd22f34592430e98ee76ed60ad8.tar.bz2 |
[Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar types instead of built-in types (#143653)
Including the results of `sizeof`, `sizeof...`, `__datasizeof`,
`__alignof`, `_Alignof`, `alignof`, `_Countof`, `size_t` literals, and
signed `size_t` literals, the results of pointer-pointer subtraction and
checks for standard library functions (and their calls).
The goal is to enable clang and downstream tools such as clangd and
clang-tidy to provide more portable hints and diagnostics.
The previous discussion can be found at #136542.
This PR implements this feature by introducing a new subtype of `Type`
called `PredefinedSugarType`, which was considered appropriate in
discussions. I tried to keep `PredefinedSugarType` simple enough yet not
limited to `size_t` and `ptrdiff_t` so that it can be used for other
purposes. `PredefinedSugarType` wraps a canonical `Type` and provides a
name, conceptually similar to a compiler internal `TypedefType` but
without depending on a `TypedefDecl` or a source file.
Additionally, checks for the `z` and `t` format specifiers in format
strings for `scanf` and `printf` were added. It will precisely match
expressions using `typedef`s or built-in expressions.
The affected tests indicates that it works very well.
Several code require that `SizeType` is canonical, so I kept `SizeType`
to its canonical form.
The failed tests in CI are allowed to fail. See the
[comment](https://github.com/llvm/llvm-project/pull/135386#issuecomment-3049426611)
in another PR #135386.
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 30a0497..68efdba 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1281,7 +1281,7 @@ SVal MallocChecker::evalMulForBufferSize(CheckerContext &C, const Expr *Blocks, SVal BlockBytesVal = C.getSVal(BlockBytes); ProgramStateRef State = C.getState(); SVal TotalSize = SB.evalBinOp(State, BO_Mul, BlocksVal, BlockBytesVal, - SB.getContext().getSizeType()); + SB.getContext().getCanonicalSizeType()); return TotalSize; } @@ -1311,11 +1311,9 @@ static bool isStandardRealloc(const CallEvent &Call) { const FunctionDecl *FD = dyn_cast<FunctionDecl>(Call.getDecl()); assert(FD); ASTContext &AC = FD->getASTContext(); - - return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy && - FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy && - FD->getParamDecl(1)->getType().getDesugaredType(AC) == - AC.getSizeType(); + return AC.hasSameType(FD->getDeclaredReturnType(), AC.VoidPtrTy) && + AC.hasSameType(FD->getParamDecl(0)->getType(), AC.VoidPtrTy) && + AC.hasSameType(FD->getParamDecl(1)->getType(), AC.getSizeType()); } static bool isGRealloc(const CallEvent &Call) { @@ -1323,10 +1321,9 @@ static bool isGRealloc(const CallEvent &Call) { assert(FD); ASTContext &AC = FD->getASTContext(); - return FD->getDeclaredReturnType().getDesugaredType(AC) == AC.VoidPtrTy && - FD->getParamDecl(0)->getType().getDesugaredType(AC) == AC.VoidPtrTy && - FD->getParamDecl(1)->getType().getDesugaredType(AC) == - AC.UnsignedLongTy; + return AC.hasSameType(FD->getDeclaredReturnType(), AC.VoidPtrTy) && + AC.hasSameType(FD->getParamDecl(0)->getType(), AC.VoidPtrTy) && + AC.hasSameType(FD->getParamDecl(1)->getType(), AC.UnsignedLongTy); } void MallocChecker::checkRealloc(ProgramStateRef State, const CallEvent &Call, @@ -2830,10 +2827,10 @@ MallocChecker::ReallocMemAux(CheckerContext &C, const CallEvent &Call, return nullptr; // Compare the size argument to 0. - DefinedOrUnknownSVal SizeZero = - svalBuilder.evalEQ(State, TotalSize.castAs<DefinedOrUnknownSVal>(), - svalBuilder.makeIntValWithWidth( - svalBuilder.getContext().getSizeType(), 0)); + DefinedOrUnknownSVal SizeZero = svalBuilder.evalEQ( + State, TotalSize.castAs<DefinedOrUnknownSVal>(), + svalBuilder.makeIntValWithWidth( + svalBuilder.getContext().getCanonicalSizeType(), 0)); ProgramStateRef StatePtrIsNull, StatePtrNotNull; std::tie(StatePtrIsNull, StatePtrNotNull) = State->assume(PtrEQ); |