Skip to content

Commit fefdb49

Browse files
authored
[Clang] Fix Variable Length Array _Countof Crash (llvm#154627)
Check for missing VLA size expressions (e.g. in int a[*][10]) before evaluation to avoid crashes in _Countof and constant expression checks. Fixes llvm#152826
1 parent 5886a27 commit fefdb49

File tree

4 files changed

+23
-2
lines changed

4 files changed

+23
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ Bug Fixes in This Version
253253
-------------------------
254254
- Fix a crash when marco name is empty in ``#pragma push_macro("")`` or
255255
``#pragma pop_macro("")``. (#GH149762).
256+
- Fix a crash in variable length array (e.g. ``int a[*]``) function parameter type
257+
being used in ``_Countof`` expression. (#GH152826).
256258
- `-Wunreachable-code`` now diagnoses tautological or contradictory
257259
comparisons such as ``x != 0 || x != 1.0`` and ``x == 0 && x == 1.0`` on
258260
targets that treat ``_Float16``/``__fp16`` as native scalar types. Previously

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2248,7 +2248,9 @@ bool Compiler<Emitter>::VisitUnaryExprOrTypeTraitExpr(
22482248
assert(VAT);
22492249
if (VAT->getElementType()->isArrayType()) {
22502250
std::optional<APSInt> Res =
2251-
VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx);
2251+
VAT->getSizeExpr()
2252+
? VAT->getSizeExpr()->getIntegerConstantExpr(ASTCtx)
2253+
: std::nullopt;
22522254
if (Res) {
22532255
if (DiscardResult)
22542256
return true;

clang/lib/AST/ExprConstant.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15353,6 +15353,13 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
1535315353
const auto *VAT = Info.Ctx.getAsVariableArrayType(Ty);
1535415354
assert(VAT);
1535515355
if (VAT->getElementType()->isArrayType()) {
15356+
// Variable array size expression could be missing (e.g. int a[*][10]) In
15357+
// that case, it can't be a constant expression.
15358+
if (!VAT->getSizeExpr()) {
15359+
Info.FFDiag(E->getBeginLoc());
15360+
return false;
15361+
}
15362+
1535615363
std::optional<APSInt> Res =
1535715364
VAT->getSizeExpr()->getIntegerConstantExpr(Info.Ctx);
1535815365
if (Res) {
@@ -17890,7 +17897,10 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
1789017897
// it is an ICE or not.
1789117898
const auto *VAT = Ctx.getAsVariableArrayType(ArgTy);
1789217899
if (VAT->getElementType()->isArrayType())
17893-
return CheckICE(VAT->getSizeExpr(), Ctx);
17900+
// Variable array size expression could be missing (e.g. int a[*][10])
17901+
// In that case, it can't be a constant expression.
17902+
return VAT->getSizeExpr() ? CheckICE(VAT->getSizeExpr(), Ctx)
17903+
: ICEDiag(IK_NotICE, E->getBeginLoc());
1789417904

1789517905
// Otherwise, this is a regular VLA, which is definitely not an ICE.
1789617906
return ICEDiag(IK_NotICE, E->getBeginLoc());

clang/test/Sema/gh152826.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_cc1 -std=c2y -verify %s
2+
// RUN: %clang_cc1 -std=c2y -verify -fexperimental-new-constant-interpreter %s
3+
// expected-no-diagnostics
4+
5+
void gh152826(char (*a)[*][5], int (*x)[_Countof(*a)]);
6+
void more_likely_in_practice(unsigned long size_one, int (*a)[*][5], int b[_Countof(*a)]);
7+
void f(int (*x)[*][1][*][2][*][*][3][*], int q[_Countof(*x)]);

0 commit comments

Comments
 (0)