aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2025-06-25 12:20:35 -0600
committerGitHub <noreply@github.com>2025-06-25 11:20:35 -0700
commit3b90597c2ceaae86608214f6b62b43e55823102b (patch)
tree3c8c3d739d99734bee8bc6bd5ed9d82d5b2d65bc /llvm/lib/IR/Verifier.cpp
parent487581b826a5339410aaf306eafedc7b806b25e3 (diff)
downloadllvm-3b90597c2ceaae86608214f6b62b43e55823102b.zip
llvm-3b90597c2ceaae86608214f6b62b43e55823102b.tar.gz
llvm-3b90597c2ceaae86608214f6b62b43e55823102b.tar.bz2
Non constant size and offset in DWARF (#141106)
In Ada, a record type can have a non-constant size, and a field can appear at a non-constant bit offset in a record. To support this, this patch changes DIType to record the size and offset using metadata, rather than plain integers. In addition to a constant offset, both DIVariable and DIExpression are now supported here. One thing of note in this patch is the choice of how exactly to represent a non-constant bit offset, with the difficulty being that DWARF 5 does not support this. DWARF 3 did have a way to support a non-constant byte offset, combined with a constant bit offset within the byte, but this was deprecated in DWARF 4 and removed from DWARF 5. This patch takes a simple approach: a DWARF extension allowing the use of an expression with DW_AT_data_bit_offset. There is a corresponding DWARF issue, see https://dwarfstd.org/issues/250501.1.html. The main reason for this approach is that it keeps API simplicity: just a single value is needed, rather than having separate data describing the byte offset and the bit within the byte.
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 70beb03..3e53ade 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1172,6 +1172,10 @@ void Verifier::visitDISubrangeType(const DISubrangeType &N) {
CheckDI(!Bias || isa<ConstantAsMetadata>(Bias) || isa<DIVariable>(Bias) ||
isa<DIExpression>(Bias),
"Bias must be signed constant or DIVariable or DIExpression", &N);
+ // Subrange types currently only support constant size.
+ auto *Size = N.getRawSizeInBits();
+ CheckDI(!Size || isa<ConstantAsMetadata>(Size),
+ "SizeInBits must be a constant");
}
void Verifier::visitDISubrange(const DISubrange &N) {
@@ -1233,6 +1237,10 @@ void Verifier::visitDIBasicType(const DIBasicType &N) {
N.getTag() == dwarf::DW_TAG_unspecified_type ||
N.getTag() == dwarf::DW_TAG_string_type,
"invalid tag", &N);
+ // Basic types currently only support constant size.
+ auto *Size = N.getRawSizeInBits();
+ CheckDI(!Size || isa<ConstantAsMetadata>(Size),
+ "SizeInBits must be a constant");
}
void Verifier::visitDIFixedPointType(const DIFixedPointType &N) {
@@ -1313,6 +1321,11 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
"DWARF address space only applies to pointer or reference types",
&N);
}
+
+ auto *Size = N.getRawSizeInBits();
+ CheckDI(!Size || isa<ConstantAsMetadata>(Size) || isa<DIVariable>(Size) ||
+ isa<DIExpression>(Size),
+ "SizeInBits must be a constant or DIVariable or DIExpression");
}
/// Detect mutually exclusive flags.
@@ -1400,6 +1413,11 @@ void Verifier::visitDICompositeType(const DICompositeType &N) {
if (N.getTag() == dwarf::DW_TAG_array_type) {
CheckDI(N.getRawBaseType(), "array types must have a base type", &N);
}
+
+ auto *Size = N.getRawSizeInBits();
+ CheckDI(!Size || isa<ConstantAsMetadata>(Size) || isa<DIVariable>(Size) ||
+ isa<DIExpression>(Size),
+ "SizeInBits must be a constant or DIVariable or DIExpression");
}
void Verifier::visitDISubroutineType(const DISubroutineType &N) {