Skip to content

Conversation

HerrCai0907
Copy link
Contributor

fix: #151716

In #65918, support of incomplete array type is added in TryReferenceListInitialization. It causes the crash in Constant Expr Calculation since it only considers the case where it is ConstantArrayType.

This patch wants to add support for incomplete array type also.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Aug 23, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 23, 2025

@llvm/pr-subscribers-clang

Author: Congcong Cai (HerrCai0907)

Changes

fix: #151716

In #65918, support of incomplete array type is added in TryReferenceListInitialization. It causes the crash in Constant Expr Calculation since it only considers the case where it is ConstantArrayType.

This patch wants to add support for incomplete array type also.


Full diff: https://github.com/llvm/llvm-project/pull/155080.diff

2 Files Affected:

  • (modified) clang/lib/AST/ExprConstant.cpp (+8-4)
  • (modified) clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp (+15)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 9b934753bcc3c..301fc64f3f84f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4030,9 +4030,13 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
     if (ObjType->isArrayType()) {
       // Next subobject is an array element.
       const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(ObjType);
-      assert(CAT && "vla in literal type?");
+      const IncompleteArrayType *IAT =
+          Info.Ctx.getAsIncompleteArrayType(ObjType);
+      const ArrayType *AT = CAT ? static_cast<const ArrayType *>(CAT)
+                                : static_cast<const ArrayType *>(IAT);
+      assert(AT && "vla in literal type?");
       uint64_t Index = Sub.Entries[I].getAsArrayIndex();
-      if (CAT->getSize().ule(Index)) {
+      if (CAT && CAT->getSize().ule(Index)) {
         // Note, it should not be possible to form a pointer with a valid
         // designator which points more than one past the end of the array.
         if (Info.getLangOpts().CPlusPlus11)
@@ -4043,12 +4047,12 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
         return handler.failed();
       }
 
-      ObjType = CAT->getElementType();
+      ObjType = AT->getElementType();
 
       if (O->getArrayInitializedElts() > Index)
         O = &O->getArrayInitializedElt(Index);
       else if (!isRead(handler.AccessKind)) {
-        if (!CheckArraySize(Info, CAT, E->getExprLoc()))
+        if (CAT && !CheckArraySize(Info, CAT, E->getExprLoc()))
           return handler.failed();
 
         expandArray(*O, Index);
diff --git a/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp b/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp
index a29f4d720c1de..007b47c441b2f 100644
--- a/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp
+++ b/clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp
@@ -32,4 +32,19 @@ void foo(int a) {
   f({a});
 }
 
+constexpr int gh151716() {
+  int(&&g)[]{0,1,2};
+  return g[2];
+}
+// CHECK-LABEL: @_ZN3One10gh151716_fEv
+// CHECK-NEXT: entry:
+// CHECK-NEXT:   %v = alloca i32, align 4
+// CHECK-NEXT:   call void @llvm.lifetime.start.p0(ptr nonnull %v)
+// CHECK-NEXT:   store volatile i32 2, ptr %v, align 4
+// CHECK-NEXT:   call void @llvm.lifetime.end.p0(ptr nonnull %v)
+// CHECK-NEXT:   ret void
+void gh151716_f() {
+  volatile const int v = gh151716();
+}
+
 } // namespace One

Comment on lines 4035 to 4037
const ArrayType *AT = CAT ? static_cast<const ArrayType *>(CAT)
: static_cast<const ArrayType *>(IAT);
assert(AT && "vla in literal type?");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using getAsArrayType() and asserting the type is either ConstantArrayType or IncompleteArrayType would simplify that code a bit

…lation

In llvm#65918, support of incomplete array type is added in TryReferenceListInitialization.
It causes the crash in Constant Expr Calculation since it only considers the case where it is ConstantArrayType.

This patch wants to add support for incomplete array type also.
Comment on lines +4036 to +4037
if (isa<ConstantArrayType>(AT) &&
cast<ConstantArrayType>(AT)->getSize().ule(Index)) {
Copy link
Contributor

@Fznamznon Fznamznon Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isa and cast does isa two times. AFAIK llvm coding guide recommends to avoid that. Can we do everywhere

Suggested change
if (isa<ConstantArrayType>(AT) &&
cast<ConstantArrayType>(AT)->getSize().ule(Index)) {
if (auto *CAT = dyn_cast<ConstantArrayType>(AT); CAT && CAT->getSize().ule(Index)) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang] Assertion `CAT && "vla in literal type?"' failed.
4 participants