[PATCH] D158707: [analyzer] Fix a few size-type signedness inconsistency related to DynamicExtent
Balázs Benics via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 28 06:31:19 PDT 2023
steakhal added a comment.
Oh, so we would canonicalize towards a signed extent type. I see. I think I'm okay with that.
However, I think this needs a little bit of polishing and testing when the region does not point to the beginning of an array or object, but rather inside an object, or like this:
int nums[] = {1,2,3};
char *p = (char*)&nums[1];
clang_analyzer_dumpExtent(p);
clang_analyzer_dumpElementCount(p);
++p;
clang_analyzer_dumpExtent(p);
clang_analyzer_dumpElementCount(p);
++p;
int *q = (int*)p;
clang_analyzer_dumpExtent(q);
clang_analyzer_dumpElementCount(q);
================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp:47-48
+ const MemRegion *MR) {
+ if (!MR)
+ return UnknownVal();
+ MR = MR->StripCasts();
----------------
I'd prefer hoisting this check to the callsite.
Usually, we assume `MR` is non-null. This is already the case for a sibling API, `getDynamicExtent()`.
Let's keep these "overloads" behave the same.
================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp:56-57
+ QualType Ty = TVR->getValueType();
+ if (const auto *ConstArrayTy =
+ dyn_cast_or_null<ConstantArrayType>(Ty->getAsArrayTypeUnsafe()))
+ return SVB.makeIntVal(ConstArrayTy->getSize(), false);
----------------
Funnily enough, one must use the `ASTContext::getAsConstantArrayType()` to achieve this.
I'm not sure why, but I was bitten by this.
It says something like this at the ASTContext:
```
/// Type Query functions. If the type is an instance of the specified class,
/// return the Type pointer for the underlying maximally pretty type. This
/// is a member of ASTContext because this may need to do some amount of
/// canonicalization, e.g. to move type qualifiers into the element type.
const ArrayType *getAsArrayType(QualType T) const;
const ConstantArrayType *getAsConstantArrayType(QualType T) const {
return dyn_cast_or_null<ConstantArrayType>(getAsArrayType(T));
}
```
================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp:58
+ dyn_cast_or_null<ConstantArrayType>(Ty->getAsArrayTypeUnsafe()))
+ return SVB.makeIntVal(ConstArrayTy->getSize(), false);
+
----------------
For bool literal arguments we usually use "named parameter passing", aka. `/*paramname=*/false` constructs.
================
Comment at: clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp:66-75
+ assert(!ElementSize.isZeroConstant() && "Non-zero element size expected");
+ if (Size.isUndef())
+ return UnknownVal();
+
+ SValBuilder &SVB = State->getStateManager().getSValBuilder();
+
+ auto ElementCount =
----------------
If `ElementSize` would be some symbol, constrained to null, we would pass the assertion, but still end up modeling a division by zero, resulting in `Undefined`, which then turned into `Unknown` - I see.
Looking at this, the assertion seems misleading as it won't protect the division.
That said, the early return on undef could be also dropped.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D158707/new/
https://reviews.llvm.org/D158707
More information about the cfe-commits
mailing list