Re: [C++ Patch/RFC] PR 60047
On 02/06/2014 02:59 AM, Paolo Carlini wrote: - if (vec_safe_is_empty (vbases)) + if (vbases == NULL) vec_safe_is_empty is still more correct here. The rest of the patch is OK. Jason
[Ping] Re: [C++ Patch/RFC] PR 60047
Hi, the last version of this work is unreviewed, should be rather straightforward... Paolo.
Re: [C++ Patch/RFC] PR 60047
Hi, On 02/05/2014 10:28 PM, Jason Merrill wrote: On 02/05/2014 11:19 AM, Paolo Carlini wrote: if (vec_safe_is_empty (vbases)) /* No virtual bases to worry about. */; else if (!assign_p) { if (constexpr_p) *constexpr_p = false; *constexpr_p should be false for a constructor of a class with virtual bases, according to the standard (7.1.5p4): The definition of a constexpr constructor shall satisfy the following constraints: — the class shall not have any virtual base classes; ... So the assert in implicit_declare_fn is wrong. I guess I would fix it by checking CLASSTYPE_VBASECLASSES. Ah! It didn't occur to me that the bug could be in the gcc_assert itself. Thus, thanks, I tested on x86_64-linux the below. Paolo. // /cp 2014-02-06 Paolo Carlini PR c++/60047 * method.c (implicitly_declare_fn): A constructor of a class with virtual base classes isn't constexpr (7.1.5p4). (synthesized_method_walk): Revert PR58871 change. /testsuite 2014-02-06 Paolo Carlini PR c++/60047 * g++.dg/cpp0x/pr60047.C: New. Index: cp/method.c === --- cp/method.c (revision 207536) +++ cp/method.c (working copy) @@ -1366,7 +1366,7 @@ synthesized_method_walk (tree ctype, special_funct } vbases = CLASSTYPE_VBASECLASSES (ctype); - if (vec_safe_is_empty (vbases)) + if (vbases == NULL) /* No virtual bases to worry about. */; else if (!assign_p) { @@ -1656,10 +1656,12 @@ implicitly_declare_fn (special_function_kind kind, /* Don't bother marking a deleted constructor as constexpr. */ if (deleted_p) constexpr_p = false; - /* A trivial copy/move constructor is also a constexpr constructor. */ + /* A trivial copy/move constructor is also a constexpr constructor, + unless the class has virtual bases (7.1.5p4). */ else if (trivial_p && cxx_dialect >= cxx11 && (kind == sfk_copy_constructor - || kind == sfk_move_constructor)) + || kind == sfk_move_constructor) + && !CLASSTYPE_VBASECLASSES (type)) gcc_assert (constexpr_p); if (!trivial_p && type_has_trivial_fn (type, kind)) Index: testsuite/g++.dg/cpp0x/pr60047.C === --- testsuite/g++.dg/cpp0x/pr60047.C(revision 0) +++ testsuite/g++.dg/cpp0x/pr60047.C(working copy) @@ -0,0 +1,14 @@ +// PR c++/60047 +// { dg-do compile { target c++11 } } + +struct B { }; + +template struct A : virtual B +{ + A(); + A(const A&); +}; + +template A::A(const A&) = default; + +A a = A();
Re: [C++ Patch/RFC] PR 60047
On 02/05/2014 11:19 AM, Paolo Carlini wrote: if (vec_safe_is_empty (vbases)) /* No virtual bases to worry about. */; else if (!assign_p) { if (constexpr_p) *constexpr_p = false; *constexpr_p should be false for a constructor of a class with virtual bases, according to the standard (7.1.5p4): The definition of a constexpr constructor shall satisfy the following constraints: — the class shall not have any virtual base classes; ... So the assert in implicit_declare_fn is wrong. I guess I would fix it by checking CLASSTYPE_VBASECLASSES. Jason
Re: [C++ Patch/RFC] PR 60047
Hi, On 02/04/2014 12:51 PM, Paolo Carlini wrote: Hi, thus I tried to have a look to this issue, while experiencing some weird problems with the debugger, which slowed me down a lot. I have been able to figure out that we don't seem to actively set constexpr_p to true anywhere in implicitly_declare_fn (besides the unrelated case of inheriting constructors), thus I'm wondering if it would make sense to simply do the below?!? (and revert my recent tweak) I spent a little more time on this. Outside the case of inheriting constructors and the special case of expected_trivial default constructors (which are handled in a special conditional), we are normally assigning true to constexpr_p only in one place, that is close to the beginning of synthesized_method_walk: /* If that user-written default constructor would satisfy the requirements of a constexpr constructor (7.1.5), the implicitly-defined default constructor is constexpr. */ if (constexpr_p) *constexpr_p = ctor_p; then, for the testcase at issue it becomes false in the place which we already discussed for the ICE: if (vec_safe_is_empty (vbases)) /* No virtual bases to worry about. */; else if (!assign_p) { if (constexpr_p) *constexpr_p = false; Then it doesn't gets a chance to return true. Thus, given the more accurate analysis, I think that we either do what I quickly proposed yesterday, or alternately, the only option I can see, we change process_subob_fn to set it to true in some cases (but I note that it does never set to true trivial_p). Thanks, Paolo.
[C++ Patch/RFC] PR 60047
Hi, thus I tried to have a look to this issue, while experiencing some weird problems with the debugger, which slowed me down a lot. I have been able to figure out that we don't seem to actively set constexpr_p to true anywhere in implicitly_declare_fn (besides the unrelated case of inheriting constructors), thus I'm wondering if it would make sense to simply do the below?!? (and revert my recent tweak) Otherwise, Jason, if you suspect something deeper is going on, I would rather ask you to take over, today the debugger is still misbehaving on me :( Thanks! Paolo. // Index: cp/method.c === --- cp/method.c (revision 207457) +++ cp/method.c (working copy) @@ -1366,7 +1366,7 @@ synthesized_method_walk (tree ctype, special_funct } vbases = CLASSTYPE_VBASECLASSES (ctype); - if (vec_safe_is_empty (vbases)) + if (vbases == NULL) /* No virtual bases to worry about. */; else if (!assign_p) { @@ -1660,7 +1660,7 @@ implicitly_declare_fn (special_function_kind kind, else if (trivial_p && cxx_dialect >= cxx11 && (kind == sfk_copy_constructor || kind == sfk_move_constructor)) -gcc_assert (constexpr_p); +constexpr_p = true; if (!trivial_p && type_has_trivial_fn (type, kind)) type_set_nontrivial_flag (type, kind); Index: testsuite/g++.dg/cpp0x/pr60047.C === --- testsuite/g++.dg/cpp0x/pr60047.C(revision 0) +++ testsuite/g++.dg/cpp0x/pr60047.C(working copy) @@ -0,0 +1,14 @@ +// PR c++/60047 +// { dg-do compile { target c++11 } } + +struct B { }; + +template struct A : virtual B +{ + A(); + A(const A&); +}; + +template A::A(const A&) = default; + +A a = A();