Enables code such as: #undef NDEBUG #include <assert.h> #include <stdint.h> static int st_x = 42; static int st_x_ __attribute((alias("st_x"))); int main(void){ assert((uintptr_t)&st_x == (uintptr_t)&st_x_); } which would previously fail with no compiler warnings. The limitation of this is that the alias must be done (or redone) after an actual definition. An alias done right after a later overridden tentative declaration won't work (sufficient for my use case).
Unified · Split
| @@ -8661,6 +8661,16 @@ static int decl(int l) · 8660 unmodified lines | ||
| 8661 | 8661 | else if (l == VT_CONST) |
| 8662 | 8662 | /* uninitialized global variables may be overridden */ |
| 8663 | 8663 | type.t |= VT_EXTERN; |
| 8664 | + | |
| 8665 | + if (ad.alias_target && 1) { | |
| 8666 | + Sym *alias_target = sym_find(ad.alias_target); | |
| 8667 | + ElfSym *esym = elfsym(alias_target); | |
| 8668 | + if (!esym) tcc_error("unsupported forward __alias__ attribute"); | |
| 8669 | + sym = external_sym(v, &type, r, &ad); | |
| 8670 | + put_extern_sym2(sym, esym->st_shndx, | |
| 8671 | + esym->st_value, esym->st_size, 1); | |
| 8672 | + } | |
| 8673 | + | |
| 8664 | 8674 | decl_initializer_alloc(&type, &ad, r, has_init, v, l == VT_CONST); |
| 8665 | 8675 | } |
| 8666 | 8676 | } |