Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue a warning on packed record member access #800

Merged
merged 6 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/aro/Diagnostics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub const Message = struct {

pub const Extra = union {
str: []const u8,
record_member: struct {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the Extra union 32 bytes instead of 16 (on a 64-bit system). We should use something like what is done in errDeprecated or valueChangedStr - write the string to p.strings, dupe it, and then just use the .str Extra field

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

record: []const u8,
member: []const u8,
},
tok_id: struct {
expected: Tree.Token.Id,
actual: Tree.Token.Id,
Expand Down Expand Up @@ -219,6 +223,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 Expand Up @@ -392,6 +397,7 @@ pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
const prop = msg.tag.property();
switch (prop.extra) {
.str => printRt(m, prop.msg, .{"{s}"}, .{msg.extra.str}),
.record_member => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{ msg.extra.record_member.member, msg.extra.record_member.record }),
.tok_id => printRt(m, prop.msg, .{ "{s}", "{s}" }, .{
msg.extra.tok_id.expected.symbol(),
msg.extra.tok_id.actual.symbol(),
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}' of class or structure '{s}' may result in an unaligned pointer value"
.opt = W("address-of-packed-member")
.kind = .warning
.extra = .record_member
9 changes: 9 additions & 0 deletions src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7211,6 +7211,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 +7222,14 @@ 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.getAttribute(.@"packed") != null) {
const record = lhs_ty.getRecord().?;
const mapper = p.comp.string_interner.getSlowTypeMapper();
const extra = Diagnostics.Message.Extra{ .record_member = .{ .record = mapper.lookup(record.name), .member = mapper.lookup(record.fields[data.member.index].name) } };
try p.errExtra(.packed_member_address, orig_tok_i, extra);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the errStr function here with the string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}
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
Loading