Bug 41809 - escaping address of packed field should trigger warning
Summary: escaping address of packed field should trigger warning
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.5.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
: 54032 79918 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-10-23 16:05 UTC by Mikael Pettersson
Modified: 2020-05-20 22:00 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.1.0, 9.2.0
Known to fail:
Last reconfirmed: 2012-02-01 00:00:00


Attachments
Another testcase (178 bytes, text/x-c++src)
2012-10-18 11:38 UTC, Yuri Gribov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mikael Pettersson 2009-10-23 16:05:53 UTC
A field in a packed struct will often not have the normal alignment for its type.  So taking the address of such a field may yield a misaligned pointer, but gcc does not warn about that.  This is similar to casting a pointer from a less aligned type to a more aligned type, which does give a warning (with -Wcast-align).

Example:
> cat aopf.c
#include <stdio.h>

void __attribute__((noinline)) f(int *p)
{
    printf("%p\n", p);
}

struct s {
    int x;
    char c;
} __attribute__((__packed__));

struct s A[10];

int main(void)
{
    unsigned int i;

    for (i = 0; i < sizeof(A)/sizeof(A[0]); ++i) {
        f(&A[i].x);
        f((int*)(char*)&A[i].x);
    }    
    return 0;
}
> gcc -Wall -Wextra -Wcast-align -O aopf.c
aopf.c: In function 'main':
aopf.c:21:4: warning: cast increases required alignment of target type

Ideally both calls to f() should trigger alignment warnings.
Comment 1 Hans-Peter Nilsson 2009-10-26 21:46:49 UTC
To whomever will fix this: beware not to introduce warnings for targets where the "packed" layout is the default. (As has happened in the past for other "packed warnings".)
Comment 2 Andrew Pinski 2012-02-01 23:28:03 UTC
Confirmed.
Comment 3 Yuri Gribov 2012-10-18 11:38:45 UTC
Created attachment 28481 [details]
Another testcase

Testcase which demonstrates more issues.
Comment 4 Yuri Gribov 2012-10-18 11:41:10 UTC
Gcc does warn (actually it even errs) if you try to pass unaligned variable by reference but does not do this when you use pointers:
  $ g++ -Wall -c pack_warns.cpp
  pack_warns.cpp:22:9: error: cannot bind packed field 't->Test::x' to 'float&'

Also it'll fail to warn if you use #pragma pack instead of __attribute__((packed)):
  $ g++ -Wall -c -DUSE_PRAGMA pack_warns.cpp   # Compiles wo warnings

Just wanted to mention that users frequently run into errors with unaligned data (especially on targets where it really matters e.g. on ARM) so this might be important issue.
Comment 5 Martin Sebor 2017-03-24 16:37:54 UTC
*** Bug 79918 has been marked as a duplicate of this bug. ***
Comment 6 Martin Sebor 2017-03-24 20:05:25 UTC
*** Bug 54032 has been marked as a duplicate of this bug. ***
Comment 7 Martin Sebor 2020-05-19 20:16:15 UTC
Starting with version 9 GCC diagnoses both calls in the test case in comment #0 (the test case with #pragma pack in comment #3 is not diagnosed):

$ cat pr41809.c && gcc -O2 -S -Wall pr41809.c
void f(int *);

struct s {
    int x;
    char c;
} __attribute__((__packed__));

struct s A[10];

int main(void)
{
    for (int i = 0; i != sizeof(A)/sizeof(A[0]); ++i) {
        f(&A[i].x);
        f((int*)(char*)&A[i].x);
    }    
}
pr41809.c: In function ‘main’:
pr41809.c:13:11: warning: taking address of packed member of ‘struct s’ may result in an unaligned pointer value [-Waddress-of-packed-member]
   13 |         f(&A[i].x);
      |           ^~~~~~~
pr41809.c:14:11: warning: taking address of packed member of ‘struct s’ may result in an unaligned pointer value [-Waddress-of-packed-member]
   14 |         f((int*)(char*)&A[i].x);
      |           ^~~~~~~~~~~~~~~~~~~~
Comment 8 Martin Sebor 2020-05-19 20:19:48 UTC
Let me resolve the attribute subset of the problem as fixed.  The outstanding  #pragma pack subset is the subject of pr68160.