https://github.com/adams381 created 
https://github.com/llvm/llvm-project/pull/214074

`#cir.record_layout` carries `record_align`, which CIRGen fills from 
`ASTRecordLayout::getAlignment()` and consumers read as an `llvm::Align`.  That 
constructor asserts the value is a non-zero power of two, so hand-written CIR 
naming any other alignment aborted the tool rather than reporting a parse 
error.  A zero tripped the non-zero assert and a 3 tripped the power-of-two 
one, both inside `llvm::Align` with no indication of which attribute was at 
fault.

Verify the field where it is parsed.  Values CIRGen emits are already 
well-formed, so this only affects hand-written input.


>From 178fceb6f1ac77f20f85720b9376b22932c50f20 Mon Sep 17 00:00:00 2001
From: Adam Smith <[email protected]>
Date: Tue, 4 Aug 2026 13:56:58 -0700
Subject: [PATCH] [CIR] Verify record_align is a non-zero power of two

`#cir.record_layout` carries `record_align`, which CIRGen fills from
`ASTRecordLayout::getAlignment()` and consumers read as an `llvm::Align`.  That
constructor asserts the value is a non-zero power of two, so hand-written CIR
naming any other alignment aborted the tool rather than reporting a parse error.
A zero tripped the non-zero assert and a 3 tripped the power-of-two one, both
inside `llvm::Align` with no indication of which attribute was at fault.

Verify the field where it is parsed.  Values CIRGen emits are already
well-formed, so this only affects hand-written input.
---
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  |  2 ++
 clang/lib/CIR/Dialect/IR/CIRAttrs.cpp         | 16 ++++++++++++++++
 clang/test/CIR/IR/invalid-record-layout.cir   | 19 +++++++++++++++++++
 3 files changed, 37 insertions(+)
 create mode 100644 clang/test/CIR/IR/invalid-record-layout.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index a0fe997156a69..5042ec9ab05aa 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -169,6 +169,8 @@ def CIR_RecordLayoutAttr : CIR_Attr<"RecordLayout", 
"record_layout"> {
     `>`
   }];
 
+  let genVerifyDecl = 1;
+
   let canHaveIllegalCXXABIType = 0;
 }
 
diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp 
b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index 264e836718c81..48cedbb44a856 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -920,6 +920,22 @@ LogicalResult DynamicCastInfoAttr::verify(
 // RecordLayout lookup
 
//===----------------------------------------------------------------------===//
 
+LogicalResult
+RecordLayoutAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+                         cir::ArgPassingKind argPassingKind,
+                         bool hasTrivialDtor, uint64_t recordAlign) {
+  // record_align comes from ASTRecordLayout::getAlignment() and is consumed as
+  // an llvm::Align, which requires a non-zero power of two.  Reject anything
+  // else here so hand-written CIR gets a diagnostic instead of an assertion
+  // failure inside whichever pass reads the field.
+  if (recordAlign == 0)
+    return emitError() << "record_align must be non-zero";
+  if (!llvm::isPowerOf2_64(recordAlign))
+    return emitError() << "record_align must be a power of two, got "
+                       << recordAlign;
+  return success();
+}
+
 RecordLayoutAttr cir::getRecordLayout(mlir::ModuleOp module,
                                       mlir::StringAttr name) {
   auto dict = module->getAttrOfType<mlir::DictionaryAttr>(
diff --git a/clang/test/CIR/IR/invalid-record-layout.cir 
b/clang/test/CIR/IR/invalid-record-layout.cir
new file mode 100644
index 0000000000000..fa54ef6977acf
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-record-layout.cir
@@ -0,0 +1,19 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+module attributes {
+  cir.record_layouts = {
+    // expected-error @below {{record_align must be non-zero}}
+    S = #cir.record_layout<arg_passing_kind = can_pass_in_regs,
+                           has_trivial_dtor = true, record_align = 0>}
+} {
+}
+
+// -----
+
+module attributes {
+  cir.record_layouts = {
+    // expected-error @below {{record_align must be a power of two, got 3}}
+    S = #cir.record_layout<arg_passing_kind = can_pass_in_regs,
+                           has_trivial_dtor = true, record_align = 3>}
+} {
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to