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

isj-bugzilla at i1 dot dk gcc-bugzilla@gcc.gnu.org
Sat Jan 12 02:38:00 GMT 2019


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<Value, std::allocator<Value> > 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 <vector>

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>;

        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---


More information about the Gcc-bugs mailing list