[Bug c++/97288] New: Assignment sequence before order - evaluating reference to value of right side not in order

2020-10-04 Thread kirshamir at gmail dot com via Gcc-bugs
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

2020-10-04 Thread kirshamir at gmail dot com via Gcc-bugs
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

2021-01-10 Thread kirshamir at gmail dot com via Gcc-bugs
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

2021-01-10 Thread kirshamir at gmail dot com via Gcc-bugs
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

2021-02-19 Thread kirshamir at gmail dot com via Gcc-bugs
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

2021-05-30 Thread kirshamir at gmail dot com via Gcc-bugs
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

2021-05-30 Thread kirshamir at gmail dot com via Gcc-bugs
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

2021-06-09 Thread kirshamir at gmail dot com via Gcc-bugs
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

2021-06-09 Thread kirshamir at gmail dot com via Gcc-bugs
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

2022-03-08 Thread kirshamir at gmail dot com via Gcc-bugs
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

2022-03-09 Thread kirshamir at gmail dot com via Gcc-bugs
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

2022-01-31 Thread kirshamir at gmail dot com via Gcc-bugs
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]

2022-06-26 Thread kirshamir at gmail dot com via Gcc-bugs
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

2024-10-27 Thread kirshamir at gmail dot com via Gcc-bugs
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

2024-10-27 Thread kirshamir at gmail dot com via Gcc-bugs
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