From patchwork Thu Oct 3 04:37:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 280213 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EAF642C009D for ; Thu, 3 Oct 2013 14:37:29 +1000 (EST) 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:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=U21PDNlFNqGvzsO2 y81bl31FEzogiQLTI7F+hy/YcNBDNqqXSkncsNQlPvNV0cUKvJl58o4hHgjnXN5T 5bLPsf4Na7QUMhNw01Xc68n4Zv6NIBOkdQbWcvMqzMvwkkP6ktaOUM/L5gLZ1r6Y tNeFFV2Qx0HG+/ov+rTkbWH7Opg= 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:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=4JjOo4Qtj5QPHgR6vP2Mk9 jVnPk=; b=EWCK1rEVsEPN9AyKFvrAURGQeoVrlCmCZTjMdHLG60KtOSRZlMHlD2 hWZaLQzAKhozB4OIqXBRSVNGEjProyR4lgK/lzcQ6CjAQ24HuPfjTu5/h9VEGelW F6YNAPTkW6YwD8dCEUN5MJSI2deysLmKCLsAePL1xwr/7TEeukzD4= Received: (qmail 24017 invoked by alias); 3 Oct 2013 04:37:22 -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 24005 invoked by uid 89); 3 Oct 2013 04:37:21 -0000 Received: from mail2-relais-roc.national.inria.fr (HELO mail2-relais-roc.national.inria.fr) (192.134.164.83) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Thu, 03 Oct 2013 04:37:21 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 required=5.0 tests=AWL, BAYES_00, RDNS_NONE autolearn=no version=3.3.2 X-HELO: mail2-relais-roc.national.inria.fr Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 03 Oct 2013 06:37:15 +0200 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.80) (envelope-from ) id 1VRaf6-0004hl-5M; Thu, 03 Oct 2013 06:37:16 +0200 Date: Thu, 3 Oct 2013 06:37:16 +0200 (CEST) From: Marc Glisse To: Jason Merrill cc: Jakub Jelinek , gcc-patches@gcc.gnu.org Subject: Re: operator new returns nonzero In-Reply-To: <524C1626.4000002@redhat.com> Message-ID: References: <7209CCD2-9BA5-4CD2-8A2B-9DEF2D2C88D2@comcast.net> <7BED207A-EE03-4C7B-9716-33D76FE3649E@comcast.net> <20131002070630.GK30970@tucnak.zalov.cz> <524C1626.4000002@redhat.com> User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 On Wed, 2 Oct 2013, Jason Merrill wrote: > On 10/02/2013 08:33 AM, Marc Glisse wrote: >> + if (flag_delete_null_pointer_checks && !flag_check_new > > You can't use flag_check_new in language-independent code without moving it > from c.opt to common.opt. New version, tested with bootstrap+testsuite on x86_64: 2013-10-03 Marc Glisse PR c++/19476 gcc/c-family/ * c.opt (fcheck-new): Move to common.opt. gcc/ * common.opt (fcheck-new): Moved from c.opt. Make it 'Common'. * calls.c (alloca_call_p): Use get_callee_fndecl. * fold-const.c (tree_expr_nonzero_warnv_p): Handle operator new. * tree-vrp.c (gimple_stmt_nonzero_warnv_p, stmt_interesting_for_vrp): Likewise. (vrp_visit_stmt): Remove duplicated code. gcc/testsuite/ * g++.dg/tree-ssa/pr19476-1.C: New file. * g++.dg/tree-ssa/pr19476-2.C: Likewise. * g++.dg/tree-ssa/pr19476-3.C: Likewise. * g++.dg/tree-ssa/pr19476-4.C: Likewise. Index: c-family/c.opt =================================================================== --- c-family/c.opt (revision 203101) +++ c-family/c.opt (working copy) @@ -848,24 +848,20 @@ fbuiltin- C ObjC C++ ObjC++ Joined fcanonical-system-headers C ObjC C++ ObjC++ Where shorter, use canonicalized paths to systems headers. fcilkplus C ObjC C++ ObjC++ LTO Report Var(flag_enable_cilkplus) Init(0) Enable Cilk Plus -fcheck-new -C++ ObjC++ Var(flag_check_new) -Check the return value of new - fcond-mismatch C ObjC C++ ObjC++ Allow the arguments of the '?' operator to have different types fconserve-space C++ ObjC++ Var(flag_conserve_space) Does nothing. Preserved for backward compatibility. fconstant-string-class= ObjC ObjC++ Joined MissingArgError(no class name specified with %qs) Index: calls.c =================================================================== --- calls.c (revision 203101) +++ calls.c (working copy) @@ -628,25 +628,24 @@ gimple_alloca_call_p (const_gimple stmt) return true; return false; } /* Return true when exp contains alloca call. */ bool alloca_call_p (const_tree exp) { + tree fndecl; if (TREE_CODE (exp) == CALL_EXPR - && TREE_CODE (CALL_EXPR_FN (exp)) == ADDR_EXPR - && (TREE_CODE (TREE_OPERAND (CALL_EXPR_FN (exp), 0)) == FUNCTION_DECL) - && (special_function_p (TREE_OPERAND (CALL_EXPR_FN (exp), 0), 0) - & ECF_MAY_BE_ALLOCA)) + && (fndecl = get_callee_fndecl (exp)) + && (special_function_p (fndecl, 0) & ECF_MAY_BE_ALLOCA)) return true; return false; } /* Return TRUE if FNDECL is either a TM builtin or a TM cloned function. Return FALSE otherwise. */ static bool is_tm_builtin (const_tree fndecl) { Index: common.opt =================================================================== --- common.opt (revision 203101) +++ common.opt (working copy) @@ -906,20 +906,24 @@ Common Joined RejectNegative Var(common_ ; be saved across function calls, if that produces overall better code. ; Optional now, so people can test it. fcaller-saves Common Report Var(flag_caller_saves) Optimization Save registers around function calls fcheck-data-deps Common Report Var(flag_check_data_deps) Compare the results of several data dependence analyzers. +fcheck-new +Common Var(flag_check_new) +Check the return value of new in C++ + fcombine-stack-adjustments Common Report Var(flag_combine_stack_adjustments) Optimization Looks for opportunities to reduce stack adjustments and stack references. fcommon Common Report Var(flag_no_common,0) Optimization Do not put uninitialized globals in the common section fcompare-debug Driver Index: fold-const.c =================================================================== --- fold-const.c (revision 203101) +++ fold-const.c (working copy) @@ -16215,21 +16215,29 @@ tree_expr_nonzero_warnv_p (tree t, bool case MODIFY_EXPR: case BIND_EXPR: return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1), strict_overflow_p); case SAVE_EXPR: return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0), strict_overflow_p); case CALL_EXPR: - return alloca_call_p (t); + { + tree fndecl = get_callee_fndecl (t); + if (!fndecl) return false; + if (flag_delete_null_pointer_checks && !flag_check_new + && DECL_IS_OPERATOR_NEW (fndecl) + && !TREE_NOTHROW (fndecl)) + return true; + return alloca_call_p (t); + } default: break; } return false; } /* Return true when T is an address and is known to be nonzero. Handle warnings about undefined signed overflow. */ Index: testsuite/g++.dg/tree-ssa/pr19476-1.C =================================================================== --- testsuite/g++.dg/tree-ssa/pr19476-1.C (revision 0) +++ testsuite/g++.dg/tree-ssa/pr19476-1.C (working copy) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-ccp1" } */ + +#include + +int f(){ + return 33 + (0 == new(std::nothrow) int); +} +int g(){ + return 42 + (0 == new int[50]); +} + +/* { dg-final { scan-tree-dump "return 42" "ccp1" } } */ +/* { dg-final { scan-tree-dump-not "return 33" "ccp1" } } */ +/* { dg-final { cleanup-tree-dump "ccp1" } } */ Property changes on: testsuite/g++.dg/tree-ssa/pr19476-1.C ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision URL \ No newline at end of property Index: testsuite/g++.dg/tree-ssa/pr19476-2.C =================================================================== --- testsuite/g++.dg/tree-ssa/pr19476-2.C (revision 0) +++ testsuite/g++.dg/tree-ssa/pr19476-2.C (working copy) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +#include + +int f(){ + int *p = new(std::nothrow) int; + return 33 + (0 == p); +} +int g(){ + int *p = new int[50]; + return 42 + (0 == p); +} + +/* { dg-final { scan-tree-dump "return 42" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "return 33" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ Property changes on: testsuite/g++.dg/tree-ssa/pr19476-2.C ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision URL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: testsuite/g++.dg/tree-ssa/pr19476-3.C =================================================================== --- testsuite/g++.dg/tree-ssa/pr19476-3.C (revision 0) +++ testsuite/g++.dg/tree-ssa/pr19476-3.C (working copy) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fcheck-new -fdump-tree-optimized" } */ + +#include + +int g(){ + return 42 + (0 == new int); +} + +/* { dg-final { scan-tree-dump-not "return 42" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ Property changes on: testsuite/g++.dg/tree-ssa/pr19476-3.C ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision URL \ No newline at end of property Index: testsuite/g++.dg/tree-ssa/pr19476-4.C =================================================================== --- testsuite/g++.dg/tree-ssa/pr19476-4.C (revision 0) +++ testsuite/g++.dg/tree-ssa/pr19476-4.C (working copy) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-delete-null-pointer-checks -fdump-tree-optimized" } */ + +#include + +int g(){ + return 42 + (0 == new int); +} + +/* { dg-final { scan-tree-dump-not "return 42" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ Property changes on: testsuite/g++.dg/tree-ssa/pr19476-4.C ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision URL \ No newline at end of property Index: tree-vrp.c =================================================================== --- tree-vrp.c (revision 203101) +++ tree-vrp.c (working copy) @@ -1045,21 +1045,29 @@ gimple_assign_nonzero_warnv_p (gimple st *STRICT_OVERFLOW_P.*/ static bool gimple_stmt_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p) { switch (gimple_code (stmt)) { case GIMPLE_ASSIGN: return gimple_assign_nonzero_warnv_p (stmt, strict_overflow_p); case GIMPLE_CALL: - return gimple_alloca_call_p (stmt); + { + tree fndecl = gimple_call_fndecl (stmt); + if (!fndecl) return false; + if (flag_delete_null_pointer_checks && !flag_check_new + && DECL_IS_OPERATOR_NEW (fndecl) + && !TREE_NOTHROW (fndecl)) + return true; + return gimple_alloca_call_p (stmt); + } default: gcc_unreachable (); } } /* Like tree_expr_nonzero_warnv_p, but this function uses value ranges obtained so far. */ static bool vrp_stmt_computes_nonzero (gimple stmt, bool *strict_overflow_p) @@ -6484,21 +6492,22 @@ stmt_interesting_for_vrp (gimple stmt) tree lhs = gimple_get_lhs (stmt); /* In general, assignments with virtual operands are not useful for deriving ranges, with the obvious exception of calls to builtin functions. */ if (lhs && TREE_CODE (lhs) == SSA_NAME && (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) || POINTER_TYPE_P (TREE_TYPE (lhs))) && ((is_gimple_call (stmt) && gimple_call_fndecl (stmt) != NULL_TREE - && DECL_BUILT_IN (gimple_call_fndecl (stmt))) + && (DECL_BUILT_IN (gimple_call_fndecl (stmt)) + || DECL_IS_OPERATOR_NEW (gimple_call_fndecl (stmt)))) || !gimple_vuse (stmt))) return true; } else if (gimple_code (stmt) == GIMPLE_COND || gimple_code (stmt) == GIMPLE_SWITCH) return true; return false; } @@ -7405,30 +7414,21 @@ vrp_visit_stmt (gimple stmt, edge *taken if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "\nVisiting statement:\n"); print_gimple_stmt (dump_file, stmt, 0, dump_flags); fprintf (dump_file, "\n"); } if (!stmt_interesting_for_vrp (stmt)) gcc_assert (stmt_ends_bb_p (stmt)); else if (is_gimple_assign (stmt) || is_gimple_call (stmt)) - { - /* In general, assignments with virtual operands are not useful - for deriving ranges, with the obvious exception of calls to - builtin functions. */ - if ((is_gimple_call (stmt) - && gimple_call_fndecl (stmt) != NULL_TREE - && DECL_BUILT_IN (gimple_call_fndecl (stmt))) - || !gimple_vuse (stmt)) - return vrp_visit_assignment_or_call (stmt, output_p); - } + return vrp_visit_assignment_or_call (stmt, output_p); else if (gimple_code (stmt) == GIMPLE_COND) return vrp_visit_cond_stmt (stmt, taken_edge_p); else if (gimple_code (stmt) == GIMPLE_SWITCH) return vrp_visit_switch_stmt (stmt, taken_edge_p); /* All other statements produce nothing of interest for VRP, so mark their outputs varying and prevent further simulation. */ FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF) set_value_range_to_varying (get_value_range (def));