[Bug c++/97288] New: Assignment sequence before order - evaluating reference to value of right side not in order
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97288 Bug ID: 97288 Summary: Assignment sequence before order - evaluating reference to value of right side not in order Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kirshamir at gmail dot com Target Milestone: --- Following code results with different result in gcc and clang, seems that gcc get wrong the sequence before: class Number { int num = 0; public: Number(int n): num(n) { std::cout << "in ctor of Number for: " << num << std::endl; } // Number(const Number& n): num(n.num) { // std::cout << "in copy of Number for: " << num << std::endl; // } Number& operator+=(int i) { std::cout << "in +=(int) for *this = " << num << " and int = " << i << std::endl; num += i; return *this; } Number& operator+=(Number n) { std::cout << "in +=(Number) for *this = " << num << " and Number = " << n << std::endl; num += n.num; return *this; } operator int() const { return num; } }; int main() { Number a {5}; (a += 1) += a; std::cout << a << std::endl; } Code: https://godbolt.org/z/1P63z7 Based on stackoverflow: https://stackoverflow.com/questions/64195482/chained-compound-assignments-with-c17-sequencing-are-still-undefined-behaviour
[Bug c++/97288] Assignment sequence before order - evaluating reference to value of right side not in order
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97288 --- Comment #1 from Amir Kirsh --- For user defined type this behavior might be ok, as the order of evaluation of parameters is not defined, however this behavior is reflected also for primitive types: int main() { int a {5}; (a += 1) += a; std::cout << a << std::endl; } gcc gives a warning: warning: operation on 'a' may be undefined [-Wsequence-point] 5 | (a += 1) += a; | ~~~^ :5:8: warning: operation on 'a' may be undefined [-Wsequence-point] and result is 12. Though based on C++17 sequencing rules for assignment, seems that the operation shall be valid (no warning) and result with 11. http://eel.is/c++draft/expr.ass#1 Code: https://godbolt.org/z/G1Kahh
[Bug c++/97402] Value of dependent partial-concept-id is not usable in a constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97402 Amir Kirsh changed: What|Removed |Added CC||kirshamir at gmail dot com --- Comment #2 from Amir Kirsh --- See also: https://stackoverflow.com/questions/65653983/gcc-stdis-same-vint-t-is-not-usable-in-a-constant-expression
[Bug c++/97402] Value of dependent partial-concept-id is not usable in a constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97402 --- Comment #3 from Amir Kirsh --- Playing with the code even leads to compiler seg-fault, see: https://stackoverflow.com/a/65654043/2085626
[Bug c++/99158] New: [Enhancement] Better error message when missing #include and using placement new
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99158 Bug ID: 99158 Summary: [Enhancement] Better error message when missing #include and using placement new Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kirshamir at gmail dot com Target Milestone: --- Use of placement new requires #include Without this include the error message is something like: error: no matching function for call to 'operator new(sizetype, A*)' 8 | new (this) A(other); | ^ note: candidate function not viable: no known conversion from 'A *' to 'std::align_val_t' for 2nd argument note: candidate function not viable: requires 1 argument, but 2 were provided Many std headers have #include thus users just usually write placement new without a special include and everything works fine, but when code moves around above error message may just pop up. A better error might be: error: no matching function for call to 'operator new' Note: use of placement new requires #include ...
[Bug c++/100838] New: -fno-elide-constructors for C++14 missing required destructor call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100838 Bug ID: 100838 Summary: -fno-elide-constructors for C++14 missing required destructor call Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kirshamir at gmail dot com Target Milestone: --- Code: https://godbolt.org/z/jKnKTds7s #include class MyString { public: MyString(const char* s = "") { std::cout << "ctor" << std::endl; } ~MyString() { std::cout << "dtor" << std::endl; } MyString(const MyString& s) { std::cout << "copy ctor" << std::endl; } MyString& operator=(const MyString& s) { std::cout << "operator=" << std::endl; return *this; } }; int main() { MyString s1 = "Hello"; std::cout << __LINE__ << std::endl; } --- When compiled with: -std=c++14 -fno-elide-constructors Output: ctor copy ctor 22 dtor Expected output: ctor copy ctor dtor 22 dtor
[Bug c++/100838] -fno-elide-constructors for C++14 missing required destructor call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100838 --- Comment #1 from Amir Kirsh --- This main: int main() { MyString s1 = MyString{"Hello"}; // same also for rounded brackets std::cout << __LINE__ << std::endl; } works as expected. Output with C++14 and -fno-elide-constructors: ctor copy ctor dtor 22 dtor
[Bug c++/100992] New: Wrong result for is_constructible for const ref of tuple of tuples
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100992 Bug ID: 100992 Summary: Wrong result for is_constructible for const ref of tuple of tuples Product: gcc Version: 11.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kirshamir at gmail dot com CC: kirshamir at gmail dot com Target Milestone: --- The second static_assert below fails, should pass: #include struct F { F() { } F(const std::tuple& foo) {} }; static_assert(std::is_constructible_v&>); static_assert(std::is_constructible_v>&>); // fails, unjustifiably int main() { F f1{std::tuple{F{}}}; auto tup = std::tuple{std::tuple{f1}}; F f2{tup}; // constructible } https://godbolt.org/z/3KfbxfhWE
[Bug libstdc++/100992] Wrong result for is_constructible for const ref of tuple of tuples
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100992 --- Comment #2 from Amir Kirsh --- Maybe a dup of: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96592
[Bug c++/104850] New: Instantiating a destructor for a template class too early, before the calling destructor is seen - rejects valid code
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104850 Bug ID: 104850 Summary: Instantiating a destructor for a template class too early, before the calling destructor is seen - rejects valid code Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kirshamir at gmail dot com Target Milestone: --- The following code is rejected as trying to use incomplete type, while when the actual use would actually appear the type would be complete: template struct uptr { uptr(nullptr_t) {} ~uptr() { delete (new T); } }; class A { public: A(); ~A(); private: class B; uptr m_b = nullptr; // the dtor of uptr tries to be instantiated here }; If we change the initialization of: uptr m_b = nullptr; To: uptr m_b {nullptr}; The destructor instantiation is delayed, till ~A() is seen, and the code can be compiled. See: https://stackoverflow.com/questions/71397495/why-does-default-member-initializer-request-instantiation-of-unique-ptr-destru
[Bug c++/104850] Instantiating a destructor for a template class too early, before the calling destructor is seen - rejects valid code
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104850 --- Comment #2 from Amir Kirsh --- // adding the required include to the example #include // for nullptr_t template struct uptr { uptr(nullptr_t) {} ~uptr() { delete (new T); } }; class A { public: A(); ~A(); private: class B; uptr m_b = nullptr; // the dtor of uptr tries to be instantiated here }; https://wandbox.org/permlink/rJeeB3Sliey6tGzR If we change the initialization of: uptr m_b = nullptr; To: uptr m_b {nullptr}; Relevant SO post: https://stackoverflow.com/questions/71397495/why-does-default-member-initializer-request-instantiation-of-unique-ptr-destru/71402270#71402270
[Bug c++/67969] [concepts] bug with overloaded function when using constraints
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67969 Amir Kirsh changed: What|Removed |Added CC||kirshamir at gmail dot com --- Comment #4 from Amir Kirsh --- // Bug still exists in gcc 11.2 template concept SmallVar = (sizeof(T) <= sizeof(int)); void print(SmallVar auto t) { std::cout << t << std::endl; } void print(const auto& t) { std::cout << t << std::endl; } int main() { static_assert(SmallVar); // ok static_assert(SmallVar); // ok static_assert(!SmallVar); // ok print("hello"); print('a'); // gcc 11.2 sees here ambiguity print(6); // gcc 11.2 sees here ambiguity } Code: https://godbolt.org/z/jq8edKM3E
[Bug c++/106094] New: Lifetime extension of temporary do not obey some rules of [class.temporary]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106094 Bug ID: 106094 Summary: Lifetime extension of temporary do not obey some rules of [class.temporary] Product: gcc Version: 12.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kirshamir at gmail dot com Target Milestone: --- The simple cases of lifetime extension are working. But all below do not obey the rules. Lifetime should have been extended and it is not. // casting (non user-defined) + member access const auto& a1 = static_cast(A("a1")).ptr; // casting (non user-defined) + member access const auto& a2 = ((const A&&)A("a2")).arr; // casting (non user-defined) + member access const auto& a3 = const_cast(A("a3")).str; // a pointer to a member + extending lifetime access const auto& arr_member = &A::arr; const auto& a4 = (A("a4").*arr_member)[0]; const auto& str_member = &A::str; const auto& a5 = A("a5").*str_member; const auto& ptr_member = &A::ptr; const auto& a6 = A("a6").*ptr_member; Code: https://godbolt.org/z/jeeoefhPr Rules: https://timsong-cpp.github.io/cppwp/n4868/class.temporary#6
[Bug c++/117317] New: An internal compiler error on call to virtual constexpr function via comparison operator in CRTP with multiple inheritance
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117317 Bug ID: 117317 Summary: An internal compiler error on call to virtual constexpr function via comparison operator in CRTP with multiple inheritance Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kirshamir at gmail dot com Target Milestone: --- The following code results with internal compiler error: class Base { public: constexpr bool operator==(const Base& b) const { return getIdentity() == b.getIdentity(); } private: constexpr virtual int getIdentity() const = 0; }; template class Comparable: public Base1, public AdditionalBases... { public: constexpr bool operator==(const Comparable&) const = default; private: constexpr int getIdentity() const override { return 1; } }; class A: public Comparable {}; class B: public Comparable {}; class AB: public Comparable {}; int main() { constexpr AB ab_1; constexpr AB ab_2; // internal compiler error :-( static_assert(ab_1 == ab_2); } = Error: : In instantiation of 'constexpr int Comparable::getIdentity() const [with ActualType = AB; Base1 = A; AdditionalBases = {B}]': :4:27: required from here 4 | return getIdentity() == b.getIdentity(); |~~~^~ :31:24: in 'constexpr' expansion of 'ab_1.AB::Comparable.Comparable::operator==(ab_2.AB::Comparable)' :13:20: in 'constexpr' expansion of '((const Comparable*)this)->Comparable::A.A::Comparable.Comparable::operator==(.Comparable::A.A::Comparable)' :13:20: in 'constexpr' expansion of '((const Comparable*)this)->Comparable::Base.Base::operator==(.Comparable::Base)' :17:5: internal compiler error: in use_thunk, at cp/method.cc:324 17 | } | ^ 0x287e175 diagnostic_context::diagnostic_impl(rich_location*, diagnostic_metadata const*, diagnostic_option_id, char const*, __va_list_tag (*) [1], diagnostic_t) ???:0 0x28945d5 internal_error(char const*, ...) ???:0 0xa90ace fancy_abort(char const*, int, char const*) ???:0 0xd1eb6b emit_associated_thunks(tree_node*) ???:0 0xd1ed0e expand_or_defer_fn(tree_node*) ???:0 0xcc60cd instantiate_decl(tree_node*, bool, bool) ???:0 0xb08a50 maybe_constant_value(tree_node*, tree_node*, mce_value) ???:0 0xd23df0 finish_static_assert(tree_node*, tree_node*, unsigned int, bool, bool) ???:0 0xc9e57a c_parse_file() ???:0 0xdf7f99 c_common_parse_file() ???:0 -- Notes: 1. Code compiles with clang: https://godbolt.org/z/j8oMxar8o 2. Removing the constexpr or the virtual from getIdentity() - code compiles: https://godbolt.org/z/G5nMnWMd9 and https://godbolt.org/z/f3PWez1sb 3. Without CRTP code compiles: https://godbolt.org/z/56ah81n6h
[Bug c++/117317] An internal compiler error on call to virtual constexpr function via comparison operator in CRTP with multiple inheritance
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117317 --- Comment #1 from Amir Kirsh --- A more simple example, same internal compiler error: class Base { public: constexpr bool operator==(const Base& b) const { return getIdentity() == b.getIdentity(); } private: constexpr virtual int getIdentity() const = 0; }; template class Comparable: public Base1, public Base2 { public: constexpr bool operator==(const Comparable&) const = default; private: constexpr int getIdentity() const override { return 1; } }; class A: public Base {}; class B: public Base {}; class AB: public Comparable {}; int main() { constexpr AB ab_1; constexpr AB ab_2; // internal compiler error :-( static_assert(ab_1 == ab_2); } Error: : In instantiation of 'constexpr int Comparable::getIdentity() const [with ActualType = AB; Base1 = A; Base2 = B]': :4:27: required from here 4 | return getIdentity() == b.getIdentity(); |~~~^~ :31:24: in 'constexpr' expansion of 'ab_1.AB::Comparable.Comparable::operator==(ab_2.AB::Comparable)' :13:20: in 'constexpr' expansion of '((const Comparable*)this)->Comparable::A.A::Base.Base::operator==(.Comparable::A.A::Base)' :17:5: internal compiler error: in use_thunk, at cp/method.cc:324 17 | } | ^ 0x287e175 diagnostic_context::diagnostic_impl(rich_location*, diagnostic_metadata const*, diagnostic_option_id, char const*, __va_list_tag (*) [1], diagnostic_t) ???:0 0x28945d5 internal_error(char const*, ...) ???:0 0xa90ace fancy_abort(char const*, int, char const*) ???:0 0xd1eb6b emit_associated_thunks(tree_node*) ???:0 0xd1ed0e expand_or_defer_fn(tree_node*) ???:0 0xcc60cd instantiate_decl(tree_node*, bool, bool) ???:0 0xb08a50 maybe_constant_value(tree_node*, tree_node*, mce_value) ???:0 0xd23df0 finish_static_assert(tree_node*, tree_node*, unsigned int, bool, bool) ???:0 0xc9e57a c_parse_file() ???:0 0xdf7f99 c_common_parse_file() ???:0 Code: https://godbolt.org/z/4x9bMYPhj Compiles with clang And still, it compiles without the template: https://godbolt.org/z/Wecqz9YW1