[clang] [CIR] CompoundLiteralExpr for Aggregate types (PR #164172)

via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 19 11:28:30 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

<details>
<summary>Changes</summary>

Upstream support the CompoundLiteralExpr for Aggregate types

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


3 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp (+29-3) 
- (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+2) 
- (modified) clang/test/CIR/CodeGen/struct.cpp (+19) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 901b937e4e3e7..1a4114d009ffe 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -180,9 +180,35 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
     cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitStringLiteral");
   }
   void VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
-    cgf.cgm.errorNYI(e->getSourceRange(),
-                     "AggExprEmitter: VisitCompoundLiteralExpr");
+    if (dest.isPotentiallyAliased() &&
+        e->getType().isPODType(cgf.getContext())) {
+      cgf.cgm.errorNYI(e->getSourceRange(),
+                       "AggExprEmitter: VisitCompoundLiteralExpr PODType");
+      return;
+    }
+
+    AggValueSlot slot =
+        ensureSlot(cgf.getLoc(e->getSourceRange()), e->getType());
+
+    // Block-scope compound literals are destroyed at the end of the enclosing
+    // scope in C.
+    bool destruct =
+        !cgf.getLangOpts().CPlusPlus && !slot.isExternallyDestructed();
+    if (destruct) {
+      cgf.cgm.errorNYI(
+          e->getSourceRange(),
+          "AggExprEmitter: VisitCompoundLiteralExpr setExternallyDestructed");
+      return;
+    }
+
+    cgf.emitAggExpr(e->getInitializer(), slot);
+
+    if (destruct && e->getType().isDestructedType())
+      cgf.cgm.errorNYI(
+          e->getSourceRange(),
+          "AggExprEmitter: VisitCompoundLiteralExpr destructed type");
   }
+
   void VisitPredefinedExpr(const PredefinedExpr *e) {
     cgf.cgm.errorNYI(e->getSourceRange(),
                      "AggExprEmitter: VisitPredefinedExpr");
@@ -550,7 +576,7 @@ void AggExprEmitter::emitNullInitializationToLValue(mlir::Location loc,
       return;
     }
 
-    cgf.cgm.errorNYI("emitStoreThroughBitfieldLValue");
+    cgf.emitStoreThroughBitfieldLValue(RValue::get(null), lv);
     return;
   }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h
index c05142e9853ba..f83a952d26065 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -390,6 +390,8 @@ class AggValueSlot {
 
   IsZeroed_t isZeroed() const { return IsZeroed_t(zeroedFlag); }
 
+  IsAliased_t isPotentiallyAliased() const { return IsAliased_t(aliasedFlag); }
+
   RValue asRValue() const {
     if (isIgnored())
       return RValue::getIgnored();
diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp
index 263799f8a5deb..9ec8849602a56 100644
--- a/clang/test/CIR/CodeGen/struct.cpp
+++ b/clang/test/CIR/CodeGen/struct.cpp
@@ -280,3 +280,22 @@ void bin_comma() {
 // OGCG: define{{.*}} void @_Z9bin_commav()
 // OGCG:   %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
 // OGCG:   call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)
+
+void compound_literal_expr() { CompleteS a = (CompleteS){}; }
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a", init]
+// CIR: %[[A_ELEM_0_PTR:.*]] = cir.get_member %[[A_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
+// CIR: cir.store{{.*}} %[[CONST_0]], %[[A_ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[A_ELEM_1_PTR:.*]] = cir.get_member %[[A_ADDR]][1] {name = "b"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s8i
+// CIR: cir.store{{.*}} %[[CONST_0]], %[[A_ELEM_1_PTR]] : !s8i, !cir.ptr<!s8i>
+
+// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
+// LLVM: %[[A_ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 0
+// LLVM: store i32 0, ptr %[[A_ELEM_0_PTR]], align 4
+// LLVM: %[[A_ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 1
+// LLVM: store i8 0, ptr %[[A_ELEM_1_PTR]], align 4
+
+// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
+// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)

``````````

</details>


https://github.com/llvm/llvm-project/pull/164172


More information about the cfe-commits mailing list