JuliaHubOSS/llvm-cbe

Incorrect "c++" code generation with -O3

Closed this issue · 0 comments

I was trying this project compiling programs using latest c++ features, but I found a program that generates invalid c code when built with any optimization, the program in question is

#include <algorithm>
#include <vector>
#include <iostream>
#include <ranges>

int main() {
    const std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    auto even = [](int i) { return 0 == i % 2; };
 
    using namespace std::views;
    auto rv = reverse(drop(filter(numbers, even), 1));
    for (auto& i : rv)
        std::cout << i << ' ';                                 
}

These are the steps I'm using

clang-17 -S -emit-llvm -o main.ll main.cpp -std=c++20 -O3
./llvm-cbe/build/tools/llvm-cbe/llvm-cbe main.ll
gcc main.cbe.c -lstdc++

and these are the errors I'm then getting from gcc

main.cbe.c:178:1: warning: ‘alloc_size’ attribute argument value ‘0’ does not refer to a function parameter [-Wattributes]
  178 | void* _Znwm(uint64_t _54) __ATTRIBUTELIST__((alloc_size(0)));
      | ^~~~
main.cbe.c: In function ‘main’:
main.cbe.c:250:23: error: ‘struct l_struct_class_OC_std_KD__KD_vector’ has no member named ‘field2’; did you mean ‘field0’?
  250 |   *(void**)(((&(&_2)->field2))) = _5;
      |                       ^~~~~~
      |                       field0
main.cbe.c:251:20: warning: passing argument 2 of ‘memcpy’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
  251 |   _6 = memcpy(_4, (&constinit), 40);
      |                   ~^~~~~~~~~~~
main.cbe.c:182:31: note: expected ‘void *’ but argument is of type ‘const struct l_array_10_uint32_t *’
  182 | void* memcpy(void* _61, void* _62, uint64_t _63);
      |                         ~~~~~~^~~
main.cbe.c:252:23: error: ‘struct l_struct_class_OC_std_KD__KD_vector’ has no member named ‘field1’; did you mean ‘field0’?
  252 |   *(void**)(((&(&_2)->field1))) = _5;
      |                       ^~~~~~
      |                       field0
main.cbe.c:254:18: error: ‘struct l_struct_class_OC_std_KD__KD_ranges_KD__KD_reverse_view’ has no member named ‘field1’; did you mean ‘field0’?
  254 |   _7 = ((&(&_3)->field1));
      |                  ^~~~~~
      |                  field0
main.cbe.c:255:26: error: ‘struct l_struct_class_OC_std_KD__KD_ranges_KD__KD_reverse_view’ has no member named ‘field1’; did you mean ‘field0’?
  255 |   *(uint64_t*)(((&(&_3)->field1))) = 1;
      |                          ^~~~~~
      |                          field0
main.cbe.c:256:28: error: ‘struct l_struct_class_OC_std_KD__KD_ranges_KD__KD_reverse_view’ has no member named ‘field2’; did you mean ‘field0’?
  256 |   _8 = ((&(&(&(&(&(&(&_3)->field2)->field0)->field0)->field0)->field0)->field1));
      |                            ^~~~~~
      |                            field0
main.cbe.c:257:18: error: ‘struct l_struct_class_OC_std_KD__KD_ranges_KD__KD_reverse_view’ has no member named ‘field2’; did you mean ‘field0’?
  257 |   _9 = ((&(&_3)->field2));
      |                  ^~~~~~
      |                  field0
main.cbe.c:318:37: error: ‘struct l_struct_class_OC_std_KD__KD_ranges_KD__KD_reverse_view’ has no member named ‘field2’; did you mean ‘field0’?
  318 |   *(void**)(((&(&(&(&(&(&(&(&(&_3)->field2)->field0)->field0)->field0)->field0)->field0)->field0)->field1))) = (&_3);
      |                                     ^~~~~~
      |                                     field0