#pragma weak handling

struct in6_addr
   {
     union
       {
         unsigned char __u6_addr8[16];
         unsigned short __u6_addr16[8];
         unsigned int __u6_addr32[4];
     } __in6_u;
};

extern const struct in6_addr in6addr_any;

static const struct in6_addr local_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
#pragma weak in6addr_any = local_in6addr_any

Examining the ast generated for this snippet I note two problems:

1) the extra declaration generated by #pragma has the following form:

static const struct in6_addr in6addr_any __attribute__ ((weak)) __attribute__ ((alias("local_in6addr_any")));

The problem I see is that "static" should be replaced by "extern".

I think that the bug is in Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) where it is copied also the storage class of VarDecl.

2) the extra declaration generated by #pragma seems to be not linked to other declarations for the same object and then getCanonicalDecl does not work as expected.

I'd like to know if this analysis is correct and if yes, what's the suggested way to fix point 2 (I think that the fix to point 1 is rather obvious).

Bug #3679 covers this problem, I think. Comment #32 states that "#pragma weak foo" after defining function foo() doesn't work.

Thanks,
Erik Cederstrand

Please consider that the problems I describe are not at codegen level, but at level of AST building.