From patchwork Mon Oct 22 22:45:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C++] PR 54922 Date: Mon, 22 Oct 2012 12:45:03 -0000 From: Paolo Carlini X-Patchwork-Id: 193298 Message-Id: <5085CC6F.8000908@oracle.com> To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill Hi, today I spent quite a bit of time on this reject legal issue filed by Daniel, having to do with constrexpr constructors and anonymous union members: I didn't want to make the loop much more complex but we have to handle correctly multiple anonymous union too and of course produce correct diagnostics in all cases (eg, together with multiple members initialization diagnostics too). I figured out the below. Tested x86_64-linux, as usual. Thanks, Paolo. //////////////////////// /cp 2012-10-22 Paolo Carlini PR c++/54922 * semantics.c (cx_check_missing_mem_inits): Handle anonymous union members. /testsuite 2012-10-22 Paolo Carlini PR c++/54922 * g++.dg/cpp0x/constexpr-union4.C: New. Index: testsuite/g++.dg/cpp0x/constexpr-union4.C =================================================================== --- testsuite/g++.dg/cpp0x/constexpr-union4.C (revision 0) +++ testsuite/g++.dg/cpp0x/constexpr-union4.C (working copy) @@ -0,0 +1,13 @@ +// PR c++/54922 +// { dg-do compile { target c++11 } } + +class nullable_int +{ + bool init_; + union { + unsigned char for_value_init; + int value_; + }; +public: + constexpr nullable_int() : init_(false), for_value_init() {} +}; Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 192692) +++ cp/semantics.c (working copy) @@ -6139,17 +6139,23 @@ cx_check_missing_mem_inits (tree fun, tree body, b for (i = 0; i <= nelts; ++i) { tree index; + tree anon_union_init_type = NULL_TREE; if (i == nelts) index = NULL_TREE; else { index = CONSTRUCTOR_ELT (body, i)->index; + /* Handle anonymous union members. */ + if (TREE_CODE (index) == COMPONENT_REF + && ANON_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (index, 0)))) + anon_union_init_type = TREE_TYPE (TREE_OPERAND (index, 0)); /* Skip base and vtable inits. */ - if (TREE_CODE (index) != FIELD_DECL - || DECL_ARTIFICIAL (index)) + else if (TREE_CODE (index) != FIELD_DECL + || DECL_ARTIFICIAL (index)) continue; } - for (; field != index; field = DECL_CHAIN (field)) + for (; field != index && TREE_TYPE (field) != anon_union_init_type; + field = DECL_CHAIN (field)) { tree ftype; if (TREE_CODE (field) != FIELD_DECL