tinycc/tests/tests2/120_alias.c

30 lines
722 B
C
Raw Normal View History

Reinstate attribute alias handling commit 2a0167a merged alias and asm symbol renaming, but broke semantics of aliases, see testcase. Basically the difference between the two is that an asm rename doesn't generate a new symbol, i.e. with int foo __asm__("bar"); all source reference to 'foo' will be to 'bar', nothing of the name 'foo' will remain in the object file, and for instance reference to 'foo' from other compilation units won't be resolved to this one. Aliases OTOH create an additional symbol. With: void target (void) { return; } void afunc (void) __attribute__((alias("target"))); reference to 'afunc' will remain 'afunc' in the object file. It will generate two symbols, 'afunc' and 'target' referring to the same entity. This difference matters if other compilation units make references to 'afunc'. A side requirement of this is that for alias to work that the target symbol needs to be defined in the same unit. For TCC we even require a stricter variant: it must be defined before the alias is created. Now, with this I merely re-instated the old flow of events before above commit. It didn't seem useful anymore to place both names in the asm_label member of attributes, and the asm_label member of Sym now again only needs the hold the __asm__ rename. It also follows that tcc_predefs.h can't make use of attribute alias to e.g. map __builtin_memcpy to __bound_memcpy (simply because the latter isn't defined in all units), but rather must use __asm__ renaming, which in turn means that the underscore handling needs to be done by hand.
2020-09-30 23:46:01 +08:00
/* Check semantics of various constructs to generate renamed symbols. */
extern int printf (const char *, ...);
void target(void);
void target(void) {
printf("in target function\n");
}
void alias_for_target(void) __attribute__((alias("target")));
#ifdef __leading_underscore
void asm_for_target(void) __asm__("_target");
#else
Reinstate attribute alias handling commit 2a0167a merged alias and asm symbol renaming, but broke semantics of aliases, see testcase. Basically the difference between the two is that an asm rename doesn't generate a new symbol, i.e. with int foo __asm__("bar"); all source reference to 'foo' will be to 'bar', nothing of the name 'foo' will remain in the object file, and for instance reference to 'foo' from other compilation units won't be resolved to this one. Aliases OTOH create an additional symbol. With: void target (void) { return; } void afunc (void) __attribute__((alias("target"))); reference to 'afunc' will remain 'afunc' in the object file. It will generate two symbols, 'afunc' and 'target' referring to the same entity. This difference matters if other compilation units make references to 'afunc'. A side requirement of this is that for alias to work that the target symbol needs to be defined in the same unit. For TCC we even require a stricter variant: it must be defined before the alias is created. Now, with this I merely re-instated the old flow of events before above commit. It didn't seem useful anymore to place both names in the asm_label member of attributes, and the asm_label member of Sym now again only needs the hold the __asm__ rename. It also follows that tcc_predefs.h can't make use of attribute alias to e.g. map __builtin_memcpy to __bound_memcpy (simply because the latter isn't defined in all units), but rather must use __asm__ renaming, which in turn means that the underscore handling needs to be done by hand.
2020-09-30 23:46:01 +08:00
void asm_for_target(void) __asm__("target");
#endif
Reinstate attribute alias handling commit 2a0167a merged alias and asm symbol renaming, but broke semantics of aliases, see testcase. Basically the difference between the two is that an asm rename doesn't generate a new symbol, i.e. with int foo __asm__("bar"); all source reference to 'foo' will be to 'bar', nothing of the name 'foo' will remain in the object file, and for instance reference to 'foo' from other compilation units won't be resolved to this one. Aliases OTOH create an additional symbol. With: void target (void) { return; } void afunc (void) __attribute__((alias("target"))); reference to 'afunc' will remain 'afunc' in the object file. It will generate two symbols, 'afunc' and 'target' referring to the same entity. This difference matters if other compilation units make references to 'afunc'. A side requirement of this is that for alias to work that the target symbol needs to be defined in the same unit. For TCC we even require a stricter variant: it must be defined before the alias is created. Now, with this I merely re-instated the old flow of events before above commit. It didn't seem useful anymore to place both names in the asm_label member of attributes, and the asm_label member of Sym now again only needs the hold the __asm__ rename. It also follows that tcc_predefs.h can't make use of attribute alias to e.g. map __builtin_memcpy to __bound_memcpy (simply because the latter isn't defined in all units), but rather must use __asm__ renaming, which in turn means that the underscore handling needs to be done by hand.
2020-09-30 23:46:01 +08:00
/* This is not supposed to compile, alias targets must be defined in the
same unit. In TCC they even must be defined before the reference
void alias_for_undef(void) __attribute__((alias("undefined")));
*/
extern void inunit2(void);
int main(void)
{
target();
alias_for_target();
asm_for_target();
inunit2();
return 0;
}