[clang] [CIR] Verify record_align is a non-zero power of two (PR #214074)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 4 14:05:23 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Adam Smith (adams381)
<details>
<summary>Changes</summary>
`#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.
---
Full diff: https://github.com/llvm/llvm-project/pull/214074.diff
3 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+2)
- (modified) clang/lib/CIR/Dialect/IR/CIRAttrs.cpp (+16)
- (added) clang/test/CIR/IR/invalid-record-layout.cir (+19)
``````````diff
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>}
+} {
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/214074
More information about the cfe-commits
mailing list