https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67882

            Bug ID: 67882
           Summary: surprising offsetof result on an invalid array member
                    without diagnostic
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

While looking some more at bug 67872, I noticed that the logic in
fold_offsetof_1 responsible for diagnosing past-the-end array element
references isn't quite correct after all.  GCC fails to diagnose cases of
invalid offsetof expressions whose member designator refers to an array element
past the end of the array plus one.  In the following test case, all but the
first offsetof expressions are strictly invalid.  The second one could probably
be considered an extension and accepted without diagnostic since it refers to
an element just past the end of the array, but all the others could and should
be diagnosed.

Diagnosing the invalid expressions seems especially important because
__builtin_offsetof evaluates to the "wrong" values for the invalid members. 
I.e., __builtin_offsetof (struct A, a1_1[0][1]) and __builtin_offsetof (struct
A, a1_1[1][0]) both evaluate to 1, and __builtin_offsetof (struct A,
a1_1[1][1]) evaluates to 2 rather than 3 as it would if the array element did
exist.  This is also why I opened a separate bug  rather than adding this as an
observation to the referenced bug.

struct A {
    char a1_1[1][1];
    int i;
} a;

void f (int i) {
#define Offset(m)  __builtin_offsetof (struct A, m)

    _Static_assert (sizeof a.a1_1 == 1, "sizeof a.a1_1 == 1");

    switch (i) {
    case Offset (a1_1[0][0]):
    case Offset (a1_1[0][1]):
    case Offset (a1_1[1][0]):
    case Offset (a1_1[1][1]):
        break;
    }
}
x.c: In function ‘f’:
x.c:14:5: error: duplicate case value
     case Offset (a1_1[1][0]):
     ^
x.c:13:5: error: previously used here
     case Offset (a1_1[0][1]):
     ^

Reply via email to