From patchwork Thu Mar 10 02:59:09 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 86182 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3425AB6F91 for ; Thu, 10 Mar 2011 13:59:19 +1100 (EST) Received: (qmail 28373 invoked by alias); 10 Mar 2011 02:59:16 -0000 Received: (qmail 28364 invoked by uid 22791); 10 Mar 2011 02:59:15 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 10 Mar 2011 02:59:11 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p2A2xASV018971 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 9 Mar 2011 21:59:10 -0500 Received: from [127.0.0.1] (ovpn-113-58.phx2.redhat.com [10.3.113.58]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p2A2x9CE010956 for ; Wed, 9 Mar 2011 21:59:09 -0500 Message-ID: <4D783E7D.2060409@redhat.com> Date: Wed, 09 Mar 2011 21:59:09 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Lightning/1.0b2 Thunderbird/3.1.7 MIME-Version: 1.0 To: gcc-patches List Subject: RFA (layout): PATCH for c++/48029 (ICE-on-valid with templates and arrays) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org In this testcase, when we first declare the myvectypes and mytype3, vector has not been instantiated, so we mark the array, and the pointer to the array, for structural equality comparison. When we actually go to instantiate mytype3, we complete vector and rebuild the array and pointer types, and use those to look up the template specialization. Which fails to find the one we already had because the new pointer type has TYPE_CANONICAL and therefore hashes differently from the one that didn't. We deal with ARRAY_TYPE specially in iterative_hash_template_arg, but that doesn't cover a compound type which uses an ARRAY_TYPE, such as the pointer in this case. The business of having an array with the same element type and domain have different TYPE_CANONICAL dependending on whether or not the element type is complete has always seemed strange and fragile to me, so I tried removing the relevant code from layout_type; this produced only a single test failure, which was fixed by changing type_hash_eq to not trust TYPE_ALIGN if the type isn't complete yet. I imagine that's what Doug was talking about in his comment about alignment. Tested (c,c++,fortran,java,lto,objc) x86_64-pc-linux-gnu. OK for 4.5 and 4.6? commit 45deb1cd5953c5730e14e00c5a8f800dadea66bd Author: Jason Merrill Date: Wed Mar 9 16:47:10 2011 -0500 PR c++/48029 * stor-layout.c (layout_type): Don't set structural equality on arrays of incomplete type. * tree.c (type_hash_eq): Handle comparing them properly. * cp/pt.c (iterative_hash_template_arg): Remove special case for ARRAY_TYPE. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ac91698..ab2aea3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1569,13 +1569,6 @@ iterative_hash_template_arg (tree arg, hashval_t val) val = iterative_hash_object (code, val); return iterative_hash_template_arg (TREE_OPERAND (arg, 2), val); - case ARRAY_TYPE: - /* layout_type sets structural equality for arrays of - incomplete type, so we can't rely on the canonical type - for hashing. */ - val = iterative_hash_template_arg (TREE_TYPE (arg), val); - return iterative_hash_template_arg (TYPE_DOMAIN (arg), val); - case LAMBDA_EXPR: /* A lambda can't appear in a template arg, but don't crash on erroneous input. */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 9056d7e..ed36c5b 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -2028,11 +2028,6 @@ layout_type (tree type) #else TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT); #endif - if (!TYPE_SIZE (element)) - /* We don't know the size of the underlying element type, so - our alignment calculations will be wrong, forcing us to - fall back on structural equality. */ - SET_TYPE_STRUCTURAL_EQUALITY (type); TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element); SET_TYPE_MODE (type, BLKmode); if (TYPE_SIZE (type) != 0 diff --git a/gcc/tree.c b/gcc/tree.c index c947072..61532db 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5981,12 +5981,18 @@ type_hash_eq (const void *va, const void *vb) || TREE_TYPE (a->type) != TREE_TYPE (b->type) || !attribute_list_equal (TYPE_ATTRIBUTES (a->type), TYPE_ATTRIBUTES (b->type)) - || TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type) - || TYPE_MODE (a->type) != TYPE_MODE (b->type) || (TREE_CODE (a->type) != COMPLEX_TYPE && TYPE_NAME (a->type) != TYPE_NAME (b->type))) return 0; + /* Be careful about comparing arrays before and after the element type + has been completed; don't compare TYPE_ALIGN unless both types are + complete. */ + if (TYPE_SIZE (a->type) && TYPE_SIZE (b->type) + && (TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type) + || TYPE_MODE (a->type) != TYPE_MODE (b->type))) + return 0; + switch (TREE_CODE (a->type)) { case VOID_TYPE: