[Bug c++/88816] New: Constructor calls itself recursively

2019-01-11 Thread isj-bugzilla at i1 dot dk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88816

Bug ID: 88816
   Summary: Constructor calls itself recursively
   Product: gcc
   Version: 8.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: isj-bugzilla at i1 dot dk
  Target Milestone: ---

In the reduced code below the constructor
Value::Value(std::vector > const&)
calls itself in the generated code leading to stack overflow. There is no such
recursive call in the source code.
Bug produced with versions 7.3.1, 8.2.1. And "trunk" on godbolt.org.
Bug is absent with clang, mscv, and icc.

Optimization and debug levels are irrelevant. It just have so have -std=c++11
or later.

---snip---
#include 

enum class value_type_t {
array,
null,
};

class Value {
void clear() {
switch(value_type) {
case value_type_t::array:
u.array_elements.~array_type();
break;
case value_type_t::null:
break;
}
value_type = value_type_t::null;
}
public:
using array_type = std::vector;

value_type_t value_type;
union U {
U() {}
~U() {}
array_type array_elements;
} u;

Value()
  : value_type{value_type_t::null}
{}

Value(const Value &v)
  : value_type{value_type_t::null}
{
*this = v;
}

//This is the constructor that unexpectedly calls itself
Value(const array_type &a) {
new(&u.array_elements) array_type{a};
value_type = value_type_t::array;
}

~Value() {
clear();
}


Value& operator=(const Value &v) {
if(this!=&v) {
clear();
switch(v.value_type) {
case value_type_t::array:
new(&u.array_elements)
array_type{v.u.array_elements};
value_type = value_type_t::array;
return *this;
case value_type_t::null:
value_type = value_type_t::null;
break;
}
}
return *this;
}

};


int main(void) {
Value v{Value::array_type{}};
}
---snip---

[Bug c++/88816] Constructor calls itself recursively

2019-01-12 Thread isj-bugzilla at i1 dot dk
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88816

--- Comment #3 from Ivan Skytte Jørgensen  ---
Ohhh...! Thank you for the explanation.

That was not at all obvious to me. It would be great if GCC detected it and
warned "brace-initializing a std:vector with a single std::vector may not do
what you think it does, depending on user-defined conversion constructors"