[cfe-commits] [patch] Add support for weakref

Rafael Espindola espindola at google.com
Mon Feb 22 14:09:34 PST 2010


> That's a bug in llvm-gcc; there's a PR in Bugzilla on it, although
> it's down at the moment.  The correct semantics for weakref if we
> implement it purely in clang are as follows:
>
> 1. Emit weakref variables as external declarations, and put them on a
> list to go through after everything is emitted.
> 2. For each weakref variable, see if there is an existing declaration
> of the target: if there isn't, build a weak declaration of the target.
> 3. Replace all uses of the weakref with the target.
>
> The only issue with this is that it doesn't interact with inline asm correctly.

Interesting. I did some experimentation with gcc

Compiling
------------------------------------
extern int a(void);
static int c(void) __attribute__((weakref("a")));

void* f(void) {
  return (void*)c;
}
-------------------------------

the generated .o by has

WEAK   DEFAULT  UND a

but if I add

---------------------------------
void* g(void) {
  return (void*)a;
}
--------------------------------

the generated file has

GLOBAL DEFAULT  UND a

in no case a "c" symbol is produced. In the case of gcc all it does is
pass the work to the assembler via ".weakref        c,a".

I see two ways we could implement this:

1) Add support in LLVM. The advantage is that we can also just emit a
.weakref. The problem is that this would have very strange semantics
for LTO.
2) Do it in clang.  The first example above would be compiled to
-------------------------------------------------
....
declare extern_weak i32 @a()
----------------------------------------------

but the second example would be compiled to
------------------------------------------
....
declare i32 @a()
----------------------------------------

I think the algorithm is a bit different than what you described:

1) Emit uses of a  weakref as uses the target

if (If the target exists in this file) {
  nothing to do. There will be no undefined references
} else {
  If (the target declaration is marked with __attribute__((weak))) {
    declare it using extern_weak.
  } else if (there is at least one direct undefined reference to it) {
    declare it without extern_weak.
  } else {
    declare it using extern_weak.
  }
}

for now my patch gets clang on the same level as llvm-gcc at least.

> -Eli
>


Cheers,
-- 
Rafael Ávila de Espíndola




More information about the cfe-commits mailing list