From patchwork Mon Apr 10 20:35:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 749211 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3w224v3sh9z9sDG for ; Tue, 11 Apr 2017 06:35:42 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Wf1J1UIJ"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=uBkgstS63uBTqqyZk7f0M8WSCRr/a kTIXA9fQc/hYgNg/QxrhYLk0P6JSVLDrabavsJTYHJGYZDPQwWXGgVKz+5MadTCB jTOzIU4+6gZf/6dAz08Y+RSdLPdRStMgGGRkX2h6xK5LEUq6DJF+u/ICxZy2pTPa KP+etD4DTQ2XEA= 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:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=wksZlBxpZKFfCGqiJCbsWkLmq3k=; b=Wf1 J1UIJTI1yVQEGICsImhmMstZ4NaoGO/ci/wiT8q2/IkjUQo8F0Gy+zOnfa536bwK cG6RnyvJ6jRPz1PX8Sbk8R4y5Q32UEE+BiHZCyHjfo2Qpm9w0gNzJeDlJqOnNEnJ pMZ9Jx7fvz7bI5dLcJ8ePk97zXvp4UvD1TvM+AJ4= Received: (qmail 126594 invoked by alias); 10 Apr 2017 20:35:07 -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 126535 invoked by uid 89); 10 Apr 2017 20:35:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=finalize X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 10 Apr 2017 20:35:05 +0000 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 525F281236 for ; Mon, 10 Apr 2017 20:35:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 525F281236 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 525F281236 Received: from tucnak.zalov.cz (ovpn-116-29.ams2.redhat.com [10.36.116.29]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EDAE878C17; Mon, 10 Apr 2017 20:35:04 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id v3AKZ2Kh004708; Mon, 10 Apr 2017 22:35:03 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id v3AKZ2VS004707; Mon, 10 Apr 2017 22:35:02 +0200 Date: Mon, 10 Apr 2017 22:35:02 +0200 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370) Message-ID: <20170410203502.GJ1809@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.1 (2016-10-04) X-IsSubscribed: yes Hi! The following testcase ICEs, because when cp_finish_decomp is called during parsing with processing_template_decl, but decl is not type dependent, we finalize it at that point and when we try to do it again during tsubst time, it doesn't find the expected trees (e.g. DECL_VALUE_EXPR of the expected form on the corresponding user decls). The following patch changes cp_finish_decomp processing_template_decl handling when decl is not type dependent, such that it performs diagnostics and sets types on the individual decls, but doesn't otherwise finalize them (modify their DECL_VALUE_EXPR or clear them and cp_finish_decl them). I think this way we can treat the decls as no longer type dependent, but will let the final decomp finalization still to tsubst time. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-04-10 Jakub Jelinek PR c++/80370 * decl.c (cp_finish_decomp): If processing_template_decl on non-dependent decl, only set TREE_TYPE on the v[i] decls, but don't change their DECL_VALUE_EXPR nor cp_finish_decl them. Instead make sure DECL_VALUE_EXPR is the canonical NULL type ARRAY_REF for tsubst processing. * constexpr.c (cxx_eval_constant_expression) : Don't recurse on DECL_VALUE_EXPR if the value expr has NULL type on a decomposition decl. * g++.dg/cpp1z/decomp28.C: New test. Jakub --- gcc/cp/decl.c.jj 2017-03-30 15:24:22.000000000 +0200 +++ gcc/cp/decl.c 2017-04-10 12:15:44.156022403 +0200 @@ -7473,6 +7473,8 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); + if (processing_template_decl) + continue; tree t = unshare_expr (dexp); t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF, eltype, t, size_int (i), NULL_TREE, @@ -7492,6 +7494,8 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); + if (processing_template_decl) + continue; tree t = unshare_expr (dexp); t = build1_loc (DECL_SOURCE_LOCATION (v[i]), i ? IMAGPART_EXPR : REALPART_EXPR, eltype, @@ -7510,6 +7514,8 @@ cp_finish_decomp (tree decl, tree first, { TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); + if (processing_template_decl) + continue; tree t = unshare_expr (dexp); convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]), &t, size_int (i)); @@ -7549,7 +7555,8 @@ cp_finish_decomp (tree decl, tree first, goto error_out; } /* Save the decltype away before reference collapse. */ - store_decomp_type (v[i], eltype); + if (!processing_template_decl) + store_decomp_type (v[i], eltype); eltype = cp_build_reference_type (eltype, !lvalue_p (init)); TREE_TYPE (v[i]) = eltype; layout_decl (v[i], 0); @@ -7559,8 +7566,9 @@ cp_finish_decomp (tree decl, tree first, SET_DECL_VALUE_EXPR (v[i], NULL_TREE); DECL_HAS_VALUE_EXPR_P (v[i]) = 0; } - cp_finish_decl (v[i], init, /*constexpr*/false, - /*asm*/NULL_TREE, LOOKUP_NORMAL); + if (!processing_template_decl) + cp_finish_decl (v[i], init, /*constexpr*/false, + /*asm*/NULL_TREE, LOOKUP_NORMAL); } } else if (TREE_CODE (type) == UNION_TYPE) @@ -7615,12 +7623,26 @@ cp_finish_decomp (tree decl, tree first, tt = TREE_OPERAND (tt, 0); TREE_TYPE (v[i]) = TREE_TYPE (tt); layout_decl (v[i], 0); - SET_DECL_VALUE_EXPR (v[i], tt); - DECL_HAS_VALUE_EXPR_P (v[i]) = 1; + if (!processing_template_decl) + { + SET_DECL_VALUE_EXPR (v[i], tt); + DECL_HAS_VALUE_EXPR_P (v[i]) = 1; + } i++; } } - if (DECL_NAMESPACE_SCOPE_P (decl)) + if (processing_template_decl) + { + for (unsigned int i = 0; i < count; i++) + if (!DECL_HAS_VALUE_EXPR_P (v[i])) + { + tree a = build_nt (ARRAY_REF, decl, size_int (i), + NULL_TREE, NULL_TREE); + SET_DECL_VALUE_EXPR (v[i], a); + DECL_HAS_VALUE_EXPR_P (v[i]) = 1; + } + } + else if (DECL_NAMESPACE_SCOPE_P (decl)) SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v)); } --- gcc/cp/constexpr.c.jj 2017-03-21 07:57:00.000000000 +0100 +++ gcc/cp/constexpr.c 2017-04-10 12:24:11.849717112 +0200 @@ -3935,7 +3935,10 @@ cxx_eval_constant_expression (const cons return (*ctx->values->get (t)); case VAR_DECL: - if (DECL_HAS_VALUE_EXPR_P (t)) + if (DECL_HAS_VALUE_EXPR_P (t) + /* Don't recurse on DECL_VALUE_EXPR of decomposition decls + that have not been finalized yet. */ + && (!DECL_DECOMPOSITION_P (t) || TREE_TYPE (DECL_VALUE_EXPR (t)))) return cxx_eval_constant_expression (ctx, DECL_VALUE_EXPR (t), lval, non_constant_p, overflow_p); /* fall through */ --- gcc/testsuite/g++.dg/cpp1z/decomp28.C.jj 2017-04-10 11:40:39.209346743 +0200 +++ gcc/testsuite/g++.dg/cpp1z/decomp28.C 2017-04-10 11:42:15.939128016 +0200 @@ -0,0 +1,39 @@ +// PR c++/80370 +// { dg-do compile { target c++14 } } +// { dg-options "" } + +namespace std { + template struct tuple_size; + template struct tuple_element; + template struct tuple {}; + template struct tuple_size> { static constexpr int value = 1; }; + template struct tuple_element<0, tuple> { typedef T type; }; + template int& get (tuple); +} + +template +void +foo (std::tuple b) +{ + auto [c] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +} + +template +void +bar (std::tuple b) +{ + auto [c] = b; // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +} + +void +baz (std::tuple b) +{ + foo <5> (b); + bar (b); +} + +int +main () +{ + [](auto) { [](std::tuple b) { auto[c] = b; }; } (0); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } } +}