https://github.com/HerrCai0907 updated 
https://github.com/llvm/llvm-project/pull/155080

>From 00a2038a85eec59d263f756b85b8e0527266c500 Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0...@163.com>
Date: Sat, 23 Aug 2025 14:05:04 +0800
Subject: [PATCH 1/2] [clang][initlist] handle incomplete array type in
 Constant Expr Calculation

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.
---
 clang/lib/AST/ExprConstant.cpp                    | 12 ++++++++----
 clang/test/CodeGenCXX/cxx20-p0388-unbound-ary.cpp | 15 +++++++++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a71cb8b0143be..193e0c93781fb 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

>From 7ffd6693b8dde31b3b2e44099659138876bc3f4e Mon Sep 17 00:00:00 2001
From: Congcong Cai <congcongcai0...@163.com>
Date: Sat, 23 Aug 2025 19:12:36 +0800
Subject: [PATCH 2/2] fix review

---
 clang/lib/AST/ExprConstant.cpp | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 193e0c93781fb..859e5141f86dc 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -4029,14 +4029,11 @@ findSubobject(EvalInfo &Info, const Expr *E, const 
CompleteObject &Obj,
     LastField = nullptr;
     if (ObjType->isArrayType()) {
       // Next subobject is an array element.
-      const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(ObjType);
-      const IncompleteArrayType *IAT =
-          Info.Ctx.getAsIncompleteArrayType(ObjType);
-      const ArrayType *AT = CAT ? static_cast<const ArrayType *>(CAT)
-                                : static_cast<const ArrayType *>(IAT);
+      const ArrayType *AT = Info.Ctx.getAsArrayType(ObjType);
       assert(AT && "vla in literal type?");
       uint64_t Index = Sub.Entries[I].getAsArrayIndex();
-      if (CAT && CAT->getSize().ule(Index)) {
+      if (isa<ConstantArrayType>(AT) &&
+          cast<ConstantArrayType>(AT)->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)
@@ -4052,7 +4049,8 @@ findSubobject(EvalInfo &Info, const Expr *E, const 
CompleteObject &Obj,
       if (O->getArrayInitializedElts() > Index)
         O = &O->getArrayInitializedElt(Index);
       else if (!isRead(handler.AccessKind)) {
-        if (CAT && !CheckArraySize(Info, CAT, E->getExprLoc()))
+        if (isa<ConstantArrayType>(AT) &&
+            !CheckArraySize(Info, cast<ConstantArrayType>(AT), 
E->getExprLoc()))
           return handler.failed();
 
         expandArray(*O, Index);

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to