Fixed potential pinpoint segfault

This commit is contained in:
York Jasper Niebuhr 2026-04-05 13:38:11 +02:00
parent 81550e4ca0
commit 68f4ecd6ed
2 changed files with 21 additions and 23 deletions

View File

@ -62,6 +62,9 @@ std::list<DataPin::Component> compile_datapin_record_components(tree type) {
if (TREE_CODE(type) != RECORD_TYPE)
return components;
if (!COMPLETE_TYPE_P(type))
return components;
for (tree field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) {
if (TREE_CODE(field) != FIELD_DECL)
continue;
@ -69,8 +72,10 @@ std::list<DataPin::Component> compile_datapin_record_components(tree type) {
std::size_t field_offset;
bool field_bitfield;
if (!field_info(field, &field_offset, nullptr, nullptr, &field_bitfield))
pinpoint_fatal("compile_datapin_record_components failed to get field info");
if (!field_info(field, &field_offset, nullptr, nullptr, &field_bitfield)) {
// pinpoint_fatal("compile_datapin_record_components failed to get field info");
continue; // NOTE -> Happens e.g. on trailing arrays of dynamic size (allowed only in non-target structs)
}
if (field_bitfield)
continue;

View File

@ -135,45 +135,40 @@ const TargetType* TargetType::find(UID uid) {
return &it->second;
}
bool field_info(tree field_decl, std::size_t* offset, std::size_t* size, std::size_t* alignment, bool* bitfield) {
bool field_info(tree field_decl, std::size_t* offset, std::size_t* size,
std::size_t* alignment, bool* bitfield) {
if (!field_decl || TREE_CODE(field_decl) != FIELD_DECL)
return false;
HOST_WIDE_INT tmp_byte_offset = 0;
if (TREE_CODE(DECL_FIELD_OFFSET(field_decl)) == INTEGER_CST)
tmp_byte_offset = tree_to_uhwi(DECL_FIELD_OFFSET(field_decl));
else
tree field_off_t = DECL_FIELD_OFFSET(field_decl);
if (!field_off_t || TREE_CODE(field_off_t) != INTEGER_CST)
return false;
HOST_WIDE_INT tmp_bit_offset = 0;
if (TREE_CODE(DECL_FIELD_BIT_OFFSET(field_decl)) == INTEGER_CST)
tmp_bit_offset = tree_to_uhwi(DECL_FIELD_BIT_OFFSET(field_decl));
else
tree field_bit_off_t = DECL_FIELD_BIT_OFFSET(field_decl);
if (!field_bit_off_t || TREE_CODE(field_bit_off_t) != INTEGER_CST)
return false;
tree field_size_t = DECL_SIZE(field_decl);
if (!field_size_t || TREE_CODE(field_size_t) != INTEGER_CST)
return false;
HOST_WIDE_INT tmp_byte_offset = tree_to_uhwi(field_off_t);
HOST_WIDE_INT tmp_bit_offset = tree_to_uhwi(field_bit_off_t);
HOST_WIDE_INT tmp_bit_size = tree_to_uhwi(field_size_t);
HOST_WIDE_INT bit_offset_bytes = tmp_bit_offset / 8;
tmp_byte_offset += bit_offset_bytes;
tmp_bit_offset -= bit_offset_bytes * 8;
HOST_WIDE_INT tmp_bit_size = 0;
if (TREE_CODE(DECL_SIZE(field_decl)) == INTEGER_CST)
tmp_bit_size = tree_to_uhwi(DECL_SIZE(field_decl));
else
return false;
bool tmp_bitfield = (DECL_BIT_FIELD_TYPE(field_decl) != NULL_TREE);
tmp_bitfield |= !(tmp_bit_size % 8 == 0 && tmp_bit_offset == 0);
// Intra-byte offset counts towards size
tmp_bit_size += tmp_bit_offset;
// Round size up to entire byte
HOST_WIDE_INT tmp_bit_overhang = tmp_bit_size % 8;
if (tmp_bit_overhang != 0)
tmp_bit_size += (8 - tmp_bit_overhang);
// Alignment in bytes
HOST_WIDE_INT tmp_align_bits = DECL_ALIGN(field_decl);
if (tmp_align_bits <= 0 && TREE_TYPE(field_decl))
tmp_align_bits = TYPE_ALIGN(TREE_TYPE(field_decl));
@ -185,8 +180,6 @@ bool field_info(tree field_decl, std::size_t* offset, std::size_t* size, std::si
if (tmp_alignment == 0)
tmp_alignment = 1;
// Set all outputs
if (offset)
*offset = static_cast<std::size_t>(tmp_byte_offset);