JuliaHubOSS / llvm-cbe

resurrected LLVM "C Backend", with improvements
Other
826 stars 141 forks source link

llvm-cbe generates use of variables just before they are being declared, from .ll ouput from clang++-10 (plzip-1.9 main.c) #134

Open makise-homura opened 3 years ago

makise-homura commented 3 years ago

Say, we have LLVM 10.0.0, and just have built llvm-cbe in current directory.

Trying to build main.cc from plzip-1.9 with lzlib-1.12:

wget -q http://download.savannah.gnu.org/releases/lzip/lzlib/lzlib-1.12.tar.gz
wget -q http://download.savannah.gnu.org/releases/lzip/plzip/plzip-1.9.tar.gz
tar xf plzip-1.9.tar.gz
tar xf lzlib-1.12.tar.gz
clang++-10 -S -emit-llvm -g -Iplzip-1.9 -Ilzlib-1.12 -DPROGVERSION='""' -o main.ll plzip-1.9/main.cc
./llvm-cbe main.ll
gcc-10 -Wno-builtin-declaration-mismatch -Wno-address-of-packed-member -c -o main.o main.cbe.c

I have the following output then:

main.cbe.c:721:152: error: ‘_OC_str_OC_84’ undeclared here (not in a function); did you mean ‘_OC_str_OC_83’?
  721 | static __MSALIGN__(16) struct l_array_3_struct_AC_l_struct_struct_OC_anon _ZN12_GLOBAL__N_116known_extensionsE __attribute__((aligned(16))) = { { { ((&_OC_str_OC_84.array[((int32_t)0)])), ((&_OC_str_OC_10.array[((int32_t)0)])) }, { ((&_OC_str_OC_85.array[((int32_t)0)])), ((&_OC_str_OC_86.array[((int32_t)0)])) }, { ((uint8_t*)/*NULL*/0), ((uint8_t*)/*NULL*/0) } } };
      |                                                                                                                                                        ^~~~~~~~~~~~~
      |                                                                                                                                                        _OC_str_OC_83
main.cbe.c:721:236: error: ‘_OC_str_OC_85’ undeclared here (not in a function); did you mean ‘_OC_str_OC_83’?
  721 | _(16) struct l_array_3_struct_AC_l_struct_struct_OC_anon _ZN12_GLOBAL__N_116known_extensionsE __attribute__((aligned(16))) = { { { ((&_OC_str_OC_84.array[((int32_t)0)])), ((&_OC_str_OC_10.array[((int32_t)0)])) }, { ((&_OC_str_OC_85.array[((int32_t)0)])), ((&_OC_str_OC_86.array[((int32_t)0)])) }, { ((uint8_t*)/*NULL*/0), ((uint8_t*)/*NULL*/0) } } };
      |                                                                                                                                                                                                                           ^~~~~~~~~~~~~
      |                                                                                                                                                                                                                           _OC_str_OC_83
main.cbe.c:721:276: error: ‘_OC_str_OC_86’ undeclared here (not in a function); did you mean ‘_OC_str_OC_83’?
  721 | t_struct_OC_anon _ZN12_GLOBAL__N_116known_extensionsE __attribute__((aligned(16))) = { { { ((&_OC_str_OC_84.array[((int32_t)0)])), ((&_OC_str_OC_10.array[((int32_t)0)])) }, { ((&_OC_str_OC_85.array[((int32_t)0)])), ((&_OC_str_OC_86.array[((int32_t)0)])) }, { ((uint8_t*)/*NULL*/0), ((uint8_t*)/*NULL*/0) } } };
      |                                                                                                                                                                                                                           ^~~~~~~~~~~~~
      |                                                                                                                                                                                                                           _OC_str_OC_83

Interestingly, after some analysis of main.cbe.c, i found out that _OC_str_OC_84, _OC_str_OC_85, and _OC_str_OC_86 are declared in lines 722, 723. 724 of main.cbe.c, just after being used in line 721:

static __MSALIGN__(16) struct l_array_3_struct_AC_l_struct_struct_OC_anon _ZN12_GLOBAL__N_116known_extensionsE __attribute__((aligned(16))) = { { { ((&_OC_str_OC_84.array[((int32_t)0)])), ((&_OC_str_OC_10.array[((int32_t)0)])) }, { ((&_OC_str_OC_85.array[((int32_t)0)])), ((&_OC_str_OC_86.array[((int32_t)0)])) }, { ((uint8_t*)/*NULL*/0), ((uint8_t*)/*NULL*/0) } } };
static struct l_array_4_uint8_t _OC_str_OC_84 = { ".lz" };
static struct l_array_5_uint8_t _OC_str_OC_85 = { ".tlz" };
static struct l_array_5_uint8_t _OC_str_OC_86 = { ".tar" };
makise-homura commented 3 years ago

Simple reproduction example (decls.cc):

namespace { const struct { const char * a; const char * b; } c[] = { { "x", "y" } }; };
int main() { return c[0].a[0]; }

Build:

clang++-10 -S -emit-llvm -g -o decls.ll decls.cc
./llvm-cbe decls.ll
gcc-10 -c decls.cbe.c -o decls