From patchwork Thu Jun 18 10:16:46 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 486249 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 B384C1401AF for ; Thu, 18 Jun 2015 20:17:04 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=MHTdha90; 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:subject:message-id:mime-version:content-type; q=dns; s= default; b=DjZ57HTwWHUXd28VTYFuxZu3kyGoK2JgL3emf27vjtl+Vc5PRv5rX F792D+S4RCTZCohfNkomQpxsB4DIHwexnLNzIg35RLH4wpq+cbsvuUKVMokILOWa 19sWwvc6AP/cLJXEdvHhUnq57BLXfhxe4Vn7e2K6qsaemYF6xJnHFY= 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:subject:message-id:mime-version:content-type; s= default; bh=nWp3PUXxewWVRSA7nE06/QBbbSo=; b=MHTdha90zQpU5mHPtpUq Uut+KCgYuZcBJGZHd9U5FzUZVpClZ7tBIwwjzU0xGJIyhGp79FLrOtyYhUAJAlHz lNTobR/TuWWunzPJULUtjwZp579u1lm1Mco7RYVnBYSAhZuy4hJIBiCWLZlcTFaL 5AW4oR/vOJXKbEzxR9hR5qA= Received: (qmail 49575 invoked by alias); 18 Jun 2015 10:16:58 -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 49565 invoked by uid 89); 18 Jun 2015 10:16:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-ig0-f178.google.com Received: from mail-ig0-f178.google.com (HELO mail-ig0-f178.google.com) (209.85.213.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 18 Jun 2015 10:16:55 +0000 Received: by igboe5 with SMTP id oe5so14756033igb.1 for ; Thu, 18 Jun 2015 03:16:53 -0700 (PDT) X-Received: by 10.107.11.17 with SMTP id v17mr13862968ioi.83.1434622613778; Thu, 18 Jun 2015 03:16:53 -0700 (PDT) Received: from msticlxl57.ims.intel.com ([192.55.54.40]) by mx.google.com with ESMTPSA id a139sm4614452ioa.14.2015.06.18.03.16.52 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Jun 2015 03:16:53 -0700 (PDT) Date: Thu, 18 Jun 2015 13:16:46 +0300 From: Ilya Enkovich To: gcc-patches@gcc.gnu.org Subject: [PATCH, CHKP, PR middle-end/66568] Fix internal compiler error: in expand_expr_addr_expr_1 Message-ID: <20150618101646.GC28183@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Hi, Currently return statement with no bounds in instrumented function causes ICE. This patch uses zero bounds in such cases instead. Bootstrapped and regtested for x86_64-unknown-linux-gnu. Applied to trunk. Is it OK for gcc-5-branch? Thanks, Ilya --- gcc/ 2015-06-18 Ilya Enkovich PR middle-end/66568 * cfgexpand.c (expand_return): Handle missing bounds. (expand_gimple_stmt_1): Likewise. * tree-chkp.c (chkp_expand_zero_bounds): New. * tree-chkp.h (chkp_expand_zero_bounds): New. gcc/testsuite/ 2015-06-18 Ilya Enkovich PR middle-end/66568 * gcc.target/i386/mpx/pr66568.c: New test. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index b23e325..7508b3f 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -3136,18 +3136,25 @@ expand_return (tree retval, tree bounds) bounds_rtl = DECL_BOUNDS_RTL (DECL_RESULT (current_function_decl)); if (bounds_rtl) { - rtx addr, bnd; + rtx addr = NULL; + rtx bnd = NULL; - if (bounds) + if (bounds && bounds != error_mark_node) { bnd = expand_normal (bounds); targetm.calls.store_returned_bounds (bounds_rtl, bnd); } else if (REG_P (bounds_rtl)) { - addr = expand_normal (build_fold_addr_expr (retval_rhs)); - addr = gen_rtx_MEM (Pmode, addr); - bnd = targetm.calls.load_bounds_for_arg (addr, NULL, NULL); + if (bounds) + bnd = chkp_expand_zero_bounds (); + else + { + addr = expand_normal (build_fold_addr_expr (retval_rhs)); + addr = gen_rtx_MEM (Pmode, addr); + bnd = targetm.calls.load_bounds_for_arg (addr, NULL, NULL); + } + targetm.calls.store_returned_bounds (bounds_rtl, bnd); } else @@ -3156,15 +3163,23 @@ expand_return (tree retval, tree bounds) gcc_assert (GET_CODE (bounds_rtl) == PARALLEL); - addr = expand_normal (build_fold_addr_expr (retval_rhs)); - addr = gen_rtx_MEM (Pmode, addr); + if (bounds) + bnd = chkp_expand_zero_bounds (); + else + { + addr = expand_normal (build_fold_addr_expr (retval_rhs)); + addr = gen_rtx_MEM (Pmode, addr); + } for (n = 0; n < XVECLEN (bounds_rtl, 0); n++) { - rtx offs = XEXP (XVECEXP (bounds_rtl, 0, n), 1); rtx slot = XEXP (XVECEXP (bounds_rtl, 0, n), 0); - rtx from = adjust_address (addr, Pmode, INTVAL (offs)); - rtx bnd = targetm.calls.load_bounds_for_arg (from, NULL, NULL); + if (!bounds) + { + rtx offs = XEXP (XVECEXP (bounds_rtl, 0, n), 1); + rtx from = adjust_address (addr, Pmode, INTVAL (offs)); + bnd = targetm.calls.load_bounds_for_arg (from, NULL, NULL); + } targetm.calls.store_returned_bounds (slot, bnd); } } @@ -3261,33 +3276,40 @@ expand_gimple_stmt_1 (gimple stmt) break; case GIMPLE_RETURN: - op0 = gimple_return_retval (as_a (stmt)); + { + tree bnd = gimple_return_retbnd (as_a (stmt)); + op0 = gimple_return_retval (as_a (stmt)); - if (op0 && op0 != error_mark_node) - { - tree result = DECL_RESULT (current_function_decl); + if (op0 && op0 != error_mark_node) + { + tree result = DECL_RESULT (current_function_decl); - /* If we are not returning the current function's RESULT_DECL, - build an assignment to it. */ - if (op0 != result) - { - /* I believe that a function's RESULT_DECL is unique. */ - gcc_assert (TREE_CODE (op0) != RESULT_DECL); - - /* ??? We'd like to use simply expand_assignment here, - but this fails if the value is of BLKmode but the return - decl is a register. expand_return has special handling - for this combination, which eventually should move - to common code. See comments there. Until then, let's - build a modify expression :-/ */ - op0 = build2 (MODIFY_EXPR, TREE_TYPE (result), - result, op0); - } - } - if (!op0) - expand_null_return (); - else - expand_return (op0, gimple_return_retbnd (stmt)); + /* If we are not returning the current function's RESULT_DECL, + build an assignment to it. */ + if (op0 != result) + { + /* I believe that a function's RESULT_DECL is unique. */ + gcc_assert (TREE_CODE (op0) != RESULT_DECL); + + /* ??? We'd like to use simply expand_assignment here, + but this fails if the value is of BLKmode but the return + decl is a register. expand_return has special handling + for this combination, which eventually should move + to common code. See comments there. Until then, let's + build a modify expression :-/ */ + op0 = build2 (MODIFY_EXPR, TREE_TYPE (result), + result, op0); + } + /* Mark we have return statement with missing bounds. */ + if (!bnd && chkp_function_instrumented_p (cfun->decl)) + bnd = error_mark_node; + } + + if (!op0) + expand_null_return (); + else + expand_return (op0, bnd); + } break; case GIMPLE_ASSIGN: diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr66568.c b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c new file mode 100644 index 0000000..d7bb9f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target fpic } */ +/* { dg-options "-O2 -fcheck-pointer-bounds -mmpx -O2 -fPIC" } */ + +int a, b, c; +void *set_test () { + if (b) + a ? exit (0) : exit (1); + b = c; +} diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index 8edef48..9b0b33c 100644 --- a/gcc/tree-chkp.c +++ b/gcc/tree-chkp.c @@ -468,6 +468,21 @@ chkp_gimple_call_builtin_p (gimple call, return false; } +/* Emit code to build zero bounds and return RTL holding + the result. */ +rtx +chkp_expand_zero_bounds () +{ + tree zero_bnd; + + if (flag_chkp_use_static_const_bounds) + zero_bnd = chkp_get_zero_bounds_var (); + else + zero_bnd = chkp_build_make_bounds_call (integer_zero_node, + integer_zero_node); + return expand_normal (zero_bnd); +} + /* Emit code to store zero bounds for PTR located at MEM. */ void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr) diff --git a/gcc/tree-chkp.h b/gcc/tree-chkp.h index b5ab562..6e41086 100644 --- a/gcc/tree-chkp.h +++ b/gcc/tree-chkp.h @@ -53,6 +53,7 @@ extern void chkp_copy_bounds_for_assign (gimple assign, struct cgraph_edge *edge); extern bool chkp_gimple_call_builtin_p (gimple call, enum built_in_function code); +extern rtx chkp_expand_zero_bounds (void); extern void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr); extern tree chkp_insert_retbnd_call (tree bndval, tree retval, gimple_stmt_iterator *gsi);