[Bug c++/91953] [8/9/10 Regression] G++ rejects lambda with constexpr variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91953 --- Comment #4 from Kyrylo Bohdanenko --- The problem can also be worked around by manually specifying "the holy trio" of constructors and providing empty bodies (= default does not work) This code compiles with GCC 8.3.0 and trunk (20190919): template struct integral_constant { static constexpr _Tp value = __v; typedef _Tp value_type; constexpr operator value_type() const noexcept { return value; } // all of these constructors are needed for the code to compile constexpr integral_constant(const integral_constant&) noexcept {} constexpr integral_constant(integral_constant&&) noexcept {} constexpr integral_constant() noexcept {} }; int main() { auto l = [](auto value) { constexpr auto i = value; static_cast(i); }; l(integral_constant{}); }
[Bug c++/91953] [8/9/10 Regression] G++ rejects lambda with constexpr variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91953 --- Comment #5 from Kyrylo Bohdanenko --- Sorry, the move constructor isn't necessary... template struct integral_constant { constexpr integral_constant(const integral_constant&) noexcept {} constexpr integral_constant() noexcept {} }; int main() { auto l = [](auto value) { constexpr auto i = value; static_cast(i); }; l(integral_constant{}); }
[Bug c++/101240] New: [missed optimization] Transitivity of less-than and less-or-equal
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101240 Bug ID: 101240 Summary: [missed optimization] Transitivity of less-than and less-or-equal Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kyrylo.bohdanenko at gmail dot com Target Milestone: --- Consider the following C++ code #define ALWAYS_TRUE(x) do { if (x) __builtin_unreachable(); } while (false) int divide(int a, int b) { ALWAYS_TRUE(a == b); return a / b; } void test_array(unsigned (&arr)[3]) { ALWAYS_TRUE(a[0] < a[1] && a[1] < a[2]); return a[0] < a[2]; } The first function is optimiozed away: divide(int, int): mov eax, 1 ret While the second still does the comparison: test_array(unsigned int (&) [3]): mov eax, DWORD PTR [rdi+8] cmp DWORD PTR [rdi], eax setbal ret It would be nice if GCC could deduce that a < b && b < c --> a < c And optimize that second function (provided no other UB is involved)
[Bug tree-optimization/106076] New: Sub-optimal code is generated for checking bitfields via proxy functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106076 Bug ID: 106076 Summary: Sub-optimal code is generated for checking bitfields via proxy functions Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: kyrylo.bohdanenko at gmail dot com Target Milestone: --- Consider the following struct: #include struct SomeClass { uint16_t dummy1 : 1; uint16_t cfg2 : 1; uint16_t cfg3 : 1; uint16_t dummy2 : 1; uint16_t dummy3 : 1; uint16_t dummy4 : 1; uint16_t cfg1 : 1; uint16_t dummy5 : 1; uint16_t cfg4 : 1; constexpr bool checkA() const { return cfg1 || cfg2 || cfg3; } constexpr bool checkB() const { return cfg4; } constexpr bool checkA_B() const { return (cfg1 || cfg2 || cfg3) || cfg4; } constexpr bool checkA_B_SLOW() const { return checkA() || checkB(); } }; For the following functions (which do the same thing) GCC generates different assembly. bool check(const SomeClass& rt) { return rt.checkA_B(); } bool check_SLOW(const SomeClass& rt) { return rt.checkA_B_SLOW(); } Compiled as: g++ -std=c++17 -S The assembly: ; demangled: check(SomeClass const&) _Z5checkRK9SomeClass: endbr64 testw $326, (%rdi) setne %al ret ; demangled: check_SLOW(SomeClass const&) _Z10check_SLOWRK9SomeClass: endbr64 movzwl (%rdi), %edx movl$1, %eax testb $70, %dl jne .L3 movzbl %dh, %eax andl$1, %eax .L3: ret As we can see, during check_SLOW GCC decided to check the result on byte-by-byte basis introducing a conditional jump in between. It looks like GCC did not fully analyse the code after inlining checkA() and checkB(). FYI, the same code on Clang produces the 1st option of ASM for both functions.
[Bug tree-optimization/106076] Sub-optimal code is generated for checking bitfields via proxy functions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106076 --- Comment #1 from Kyrylo Bohdanenko --- The provided assembly is for -O2/-O3
[Bug c++/95454] type-level nodiscard not applied to constructors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95454 Kyrylo Bohdanenko changed: What|Removed |Added CC||kyrylo.bohdanenko at gmail dot com --- Comment #2 from Kyrylo Bohdanenko --- Still relevant as of the current trunk. A workaround would be to declare the constructor(s) [[nodiscard]]: struct Data { [[nodiscard]] Data() {} }; int main() { Data{}; } This actually issues a warning: : In function 'int main()': :6:11: warning: ignoring return value of 'Data::Data()', declared with attribute 'nodiscard' [-Wunused-result] Sandbox: https://godbolt.org/z/3Koj8rra7
[Bug c++/113108] New: Internal compiler error when choosing overload for operator=
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113108 Bug ID: 113108 Summary: Internal compiler error when choosing overload for operator= Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kyrylo.bohdanenko at gmail dot com Target Milestone: --- The following code causes GCC internal error: template struct Foo { Foo& operator=(Foo&&) = default; T data; }; template void consume(Foo& (Foo::*)(Foo&&) ) {} template void consume(Foo& (Foo::*)(Foo&&) noexcept) {} int main() { consume(&Foo::operator=); } Output: : In substitution of 'template void consume(Foo& (Foo::*)(Foo&&) noexcept) [with T = ]': :26:12: required from here 26 | consume(&Foo::operator=); | ~~~^~ :26:12: internal compiler error: in nothrow_spec_p, at cp/except.cc:1201 0x262b4bc internal_error(char const*, ...) ???:0 0xa4d583 fancy_abort(char const*, int, char const*) ???:0 0xca6a7f fn_type_unification(tree_node*, tree_node*, tree_node*, tree_node* const*, unsigned int, tree_node*, unification_kind_t, int, conversion**, bool, bool) ???:0 0xa7cfd9 build_new_function_call(tree_node*, vec**, int) ???:0 0xcc6c76 finish_call_expr(tree_node*, vec**, bool, bool, int) ???:0 0xc4b8ba c_parse_file() ???:0 0xd9cda9 c_common_parse_file() ???:0 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions.
[Bug c++/113108] Internal compiler error when choosing overload for operator=
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113108 --- Comment #1 from Kyrylo Bohdanenko --- Compiled with -std=c++17 -O2 -Wall -Wextra -Wpedantic
[Bug c++/113108] Internal compiler error when choosing overload for operator=
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113108 --- Comment #2 from Kyrylo Bohdanenko --- Godbolt link (not the original example): https://godbolt.org/z/E1veMxcdx