From patchwork Tue Nov 28 18:27:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 842250 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-468112-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ROAxXuxs"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ymXGp40Z5z9sBd for ; Wed, 29 Nov 2017 05:28:17 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=STu9XvudsFwRdcty1D/hsJbVn6a9rvfN9A7oNArCG0YoKXhPWR cNKoAKJB39MMLrOYP4h89P3IW5+agJdY18i0giyqxhQ904ck+iT+Fa9Q+7zfLAtY WtNDbvFHtQhov1/BFlJNPQuD0u4KA9XZpVJiKTLYK8pCkDKlr/F1zIzHo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=c91fRBkhfzR8R7vPpZS6ChlB/hs=; b=ROAxXuxsgYD4d0IIgo2v zoNHwYZyDZiN98lNQxsSjiMnm99W+9mBTse6+ixpZ7lpyWtzfB5gexTHUGr7RADS h4qFPpMnLg7kWxD0i1pYTi4jYE/Qoiozl/peVF+LR/zlSpEum0zKR9g4m3xb1LTW l9hmlldHuoP5pNyMMNbla8U= Received: (qmail 7126 invoked by alias); 28 Nov 2017 18:28:05 -0000 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 Received: (qmail 7112 invoked by uid 89); 28 Nov 2017 18:28:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=proceeds X-HELO: mail-yb0-f173.google.com Received: from mail-yb0-f173.google.com (HELO mail-yb0-f173.google.com) (209.85.213.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 28 Nov 2017 18:27:58 +0000 Received: by mail-yb0-f173.google.com with SMTP id v12so336460ybj.5 for ; Tue, 28 Nov 2017 10:27:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:cc:from:subject:message-id:date :user-agent:mime-version:content-language; bh=Jdg2qIrUm0Y3A6oqULOqOPTU4z7LsEk7FCjlG6NrVPc=; b=oa5hMaN0mkyGWNvdw4JAQgRMVpZCg+p/vlB/Uvct3tVcPvCrSf8owI+7qIfi5122jw RlI3hU+OYS2A6NJa3VHAj3mk4zLRaf8utbAGANE7JfS1HNJAe5GlMtSE3Ppk+9sh245p TYby4tSxOhmPnGTZepsDN4xtIaUlnmyBz4DPFSkNSURR/PPo3eQCANDzEQ8er5GcxIfj FfQjubSdn/PNV+pzmzNn8meXKiz/DEsy4JpPhmMzzxIKxR0izCrlsIdLHxBr9Ld/Cu2R /6bxK7Evz5kXP3la1dChMZrdyqzMhVt6do8tWBLxMsU1LZGTMdk0dKPSVYqyPDaBc4mJ qyMg== X-Gm-Message-State: AJaThX5CzRigqGbYW4X9ES8tc5XRWk0LhuzqYF7Y5gpb9tlc6iMn23X+ UGB64aBOFMONes3F9vMEQog= X-Google-Smtp-Source: AGs4zMYCcMwE6Au76pAmD2sDyfhRE5uCaFgAQVONhCTf3ZI9j/+18zP7hxnR0P4RlFGu6Yhexs8k5w== X-Received: by 10.37.129.130 with SMTP id p2mr56368ybk.428.1511893676450; Tue, 28 Nov 2017 10:27:56 -0800 (PST) Received: from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254? ([2620:10d:c091:200::3:38a4]) by smtp.googlemail.com with ESMTPSA id x129sm8743791ywx.94.2017.11.28.10.27.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Nov 2017 10:27:55 -0800 (PST) To: GCC Patches Cc: Jakub Jelinek From: Nathan Sidwell Subject: [PATCH] complex type canonicalization Message-ID: <384ed945-83b4-b421-ab82-92b5e236d874@acm.org> Date: Tue, 28 Nov 2017 13:27:54 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 MIME-Version: 1.0 This patch fixes PR 83187, a C++ ICE with alias sets. As Jakub observed in the bug, we ended up with a type whose main variant's canonical type's main variant was not itself. That should be an invariant. In build_complex_type, we create a probe type: tree probe = make_node (COMPLEX_TYPE); TREE_TYPE (probe) = TYPE_MAIN_VARIANT (component_type); notice setting TREE_TYPE to main_variant of the component type. We then insert this into the canonical type hash (or find a match). I think my type hashing clean up exposed an underlying problem, when I changed: hstate.add_object (TYPE_HASH (component_type)); to hashval_t hash = type_hash_canon_hash (t); because that's abstractly better. However, build_complex_type then proceeds to do two strange things. 1) regardless of whether it added a new type to the hash table, it checks for t == CANONICAL (t) and if equal goes to recreate the canonical type. 2) but it checks the canonicalness of component_type, not TYPE_MAIN_VARIANT (component_type), which is what the newly created complex's TREE_TYPE was set to. #2 is where I think things are getting confused. Anyway, this patch simply moves all of the post-insertion setting after a check to see whether the insertion inserted the new type, (rather than find an existing variant). It also consistently uses TREE_TYPE (new_type), when looking at the component type in that context. booted on x86_64-linux-gnu. no C or C++ regressions. ok? nathan 2017-11-28 Nathan Sidwell PR c++/83817 * tree.c (build_complex_type): Fix canonicalization. Only fill in type if it is new. PR c++/83187 * g++.dg/opt/pr83187.C: New. Index: testsuite/g++.dg/opt/pr83187.C =================================================================== --- testsuite/g++.dg/opt/pr83187.C (revision 0) +++ testsuite/g++.dg/opt/pr83187.C (working copy) @@ -0,0 +1,32 @@ +// { dg-do compile { target c++11 } } +// { dg-additional-options "-O1 -Wno-pedantic" } +// PR c++/83187 ICE in get_alias_set due to canonical type confusion. + +extern "C" { + double cos (double); + double sin (double); +} + +template class COMPLEX; + +template <> +struct COMPLEX +{ + COMPLEX(double r, double i); + + __complex__ mem; +}; + +COMPLEX::COMPLEX (double r, double i) + : mem {r, i} {} + +typedef double dbl_t; + +dbl_t var; + +void foo (COMPLEX *ptr) +{ + const dbl_t unused = var; + + *ptr = COMPLEX (cos (var), sin (var)); +} Index: tree.c =================================================================== --- tree.c (revision 255202) +++ tree.c (working copy) @@ -8077,65 +8077,66 @@ build_offset_type (tree basetype, tree t tree build_complex_type (tree component_type, bool named) { - tree t; - gcc_assert (INTEGRAL_TYPE_P (component_type) || SCALAR_FLOAT_TYPE_P (component_type) || FIXED_POINT_TYPE_P (component_type)); /* Make a node of the sort we want. */ - t = make_node (COMPLEX_TYPE); + tree probe = make_node (COMPLEX_TYPE); - TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type); + TREE_TYPE (probe) = TYPE_MAIN_VARIANT (component_type); /* If we already have such a type, use the old one. */ - hashval_t hash = type_hash_canon_hash (t); - t = type_hash_canon (hash, t); - - if (!COMPLETE_TYPE_P (t)) - layout_type (t); + hashval_t hash = type_hash_canon_hash (probe); + tree t = type_hash_canon (hash, probe); - if (TYPE_CANONICAL (t) == t) + if (t == probe) { - if (TYPE_STRUCTURAL_EQUALITY_P (component_type)) + /* We created a new type. The hash insertion will have laid + out the type. We need to check the canonicalization and + maybe set the name. */ + gcc_checking_assert (COMPLETE_TYPE_P (t) + && !TYPE_NAME (t) + && TYPE_CANONICAL (t) == t); + + if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t))) SET_TYPE_STRUCTURAL_EQUALITY (t); - else if (TYPE_CANONICAL (component_type) != component_type) + else if (TYPE_CANONICAL (TREE_TYPE (t)) != TREE_TYPE (t)) TYPE_CANONICAL (t) - = build_complex_type (TYPE_CANONICAL (component_type), named); - } + = build_complex_type (TYPE_CANONICAL (TREE_TYPE (t)), named); - /* We need to create a name, since complex is a fundamental type. */ - if (!TYPE_NAME (t) && named) - { - const char *name; - if (component_type == char_type_node) - name = "complex char"; - else if (component_type == signed_char_type_node) - name = "complex signed char"; - else if (component_type == unsigned_char_type_node) - name = "complex unsigned char"; - else if (component_type == short_integer_type_node) - name = "complex short int"; - else if (component_type == short_unsigned_type_node) - name = "complex short unsigned int"; - else if (component_type == integer_type_node) - name = "complex int"; - else if (component_type == unsigned_type_node) - name = "complex unsigned int"; - else if (component_type == long_integer_type_node) - name = "complex long int"; - else if (component_type == long_unsigned_type_node) - name = "complex long unsigned int"; - else if (component_type == long_long_integer_type_node) - name = "complex long long int"; - else if (component_type == long_long_unsigned_type_node) - name = "complex long long unsigned int"; - else - name = 0; - - if (name != 0) - TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, - get_identifier (name), t); + /* We need to create a name, since complex is a fundamental type. */ + if (named) + { + const char *name = NULL; + + if (TREE_TYPE (t) == char_type_node) + name = "complex char"; + else if (TREE_TYPE (t) == signed_char_type_node) + name = "complex signed char"; + else if (TREE_TYPE (t) == unsigned_char_type_node) + name = "complex unsigned char"; + else if (TREE_TYPE (t) == short_integer_type_node) + name = "complex short int"; + else if (TREE_TYPE (t) == short_unsigned_type_node) + name = "complex short unsigned int"; + else if (TREE_TYPE (t) == integer_type_node) + name = "complex int"; + else if (TREE_TYPE (t) == unsigned_type_node) + name = "complex unsigned int"; + else if (TREE_TYPE (t) == long_integer_type_node) + name = "complex long int"; + else if (TREE_TYPE (t) == long_unsigned_type_node) + name = "complex long unsigned int"; + else if (TREE_TYPE (t) == long_long_integer_type_node) + name = "complex long long int"; + else if (TREE_TYPE (t) == long_long_unsigned_type_node) + name = "complex long long unsigned int"; + + if (name != NULL) + TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, + get_identifier (name), t); + } } return build_qualified_type (t, TYPE_QUALS (component_type));