From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14727 invoked by alias); 5 Jul 2010 20:47:40 -0000 Received: (qmail 14711 invoked by uid 22791); 5 Jul 2010 20:47:38 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rcsinet10.oracle.com (HELO rcsinet10.oracle.com) (148.87.113.121) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 05 Jul 2010 20:47:30 +0000 Received: from rcsinet13.oracle.com (rcsinet13.oracle.com [148.87.113.125]) by rcsinet10.oracle.com (Switch-3.4.2/Switch-3.4.2) with ESMTP id o65KlQEs008886 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 5 Jul 2010 20:47:27 GMT Received: from acsmt353.oracle.com (acsmt353.oracle.com [141.146.40.153]) by rcsinet13.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id o65BIihH000909; Mon, 5 Jul 2010 20:47:25 GMT Received: from abhmt018.oracle.com by acsmt353.oracle.com with ESMTP id 399074971278362734; Mon, 05 Jul 2010 13:45:34 -0700 Received: from [192.168.0.4] (/79.52.240.176) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 05 Jul 2010 13:45:33 -0700 Message-ID: <4C32446B.90807@oracle.com> Date: Mon, 05 Jul 2010 20:47:00 -0000 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100520 SUSE/3.0.5 Thunderbird/3.0.5 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: [C++ Patch] PR 44625, v2 References: <4C31C773.3050000@oracle.com> <4C31D9C7.9000209@redhat.com> <4C31DA00.5070100@oracle.com> In-Reply-To: <4C31DA00.5070100@oracle.com> Content-Type: multipart/mixed; boundary="------------070608020505080309050704" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2010-07/txt/msg00412.txt.bz2 This is a multi-part message in MIME format. --------------070608020505080309050704 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-length: 432 Hi again, this is my second try: the idea is avoiding completely creating COMPONENT_REFs with a null operand 1, as suggested by Jason. I also tidied a bit the original testcase and added a second for anonymous union inside anonymous union. About error17.C, we now emit one less diagnostic message, similarly to ICC, turns out. Tested x86_64-linux. Is this one better? Mainline only, in my opinion... Paolo. //////////////////// --------------070608020505080309050704 Content-Type: text/plain; name="CL_44625_2" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="CL_44625_2" Content-length: 375 /cp 2010-07-05 Paolo Carlini PR c++/44625 * decl2.c (build_anon_union_vars): Avoid creating COMPONENT_REFs with a null operand 1; tidy, reformat. /testsuite 2010-07-05 Paolo Carlini PR c++/44625 * g++.dg/template/crash102.C: New. * g++.dg/template/crash103.C: Likewise. * g++.dg/template/error17.C: Adjust. --------------070608020505080309050704 Content-Type: text/plain; name="patch_44625_2" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch_44625_2" Content-length: 4033 Index: testsuite/g++.dg/template/crash102.C =================================================================== --- testsuite/g++.dg/template/crash102.C (revision 0) +++ testsuite/g++.dg/template/crash102.C (revision 0) @@ -0,0 +1,19 @@ +// PR c++/44625 +// { dg-do compile } +// { dg-options "" } + +template struct Vec { + Vec& operator^=(Vec& rhs) { + union { + struct {FP_ x,y,z;}; + }; // { dg-error "anonymous struct" } + y*rhs.z() - z*rhs.y(); // { dg-error "not declared|no member" } + return *this; + } + Vec& operator^(Vec& rhs) { + return Vec(*this)^=rhs; // { dg-message "instantiated" } + } +}; +Vec v; +Vec V; +Vec c = v^V; // { dg-message "instantiated" } Index: testsuite/g++.dg/template/error17.C =================================================================== --- testsuite/g++.dg/template/error17.C (revision 161841) +++ testsuite/g++.dg/template/error17.C (working copy) @@ -4,7 +4,6 @@ template void foo() { - union { struct { }; }; // { dg-error "prohibits anonymous struct" "anon" } + union { struct { }; }; // { dg-error "prohibits anonymous struct" } // { dg-error "not inside" "not inside" { target *-*-* } 7 } - // { dg-warning "no members" "no members" { target *-*-* } 7 } } Index: testsuite/g++.dg/template/crash103.C =================================================================== --- testsuite/g++.dg/template/crash103.C (revision 0) +++ testsuite/g++.dg/template/crash103.C (revision 0) @@ -0,0 +1,19 @@ +// PR c++/44625 +// { dg-do compile } +// { dg-options "" } + +template struct Vec { + Vec& operator^=(Vec& rhs) { + union { + union {FP_ x,y,z;}; + }; + y*rhs.z() - z*rhs.y(); // { dg-error "not declared|no member" } + return *this; + } + Vec& operator^(Vec& rhs) { + return Vec(*this)^=rhs; // { dg-message "instantiated" } + } +}; +Vec v; +Vec V; +Vec c = v^V; // { dg-message "instantiated" } Index: cp/decl2.c =================================================================== --- cp/decl2.c (revision 161844) +++ cp/decl2.c (working copy) @@ -1319,40 +1319,50 @@ build_anon_union_vars (tree type, tree object) if (TREE_CODE (type) != UNION_TYPE) error ("anonymous struct not inside named type"); + if (!object) + return error_mark_node; + for (field = TYPE_FIELDS (type); field != NULL_TREE; field = TREE_CHAIN (field)) { tree decl; - tree ref; + tree ref = NULL_TREE; + tree name; if (DECL_ARTIFICIAL (field)) continue; if (TREE_CODE (field) != FIELD_DECL) { - permerror (input_location, "%q+#D invalid; an anonymous union can only " - "have non-static data members", field); + permerror (input_location, "%q+#D invalid; an anonymous union can " + "only have non-static data members", field); continue; } if (TREE_PRIVATE (field)) - permerror (input_location, "private member %q+#D in anonymous union", field); + permerror (input_location, "private member %q+#D in anonymous union", + field); else if (TREE_PROTECTED (field)) - permerror (input_location, "protected member %q+#D in anonymous union", field); + permerror (input_location, "protected member %q+#D in anonymous union", + field); + name = DECL_NAME (field); + if (processing_template_decl) - ref = build_min_nt (COMPONENT_REF, object, - DECL_NAME (field), NULL_TREE); + { + if (name) + ref = build_min_nt (COMPONENT_REF, object, name, NULL_TREE); + } else ref = build_class_member_access_expr (object, field, NULL_TREE, false, tf_warning_or_error); - if (DECL_NAME (field)) + if (name) { tree base; decl = build_decl (input_location, - VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); + VAR_DECL, name, TREE_TYPE (field)); DECL_ANON_UNION_VAR_P (decl) = 1; DECL_ARTIFICIAL (decl) = 1; --------------070608020505080309050704--