V8 [PATCH] C/C++: Add -Waddress-of-packed-member
H.J. Lu
hjl.tools@gmail.com
Tue Dec 18 21:13:00 GMT 2018
On Tue, Dec 18, 2018 at 12:36 PM Jason Merrill <jason@redhat.com> wrote:
>
> On 12/18/18 9:10 AM, H.J. Lu wrote:
> > + switch (TREE_CODE (rhs))
> > + {
> > + case ADDR_EXPR:
> > + base = TREE_OPERAND (rhs, 0);
> > + while (handled_component_p (base))
> > + {
> > + if (TREE_CODE (base) == COMPONENT_REF)
> > + break;
> > + base = TREE_OPERAND (base, 0);
> > + }
> > + if (TREE_CODE (base) != COMPONENT_REF)
> > + return NULL_TREE;
> > + object = TREE_OPERAND (base, 0);
> > + field = TREE_OPERAND (base, 1);
> > + break;
> > + case COMPONENT_REF:
> > + object = TREE_OPERAND (rhs, 0);
> > + field = TREE_OPERAND (rhs, 1);
> > + break;
> > + default:
> > + return NULL_TREE;
> > + }
> > +
> > + tree context = check_alignment_of_packed_member (type, field);
> > + if (context)
> > + return context;
> > +
> > + /* Check alignment of the object. */
> > + while (TREE_CODE (object) == COMPONENT_REF)
> > + {
> > + field = TREE_OPERAND (object, 1);
> > + context = check_alignment_of_packed_member (type, field);
> > + if (context)
> > + return context;
> > + object = TREE_OPERAND (object, 0);
> > + }
> > +
>
> You can see interleaved COMPONENT_REF and ARRAY_REF that this still
> doesn't look like it will handle, something like
>
> struct A
> {
> int i;
> };
>
> struct B
> {
> char c;
> __attribute ((packed)) A ar[4];
> };
>
> B b;
>
> int *p = &b.ar[1].i;
>
> Rather than have a loop in the ADDR_EXPR case of the switch, you can
> handle everything in the lower loop. And not have a switch at all, just
> strip any ADDR_EXPR before the loop.
I changed it to
if (TREE_CODE (rhs) == ADDR_EXPR)
rhs = TREE_OPERAND (rhs, 0);
while (handled_component_p (rhs))
{
if (TREE_CODE (rhs) == COMPONENT_REF)
break;
rhs = TREE_OPERAND (rhs, 0);
}
if (TREE_CODE (rhs) != COMPONENT_REF)
return NULL_TREE;
object = TREE_OPERAND (rhs, 0);
field = TREE_OPERAND (rhs, 1);
[hjl@gnu-cfl-1 pr51628-6]$ cat a.i
struct A
{
int i;
} __attribute ((packed));
struct B
{
char c;
struct A ar[4];
};
struct B b;
int *p = &b.ar[1].i;
[hjl@gnu-cfl-1 pr51628-6]$ make a.s
/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/ -O2
-S a.i
a.i:14:10: warning: taking address of packed member of ‘struct A’ may
result in an unaligned pointer value [-Waddress-of-packed-member]
14 | int *p = &b.ar[1].i;
| ^~~~~~~~~~
[hjl@gnu-cfl-1 pr51628-6]$
> > +check_and_warn_address_of_packed_member (tree type, tree rhs)
> > +{
> > + if (TREE_CODE (rhs) != COND_EXPR)
> > + {
> > + tree context = check_address_of_packed_member (type, rhs);
> > + if (context)
> > + {
> > + location_t loc = EXPR_LOC_OR_LOC (rhs, input_location);
> > + warning_at (loc, OPT_Waddress_of_packed_member,
> > + "taking address of packed member of %qT may result "
> > + "in an unaligned pointer value",
> > + context);
> > + }
> > + return;
> > + }
> > +
> > + /* Check the THEN path. */
> > + check_and_warn_address_of_packed_member (type, TREE_OPERAND (rhs, 1));
> > +
> > + /* Check the ELSE path. */
> > + check_and_warn_address_of_packed_member (type, TREE_OPERAND (rhs, 2));
> > +}
>
> You probably also want to handle COMPOUND_EXPR.
>
Done.
[hjl@gnu-cfl-1 pr51628-5]$ cat c.i
struct A {
int i;
} __attribute__ ((packed));
int*
foo3 (struct A *p1, int *q1, int *q2, struct A *p2)
{
return q1 ? (*q1 = 1, &p1->i) : (q2 ? (*q2 = 2, &p2->i): q2);
}
[hjl@gnu-cfl-1 pr51628-5]$
/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/xgcc
-B/export/build/gnu/tools-build/gcc-debug/build-x86_64-linux/gcc/ -O2
-S c.i
c.i: In function ‘foo3’:
c.i:8:25: warning: taking address of packed member of ‘struct A’ may
result in an unaligned pointer value [-Waddress-of-packed-member]
8 | return q1 ? (*q1 = 1, &p1->i) : (q2 ? (*q2 = 2, &p2->i): q2);
| ^~~~~~
c.i:8:51: warning: taking address of packed member of ‘struct A’ may
result in an unaligned pointer value [-Waddress-of-packed-member]
8 | return q1 ? (*q1 = 1, &p1->i) : (q2 ? (*q2 = 2, &p2->i): q2);
| ^~~~~~
[hjl@gnu-cfl-1 pr51628-5]$
Here is the updated patch. OK for trunk?
Thanks.
--
H.J.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-C-C-Add-Waddress-of-packed-member.patch
Type: text/x-patch
Size: 51900 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20181218/d1ee6d27/attachment.bin>
More information about the Gcc-patches
mailing list