[Bug libgcc/88641] New: crtstuff.c ctors/dtors list breaks with -fdata-sections
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88641 Bug ID: 88641 Summary: crtstuff.c ctors/dtors list breaks with -fdata-sections Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libgcc Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- Created attachment 45309 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45309&action=edit Patch to compile crtstuff.c with -fno-function-sections and -fno-data-sections. Breakage of ctors/dtors lists in crtbegin.o/crtend.o may occur when CFLAGS_FOR_TARGET contains -fdata-sections, leading to a crash at program startup. The issue is in libgcc/crtstuff.c where __LIBGCC_CTORS_SECTION_ASM_OP__ is used. I have experienced this with the MicroBlaze architecture, but any architecture where this code path is used has to be affected. Specifically, the problem is in the following code: static func_ptr force_to_data[1] __attribute__ ((__used__)) = { }; asm (__LIBGCC_CTORS_SECTION_ASM_OP__); STATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__used__, aligned(sizeof(func_ptr = { (func_ptr) (-1) }; Here asm is used to make the variable go into a specific section, usually ".ctors" or ".dtors". However, with -fdata-sections, gcc will anyway put it into its own section such as ".data.__CTOR_LIST__", and the asm will have no effect. The result is that these variables will not be found by the linker script using expressions like "KEEP (*crtbegin.o(.ctors))", which will cause a runtime failure in __do_global_ctors_aux as the ctors list will have no terminator. I believe that -ffunction-section could also cause problems in the crtstuff code, in particular where __LIBGCC_TEXT_SECTION_ASM_OP__ is used; there seems to be an assumption that all functions are by default placed in the ".text" section, which is not true with -ffunction-sections. I suggest fixing these issues by ensuring that crtstuff.c is compiled with -fno-function-sections and -fno-data-sections. I am attaching a patch that I have verified fixes the ctors/dtors section problem.
[Bug c++/85570] New: Resolution of unqualified-id in member access involving templates fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85570 Bug ID: 85570 Summary: Resolution of unqualified-id in member access involving templates fails Product: gcc Version: 7.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- In the following test program, the resolution of "TheA" in the expression "b.TheA::func()" fails but should not. According to the C++14 standard in [basic.lookup.classref] p2, the resolution of unqualified-id "TheA" should be done in the scope of the class type "B". Therefore it should resolve to the "TheA" type alias declared in the B class template. Compilation fails with this error: main.cpp: In function 'void test()': main.cpp:13:7: error: 'TheA' has not been declared b.TheA::func(); ^~~~ The code compiles with Clang. struct A { void func() {} }; template struct B : public A { using TheA = A; }; template void test() { B b; b.TheA::func(); } int main() { test(); return 0; }
[Bug c++/83417] New: Pointer-to-member template parameter with auto member type dependent container type does not work (C++17)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83417 Bug ID: 83417 Summary: Pointer-to-member template parameter with auto member type dependent container type does not work (C++17) Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- The following C++17 program does not compile with GCC 7.2.0 but does with Clang 5.0.0: template void f() {} struct A { int x; }; int main() { f(); return 0; } The error is: test.cpp: In function ‘int main()’: test.cpp:4:17: error: no matching function for call to ‘f()’ f(); ^ test.cpp:1:40: note: candidate: template void f() template void f() {} ^ test.cpp:1:40: note: template argument deduction/substitution failed: test.cpp:4:17: error: unable to deduce ‘auto T::*’ from ‘&A::x’ f(); ^ test.cpp:4:17: note: mismatched types ‘T’ and ‘A’
[Bug c++/82331] New: ICE specializing template for function pointer
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82331 Bug ID: 82331 Summary: ICE specializing template for function pointer Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- The code below crashes the compiler (compile with -std=c++17). gcccrash.cpp: In function ‘int test()’: gcccrash.cpp:15:30: internal compiler error: in tsubst_pack_expansion, at cp/pt.c:11514 int test () { return X<&func>::call(1, 2); } template class X; template class X { public: static R call (A... args) { return (*F)(args...); } }; int func (int a, int b) { return a + b; } int test () { return X<&func>::call(1, 2); }
[Bug libstdc++/80187] C++ variant should be trivially copy constructible if possible
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80187 --- Comment #4 from Ambroz Bizjak --- Oh wait sorry, that doesn't solve it (yet), the variant_storage_byte would still have a default copy constructor that copies the byte member.
[Bug libstdc++/80187] C++ variant should be trivially copy constructible if possible
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80187 --- Comment #3 from Ambroz Bizjak --- Hey, Does this idea help: https://godbolt.org/g/3Iqp2c ? The storage is an array of "special" byte classes which have empty constructors/assign when those would be implemented by one of the mixins.
[Bug libstdc++/80187] New: C++ variant should be trivially copy constructible if possible
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80187 Bug ID: 80187 Summary: C++ variant should be trivially copy constructible if possible Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- Presumably because std::variant is not trivially copy constructible, the ABI will be unable to pass it by value in a register in a call to a non-inlined function taking the variant by value, but will have to pass it by reference. Test case: #include struct TaggedUnion { union { int i; char c; }; int tag; }; void f1(std::variant); void f2(TaggedUnion); int main () { f1(42); f2({42, 0}); return 0; } Result on Linux x86-64: f1 is called passing the argument by address, f2 is called passing by register. See the standard proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0602r0.html however I think this can be fixed in gcc regardless of when/whether the proposal is accepted.
[Bug c++/78873] New: Virtual call after conversion to base class pointer is not devirtualized
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78873 Bug ID: 78873 Summary: Virtual call after conversion to base class pointer is not devirtualized Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- The following test case shows the issue. The generated code for TestDevirtualization could perform a direct call to Impl::Foo but it performs a call via the vtable. #include struct Iface { virtual void Foo() = 0; }; struct Impl : public Iface { __attribute__ ((noinline)) void Foo() override final { printf("Impl::Foo\n"); } }; template __attribute__ ((noinline)) void TestDevirtualuzation(Type *obj) { static_cast(obj)->Foo(); } int main() { Impl impl; TestDevirtualuzation(&impl); return 0; } I have heard arguments that optimizing this would not be legal, with the following test case which supposedly might be valid: struct Liar : Iface { void Foo() {} }; Impl impl; TestDevirtualuzation(reinterpret_cast(&impl)); But I think it is not valid; the result of the reinterpret_cast does not point to a Liar object, so the static_cast done in TestDevirtualuzation *should* be invalid. I couldn't find a clear statement in the standard about this though.
[Bug c++/77939] New: Valid program rejected due to access control
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77939 Bug ID: 77939 Summary: Valid program rejected due to access control Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- The following C++ program cannot be compiled, which is valid to my understanding. template class Test { struct CatDog { static void meow () { CrazyHouse::TheCatDog::meow(); } struct Dog { static void bark (); }; }; struct CrazyHouse { using TheCatDog = CatDog; static void startMadness () { TheCatDog::meow(); TheCatDog::Dog::bark(); } }; public: static void init () { CrazyHouse::startMadness(); } }; int main () { Test t; t.init(); } The error is: In instantiation of 'static void Test::CatDog::meow() [with Dummy = void]': 19 : required from 'static void Test::CrazyHouse::startMadness() [with Dummy = void]' 27 : required from 'static void Test::init() [with Dummy = void]' 34 : required from here 6 : error: 'using TheCatDog = struct Test::CatDog' is private within this context CrazyHouse::TheCatDog::meow(); ~~~^~ 15 : note: declared private here using TheCatDog = CatDog; CatDog::meow() should have access to CatDog class because 1) CatDog::meow() is part of CatDog class, 2) CatDog::meow() is declared within the Test class. I believe the test case is minimal.
[Bug debug/70599] Crash when adding debug symbols to a program making heavy use of nested templates.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70599 Ambroz Bizjak changed: What|Removed |Added CC||ambrop7 at gmail dot com --- Comment #4 from Ambroz Bizjak --- Hi, (I'm the author of Aprinter) I find that with -g1 instead of -g, the compile works fine. I've managed to refactor the code so that gcc compiles it with -g, using up to 8.5 GiB. The resulting .elf file is 627M (with -g1 16M, without -g 437K). It takes gdb about a minute to load the full file, and memory use of gdb grows to gigabytes. I suspect that the issue with -g is that gcc includes ALL types in the output, including types used only for metaprogramming. Probably for every list like Cons<1, Cons<2, Cons<3>>> there will be a quadratic explosion all constituent lists are included as symbols in the output, which is very bad for non-trivial lists. Clang manages to compile the same thing (with -g) using 1GiB RAM and results in a 181M .elf output.
[Bug other/60040] AVR: error: unable to find a register to spill in class 'POINTER_REGS'
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60040 --- Comment #11 from Ambroz Bizjak --- Created attachment 37320 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37320&action=edit Modified patch which clears failure I made a wild guess that the issue is that the "failure" is not cleared, so I modified the patch (by hand), to clear "failure" after an ignored failure. With this my code compiles and links.
[Bug other/60040] AVR: error: unable to find a register to spill in class 'POINTER_REGS'
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60040 Ambroz Bizjak changed: What|Removed |Added CC||ambrop7 at gmail dot com --- Comment #10 from Ambroz Bizjak --- I've been getting this error on some complex code of mine (for atmga2560). I tried the attached patch on gcc 5.3. While it resolves the original compile error, I then get an error from the linker, an undefined reference to the same function that the original error was related to. So I think something is wrong with the patch.
[Bug target/59174] New: [avr] Suboptimal multiplication when indexing an array
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59174 Bug ID: 59174 Summary: [avr] Suboptimal multiplication when indexing an array Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com When indexing an array, gcc will sometimes perform a multiplication using shifts and adds, instead of using the more efficient multiplication instructions. This program demonstrates the issue. #include struct Foo { char a[12]; } foo[10]; struct Foo * test (uint8_t i) { return &foo[i]; } Compile with: avr-gcc -mmcu=atmega2560 -O2 -S test.c -o - Result: test: mov r18,r24 ldi r19,0 movw r24,r18 lsl r24 rol r25 add r24,r18 adc r25,r19 lsl r24 rol r25 lsl r24 rol r25 subi r24,lo8(-(foo)) sbci r25,hi8(-(foo)) ret On the other hand, if the struct size is changed to 13, much more efficient assembly is produced: test: ldi r18,lo8(13) mul r24,r18 movw r24,r0 clr __zero_reg__ subi r24,lo8(-(foo)) sbci r25,hi8(-(foo)) ret The first assembly takes 13 cycles, the second just 7. I don't see any reason why the second assembly wouldn't work for size 12.
[Bug c++/57390] Fixed point types on AVR are not available in C++ mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57390 --- Comment #2 from Ambroz Bizjak --- I've been reading the discussion there, but I don't see any interaction problems with templates. Most of it is just useless arguing about whether fixed point types can be implemented externally with templates. The support in the GCC code is already there, what is the real obstacle to enabling that in C++?
[Bug c++/57390] New: Fixed point types on AVR are not available in C++ mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57390 Bug ID: 57390 Summary: Fixed point types on AVR are not available in C++ mode Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com As of version 4.8, GCC supports fixed point types for the AVR target. See: http://gcc.gnu.org/wiki/avr-gcc#Fixed-Point_Support However, this is only available in C and not in C++. Please enable fixed point for C++ too. It may have to be hidden behind an option to not break existing C++ code though.