[LLVMbugs] [Bug 6345] New: [GNU Extension] Clang differs from GCC on anonymous structs

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Thu Feb 18 12:02:11 PST 2010


http://llvm.org/bugs/show_bug.cgi?id=6345

           Summary: [GNU Extension] Clang differs from GCC on anonymous
                    structs
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Semantic Analyzer
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: cdavis at mymail.mines.edu
                CC: llvmbugs at cs.uiuc.edu


Consider the following:

union foo {
  struct {
    union {
      struct {void* bar[4];};
    } u;
    struct {
      union {int baz;} u;
    };
  } s;
};

int f(void) {
  union foo foo;
  foo.s.u.bar[2] = (void*)0;
  foo.s.u.baz = 0;
}

When GCC 4.2 is run on this example, it produces the following:
foo.c: In function ‘f’:
foo.c:17: error: ‘union <anonymous>’ has no member named ‘baz’

but when Clang is run on the example, it produces this:
test-su.c:7:23: error: member of anonymous struct redeclares 'u'
                        union { int baz; } u;
                                           ^
test-su.c:5:5: note: previous declaration is here
                } u;
                  ^
test-su.c:16:10: error: no member named 'bar' in 'union foo::<anonymous>'; did
      you mean 'baz'?
        foo.s.u.bar[2] = (void*)0;
                ^~~
                baz
test-su.c:7:16: note: 'baz' declared here
                        union { int baz; } u;
                                    ^
test-su.c:16:13: error: subscripted value is not an array, pointer, or vector
        foo.s.u.bar[2] = (void*)0;
        ~~~~~~~~~~~^~
5 diagnostics generated.

It does not matter if Clang is in C99 or C89 mode (with GNU extensions, of
course).

So there's two differences between clang and GCC:
- Clang complains if a member is redeclared in an anonymous struct. GCC simply
discards the second declaration.
- Interestingly, clang then hides the first definition, using only the second
one. GCC simply discards the second one.

I don't know if you want to fix this, but the union construct has appeared in
the wild, specifically in Wine, and they're loath to change it. After all, it's
worked well for them for the past 10 years with GCC.


-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list