Skip to content

Commit

Permalink
Issue a warning on packed record member access
Browse files Browse the repository at this point in the history
  • Loading branch information
wrongnull authored Nov 12, 2024
1 parent 8d01979 commit 7a40472
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/aro/Diagnostics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ pub const Options = struct {
@"shift-count-overflow": Kind = .default,
@"constant-conversion": Kind = .default,
@"sign-conversion": Kind = .default,
@"address-of-packed-member": Kind = .default,
nonnull: Kind = .default,
};

Expand Down
6 changes: 6 additions & 0 deletions src/aro/Diagnostics/messages.def
Original file line number Diff line number Diff line change
Expand Up @@ -2560,3 +2560,9 @@ subtract_pointers_zero_elem_size
.kind = .warning
.opt = W("pointer-arith")
.extra = .str

packed_member_address
.msg = "taking address of packed member '{s}"
.opt = W("address-of-packed-member")
.kind = .warning
.extra = .str
22 changes: 22 additions & 0 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7171,6 +7171,21 @@ fn computeOffset(p: *Parser, res: Result) !Value {
return p.computeOffsetExtra(res.node, &val);
}

fn packedMemberAccessStr(p: *Parser, record: StringId, member: StringId) ![]const u8 {
const strings_top = p.strings.items.len;
defer p.strings.items.len = strings_top;

var w = p.strings.writer();
const mapper = p.comp.string_interner.getSlowTypeMapper();

try w.writeAll(mapper.lookup(member));
try w.writeAll("' of class or structure '");
try w.writeAll(mapper.lookup(record));
try w.writeAll("' may result in an unaligned pointer value");

return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]);
}

/// unExpr
/// : (compoundLiteral | primaryExpr) suffixExpr*
/// | '&&' IDENTIFIER
Expand Down Expand Up @@ -7211,6 +7226,7 @@ fn unExpr(p: *Parser) Error!Result {
try p.err(.invalid_preproc_operator);
return error.ParsingFailed;
}
const orig_tok_i = p.tok_i;
p.tok_i += 1;
var operand = try p.castExpr();
try operand.expect(p);
Expand All @@ -7221,6 +7237,12 @@ fn unExpr(p: *Parser) Error!Result {
p.getNode(operand.node, .member_access_ptr_expr)) |member_node|
{
if (tree.isBitfield(member_node)) try p.errTok(.addr_of_bitfield, tok);
const data = p.nodes.items(.data)[@intFromEnum(member_node)];
const lhs_ty = p.nodes.items(.ty)[@intFromEnum(data.member.lhs)];
if (lhs_ty.hasAttribute(.@"packed")) {
const record = lhs_ty.getRecord().?;
try p.errStr(.packed_member_address, orig_tok_i, try p.packedMemberAccessStr(record.name, record.fields[data.member.index].name));
}
}
const operand_ty_valid = !operand.ty.is(.invalid);
if (!tree.isLval(operand.node) and operand_ty_valid) {
Expand Down
8 changes: 8 additions & 0 deletions test/cases/packed member address.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct __attribute__((packed)) Foo {
int x;
};
struct Foo foo;
int *p = &foo.x;


#define EXPECTED_ERRORS "packed member address.c:5:10: warning: taking address of packed member 'x' of class or structure 'Foo' may result in an unaligned pointer value [-Waddress-of-packed-member]"
2 changes: 2 additions & 0 deletions test/cases/relocations.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ void foo(void) {
#define EXPECTED_ERRORS "relocations.c:24:1: error: static assertion failed" \
"relocations.c:29:16: error: static_assert expression is not an integral constant expression" \
"relocations.c:30:16: error: static_assert expression is not an integral constant expression" \
"relocations.c:39:16: warning: taking address of packed member 'x' of class or structure 'Packed' may result in an unaligned pointer value [-Waddress-of-packed-member]" \
"relocations.c:39:28: warning: taking address of packed member 'y' of class or structure 'Packed' may result in an unaligned pointer value [-Waddress-of-packed-member]" \
"relocations.c:50:26: warning: subtraction of pointers to type 'union Empty' of zero size has undefined behavior [-Wpointer-arith]" \
"relocations.c:50:16: error: static_assert expression is not an integral constant expression" \
"relocations.c:60:20: error: static_assert expression is not an integral constant expression" \
Expand Down

0 comments on commit 7a40472

Please sign in to comment.