[clang] [C2y] Implement WG14 N3369 and N3469 (_Countof) (PR #133125)
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 27 04:29:38 PDT 2025
================
@@ -14926,6 +14926,42 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
return false;
}
+ case UETT_CountOf: {
+ QualType Ty = E->getTypeOfArgument();
+ assert(Ty->isArrayType());
+
+ // We don't need to worry about array element qualifiers, so getting the
+ // unsafe array type is fine.
+ if (const auto *CAT =
+ dyn_cast<ConstantArrayType>(Ty->getAsArrayTypeUnsafe())) {
+ return Success(CAT->getSize(), E);
+ }
+
+ assert(!Ty->isConstantSizeType());
+
+ // If it's a variable-length array type, we need to check whether it is a
+ // multidimensional array. If so, we need to check the size expression of
+ // the VLA to see if it's a constant size. If so, we can return that value.
+ const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
+ assert(VAT);
+ if (VAT->getElementType()->isArrayType()) {
+ std::optional<APSInt> Res =
+ VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
+ if (Res) {
+ // The resulting value always has type size_t, so we need to make the
+ // returned APInt have the correct sign and bit-width.
+ APInt Val{
+ static_cast<unsigned>(Info.Ctx.getTypeSize(Info.Ctx.getSizeType())),
+ Res->getZExtValue()};
+ return Success(Val, E);
+ }
+ }
----------------
AaronBallman wrote:
See `test_constant_expression_behavior()`:
```
// Note that this applies to each array dimension.
int another_array[n][7];
static_assert(_Countof(another_array)); // expected-error {{static assertion expression is not an integral constant expression}}
static_assert(_Countof(*another_array) == 7);
// Only the first dimension is needed for constant evaluation; other
// dimensions can be ignored.
int yet_another_array[7][n];
static_assert(_Countof(yet_another_array) == 7);
static_assert(_Countof(*yet_another_array)); // expected-error {{static assertion expression is not an integral constant expression}}
```
Without this code, `static_assert(_Countof(yet_another_array) == 7);` would give an error that the assertion is not an ICE.
https://github.com/llvm/llvm-project/pull/133125
More information about the cfe-commits
mailing list