[PATCH] D86796: [Sema] Address-space sensitive index check for unbounded arrays
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 9 10:23:48 PDT 2020
aaron.ballman added a comment.
In D86796#2263557 <https://reviews.llvm.org/D86796#2263557>, @chrish_ericsson_atx wrote:
> Ping?
Sorry for the delayed review, but this managed to fall off my radar. Thank you for the ping!
================
Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:8841-8844
+def warn_array_index_exceeds_max_addressable_bounds : Warning<
+ "array index %0 refers past the last possible element for an array in %1-bit "
+ "address space containing %2-bit (%3-byte) elements (max possible %4 element%s5)">,
+ InGroup<ArrayBounds>;
----------------
I'd combine this with the above diagnostic given how similar they are:
```
def warn_exceeds_max_addressable_bounds : Warning<
"%select{array index %1|the pointer incremented by %1}0 refers past the last possible element for an array in %2-bit "
"address space containing %3-bit (%4-byte) elements (max possible %5 element%s6)">,
InGroup<ArrayBounds>;
```
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14043
+ ArrayTy == nullptr ? nullptr : ArrayTy->getElementType().getTypePtr();
+ bool isUnboundedArray = (BaseType == nullptr);
+ if (EffectiveType->isDependentType() ||
----------------
`IsUnboundedArray` per our usual coding style rules.
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14063
+ if (isUnboundedArray) {
+ if (index.isUnsigned() || !index.isNegative()) {
+ const auto &ASTC = getASTContext();
----------------
ebevhan wrote:
> This could be early return to avoid the indentation.
+1 to using early return here. I might even get rid of `isUnboundedArray` and just use `!BaseType`
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14071
+ CharUnits ElemBytes = ASTC.getTypeSizeInChars(EffectiveType);
+ llvm::APInt apElemBytes(index.getBitWidth(), ElemBytes.getQuantity());
+ // If index has more active bits than address space, we already know
----------------
`ElemBytes` per usual coding style rules.
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14077
+ if (index.getActiveBits() <= AddrBits) {
+ bool overflow;
+ llvm::APInt product(index);
----------------
`Overflow`, `Product` (I'll stop commenting on them -- just take a quick pass to make sure the new variables you introduce meet style rules.)
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14085
+
+ // Need to compute max possible elements in address space, since that
+ // is included in diag message.
----------------
since that -> since that
(removes a whitespace)
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14094-14096
+ unsigned DiagID = diag::warn_ptr_arith_exceeds_max_addressable_bounds;
+ if (ASE)
+ DiagID = diag::warn_array_index_exceeds_max_addressable_bounds;
----------------
```
unsigned DiagID = ASE ?
diag::warn_array_index_exceeds_max_addressable_bounds :
diag::warn_ptr_arith_exceeds_max_addressable_bounds;
```
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14100
+ // dependent CharUnits)
+ DiagRuntimeBehavior(BaseExpr->getBeginLoc(), BaseExpr,
+ PDiag(DiagID)
----------------
It's not clear to me whether we need to pay the extra expense of doing reachability checks for the diagnostic -- do you have evidence that there would be a high false positive rate if we always emit the diagnostic?
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14111
+ // Try harder to find a NamedDecl to point at in the note.
+ while (const ArraySubscriptExpr *ASE =
+ dyn_cast<ArraySubscriptExpr>(BaseExpr))
----------------
You can use `const auto *` here since the type is spelled out in the initialization. Same below.
================
Comment at: clang/lib/Sema/SemaChecking.cpp:14121
+ if (ND)
+ DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr,
+ PDiag(diag::note_array_declared_here) << ND);
----------------
Similar comment here about reachability.
================
Comment at: clang/test/Sema/const-eval.c:143
// expressions, like we do for integers.
-void *PR28739a = (__int128)(unsigned long)-1 + &PR28739a;
-void *PR28739b = &PR28739b + (__int128)(unsigned long)-1;
-__int128 PR28739c = (&PR28739c + (__int128)(unsigned long)-1) - &PR28739c;
-void *PR28739d = &(&PR28739d)[(__int128)(unsigned long)-1];
+void *PR28739a = (__int128)(unsigned long)-1 + &PR28739a; // expected-warning {{refers past the last possible element}}
+void *PR28739b = &PR28739b + (__int128)(unsigned long)-1; // expected-warning {{refers past the last possible element}}
----------------
You should spell out the full form of the diagnostic the first time it appears in a test. You can use the shortened form for subsequent diagnostics.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D86796/new/
https://reviews.llvm.org/D86796
More information about the cfe-commits
mailing list