From patchwork Wed May 6 22:01:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1284811 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=ZrA+Z3Sy; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49HVt26gv1z9sP7 for ; Thu, 7 May 2020 08:01:28 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AFE50394844B; Wed, 6 May 2020 22:01:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AFE50394844B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1588802485; bh=ikycxkgCbcDBPxr/6duh5q30UgRC9RxDV/jEmN9CQdQ=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=ZrA+Z3SyetzgiwfhJs80U3myThXmgGssnki8d84708xlqajB1pVNOvsjF5kiNRKZH CSg6jCf7vdzN2kgIRosffIlA0mmxPzXpvmKupp1zzNxEhixYp5vQVycnV2jzNnvnKm gA9jpZ58g4/jRPyd6fCZk2+cXgdvlEa71jf1PC1I= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [80.241.56.172]) by sourceware.org (Postfix) with ESMTPS id 3394D386F819 for ; Wed, 6 May 2020 22:01:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 3394D386F819 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 49HVsh6rZxzQlHD; Thu, 7 May 2020 00:01:12 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter04.heinlein-hosting.de (spamfilter04.heinlein-hosting.de [80.241.56.122]) (amavisd-new, port 10030) with ESMTP id aJklYO9uOhGb; Thu, 7 May 2020 00:01:09 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Fix ICE in verify_gimple_stmt, at tree-cfg.c:4959 Date: Thu, 7 May 2020 00:01:06 +0200 Message-Id: <20200506220106.16842-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 8C8A2177D X-Rspamd-Score: -0.80 / 15.00 / 15.00 X-Spam-Status: No, score=-19.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_ABUSE_SURBL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch removes all related helper functions around BIND_EXPR generation in the D front-end, which were the cause of an ICE. Both array concat and array new expressions wrapped any temporaries created into a BIND_EXPR. This does not work if an expression used to construct the result requires scope destruction, which is represented by a TARGET_EXPR with a clean-up, and a CLEANUP_POINT_EXPR at the location where the temporaries logically go out of scope. The reason for this not working is because the lowering of cleanup point expressions does not traverse inside BIND_EXPRs to expand any gimple cleanup expressions within. The use of creating BIND_EXPR has been removed at both locations, and replaced with a normal temporary variable that has initialization delayed until its address is taken. Bootstrapped and regression tested on x86_64-linux-gnu with -m64,-m32,-mx32 target configurations. Comitted to mainline. Regards Iain --- gcc/d/ChangeLog: PR d/94970 * d-codegen.cc (force_target_expr): Move create_temporary_var implementation inline here. (create_temporary_var): Remove. (maybe_temporary_var): Remove. (bind_expr): Remove. * d-convert.cc (d_array_convert): Use build_local_temp to generate temporaries, and generate its assignment. * d-tree.h (create_temporary_var): Remove. (maybe_temporary_var): Remove. (d_array_convert): Remove vars argument. * expr.cc (ExprVisitor::visit (CatExp *)): Use build_local_temp to generate temporaries, don't wrap them in a BIND_EXPR. (ExprVisitor::visit (NewExp *)): Likewise. gcc/testsuite/ChangeLog: PR d/94970 * gdc.dg/pr94970.d: New test. --- gcc/d/d-codegen.cc | 67 +++------------------------------- gcc/d/d-convert.cc | 14 ++++--- gcc/d/d-tree.h | 4 +- gcc/d/expr.cc | 33 +++++++---------- gcc/testsuite/gdc.dg/pr94970.d | 20 ++++++++++ 5 files changed, 49 insertions(+), 89 deletions(-) create mode 100644 gcc/testsuite/gdc.dg/pr94970.d diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index b4927a2de10..5efd4b9c43c 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -619,7 +619,12 @@ build_target_expr (tree decl, tree exp) tree force_target_expr (tree exp) { - tree decl = create_temporary_var (TREE_TYPE (exp)); + tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, + TREE_TYPE (exp)); + DECL_CONTEXT (decl) = current_function_decl; + DECL_ARTIFICIAL (decl) = 1; + DECL_IGNORED_P (decl) = 1; + layout_decl (decl, 0); return build_target_expr (decl, exp); } @@ -1766,66 +1771,6 @@ array_bounds_check (void) } } -/* Return an undeclared local temporary of type TYPE - for use with BIND_EXPR. */ - -tree -create_temporary_var (tree type) -{ - tree decl = build_decl (input_location, VAR_DECL, NULL_TREE, type); - - DECL_CONTEXT (decl) = current_function_decl; - DECL_ARTIFICIAL (decl) = 1; - DECL_IGNORED_P (decl) = 1; - layout_decl (decl, 0); - - return decl; -} - -/* Return an undeclared local temporary OUT_VAR initialized - with result of expression EXP. */ - -tree -maybe_temporary_var (tree exp, tree *out_var) -{ - tree t = exp; - - /* Get the base component. */ - while (TREE_CODE (t) == COMPONENT_REF) - t = TREE_OPERAND (t, 0); - - if (!DECL_P (t) && !REFERENCE_CLASS_P (t)) - { - *out_var = create_temporary_var (TREE_TYPE (exp)); - DECL_INITIAL (*out_var) = exp; - return *out_var; - } - else - { - *out_var = NULL_TREE; - return exp; - } -} - -/* Builds a BIND_EXPR around BODY for the variables VAR_CHAIN. */ - -tree -bind_expr (tree var_chain, tree body) -{ - /* Only handles one var. */ - gcc_assert (TREE_CHAIN (var_chain) == NULL_TREE); - - if (DECL_INITIAL (var_chain)) - { - tree ini = build_assign (INIT_EXPR, var_chain, DECL_INITIAL (var_chain)); - DECL_INITIAL (var_chain) = NULL_TREE; - body = compound_expr (ini, body); - } - - return d_save_expr (build3 (BIND_EXPR, TREE_TYPE (body), - var_chain, body, NULL_TREE)); -} - /* Returns the TypeFunction class for Type T. Assumes T is already ->toBasetype(). */ diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc index e2921ec33f0..f93405ed956 100644 --- a/gcc/d/d-convert.cc +++ b/gcc/d/d-convert.cc @@ -774,21 +774,23 @@ d_array_convert (Expression *exp) /* Convert EXP to a dynamic array, where ETYPE is the element type. Similar to above, except that EXP is allowed to be an element of an array. - Temporary variables that need some kind of BIND_EXPR are pushed to VARS. */ + Temporary variables are created inline if EXP is not an lvalue. */ tree -d_array_convert (Type *etype, Expression *exp, vec **vars) +d_array_convert (Type *etype, Expression *exp) { Type *tb = exp->type->toBasetype (); if ((tb->ty != Tarray && tb->ty != Tsarray) || same_type_p (tb, etype)) { /* Convert single element to an array. */ - tree var = NULL_TREE; - tree expr = maybe_temporary_var (build_expr (exp), &var); + tree expr = build_expr (exp); - if (var != NULL_TREE) - vec_safe_push (*vars, var); + if (!exp->isLvalue ()) + { + tree var = build_local_temp (TREE_TYPE (expr)); + expr = compound_expr (modify_expr (var, expr), var); + } return d_array_value (build_ctype (exp->type->arrayOf ()), size_int (1), build_address (expr)); diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index 48587d96e38..33022055e3e 100644 --- a/gcc/d/d-tree.h +++ b/gcc/d/d-tree.h @@ -561,8 +561,6 @@ extern tree build_array_from_val (Type *, tree); extern tree void_okay_p (tree); extern tree build_bounds_condition (const Loc &, tree, tree, bool); extern bool array_bounds_check (void); -extern tree create_temporary_var (tree); -extern tree maybe_temporary_var (tree, tree *); extern tree bind_expr (tree, tree); extern TypeFunction *get_function_type (Type *); extern bool call_by_alias_p (FuncDeclaration *, FuncDeclaration *); @@ -586,7 +584,7 @@ extern tree convert_for_assignment (tree, Type *, Type *); extern tree convert_for_argument (tree, Parameter *); extern tree convert_for_condition (tree, Type *); extern tree d_array_convert (Expression *); -extern tree d_array_convert (Type *, Expression *, vec **); +extern tree d_array_convert (Type *, Expression *); /* In d-incpath.cc. */ extern void add_import_paths (const char *, const char *, bool); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 0ed50ee2d9e..d1e71f987f7 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -691,7 +691,6 @@ public: else etype = tb2->nextOf (); - vec *elemvars = NULL; tree result; if (e->e1->op == TOKcat) @@ -711,9 +710,7 @@ public: /* Store all concatenation args to a temporary byte[][ndims] array. */ Type *targselem = Type::tint8->arrayOf (); - tree var = create_temporary_var (make_array_type (targselem, ndims)); - tree init = build_constructor (TREE_TYPE (var), NULL); - vec_safe_push (elemvars, var); + tree var = build_local_temp (make_array_type (targselem, ndims)); /* Loop through each concatenation from right to left. */ vec *elms = NULL; @@ -725,7 +722,7 @@ public: ? (oe = ce->e1) : (ce = (CatExp *)ce->e1, oe = ce->e2))) { - tree arg = d_array_convert (etype, oe, &elemvars); + tree arg = d_array_convert (etype, oe); tree index = size_int (dim); CONSTRUCTOR_APPEND_ELT (elms, index, d_save_expr (arg)); @@ -738,8 +735,8 @@ public: /* Check there is no logic bug in constructing byte[][] of arrays. */ gcc_assert (dim == 0); - CONSTRUCTOR_ELTS (init) = elms; - DECL_INITIAL (var) = init; + tree init = build_constructor (TREE_TYPE (var), elms); + var = compound_expr (modify_expr (var, init), var); tree arrs = d_array_value (build_ctype (targselem->arrayOf ()), size_int (ndims), build_address (var)); @@ -752,13 +749,10 @@ public: /* Handle single concatenation (a ~ b). */ result = build_libcall (LIBCALL_ARRAYCATT, e->type, 3, build_typeinfo (e->loc, e->type), - d_array_convert (etype, e->e1, &elemvars), - d_array_convert (etype, e->e2, &elemvars)); + d_array_convert (etype, e->e1), + d_array_convert (etype, e->e2)); } - for (size_t i = 0; i < vec_safe_length (elemvars); ++i) - result = bind_expr ((*elemvars)[i], result); - this->result_ = result; } @@ -2494,12 +2488,13 @@ public: else { /* Multidimensional array allocations. */ - vec *elms = NULL; - Type *telem = e->newtype->toBasetype (); tree tarray = make_array_type (Type::tsize_t, e->arguments->dim); - tree var = create_temporary_var (tarray); - tree init = build_constructor (TREE_TYPE (var), NULL); + tree var = build_local_temp (tarray); + vec *elms = NULL; + /* Get the base element type for the array, generating the + initializer for the dims parameter along the way. */ + Type *telem = e->newtype->toBasetype (); for (size_t i = 0; i < e->arguments->dim; i++) { Expression *arg = (*e->arguments)[i]; @@ -2510,8 +2505,9 @@ public: gcc_assert (telem); } - CONSTRUCTOR_ELTS (init) = elms; - DECL_INITIAL (var) = init; + /* Initialize the temporary. */ + tree init = modify_expr (var, build_constructor (tarray, elms)); + var = compound_expr (init, var); /* Generate: _d_newarraymTX(ti, dims) or: _d_newarraymiTX(ti, dims) */ @@ -2524,7 +2520,6 @@ public: build_address (var)); result = build_libcall (libcall, tb, 2, tinfo, dims); - result = bind_expr (var, result); } if (e->argprefix) diff --git a/gcc/testsuite/gdc.dg/pr94970.d b/gcc/testsuite/gdc.dg/pr94970.d new file mode 100644 index 00000000000..4c3387e3d4b --- /dev/null +++ b/gcc/testsuite/gdc.dg/pr94970.d @@ -0,0 +1,20 @@ +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94970 +// { dg-do compile } + +struct S94970 +{ + string index() { return null; } + ~this() { } +} + +static m() { return S94970(); } + +auto concat() +{ + return m.index ~ ' '; +} + +auto newarray() +{ + return new int[][](m.index.length, 1); +}