From patchwork Thu Oct 7 22:14:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 45977 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 81A353857825 for ; Thu, 7 Oct 2021 22:18:20 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from dog.elm.relay.mailchannels.net (dog.elm.relay.mailchannels.net [23.83.212.48]) by sourceware.org (Postfix) with ESMTPS id CB4BD3858002 for ; Thu, 7 Oct 2021 22:15:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CB4BD3858002 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gotplt.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gotplt.org X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id D82AD22A0F; Thu, 7 Oct 2021 22:15:13 +0000 (UTC) Received: from pdx1-sub0-mail-a17.g.dreamhost.com (100-96-99-46.trex.outbound.svc.cluster.local [100.96.99.46]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 3523522B8A; Thu, 7 Oct 2021 22:15:13 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|siddhesh@gotplt.org Received: from pdx1-sub0-mail-a17.g.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384) by 100.96.99.46 (trex/6.4.3); Thu, 07 Oct 2021 22:15:13 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|siddhesh@gotplt.org X-MailChannels-Auth-Id: dreamhost X-Abiding-Wipe: 41a601f40e1fb337_1633644913631_3172754537 X-MC-Loop-Signature: 1633644913631:1599478823 X-MC-Ingress-Time: 1633644913631 Received: from pdx1-sub0-mail-a17.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a17.g.dreamhost.com (Postfix) with ESMTP id E714D7F2D7; Thu, 7 Oct 2021 15:15:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gotplt.org; h=from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; s=gotplt.org; bh=IrdDuT0nrePvj6q+8zV NszXEPew=; b=sm8NCfIUxDhH97sNtBDWaLKNKiPUWBMpLrSd4klL4eLx2luS4yU KDuqp58ffyqOZhn8Hxea+xgH68Sr6M7SKdBRIrPF3eoXAbBae7vKQjbJA/FBv0fn A3FLDNu4gkJFYEbGphHjuMUjTSQnkf0JXD+CMxa6bZKbB4WbpexgpcUU= Received: from rhbox.redhat.com (unknown [1.186.223.58]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: siddhesh@gotplt.org) by pdx1-sub0-mail-a17.g.dreamhost.com (Postfix) with ESMTPSA id DB67D83499; Thu, 7 Oct 2021 15:15:10 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a17 From: Siddhesh Poyarekar To: gcc-patches@gcc.gnu.org Subject: [PATCH 6/8] tree-dynamic-object-size: Handle function parameters Date: Fri, 8 Oct 2021 03:44:30 +0530 Message-Id: <20211007221432.1029249-7-siddhesh@gotplt.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211007221432.1029249-1-siddhesh@gotplt.org> References: <20211007221432.1029249-1-siddhesh@gotplt.org> MIME-Version: 1.0 X-Spam-Status: No, score=-3039.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: , Cc: jakub@redhat.com Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Handle either static sizes in function parameters or hints provided by __attribute__ ((access (...))) to compute sizes for objects. gcc/ChangeLog: * tree-dynamic-object-size.c: Include tree-dfa.h. (emit_size_stmts): New argument osi. Handle GIMPLE_NOP. (eval_size_expr, gimplify_size_exprs): Adjust. (parm_object_size): New function. (collect_object_sizes_for): Handle GIMPLE_NOP. gcc/testsuite/ChangeLog: * gcc.dg/builtin-dynamic-object-size-0.c (test_parmsz): New test. (main): Call it. Signed-off-by: Siddhesh Poyarekar --- .../gcc.dg/builtin-dynamic-object-size-0.c | 22 +++++ gcc/tree-dynamic-object-size.c | 98 +++++++++++++++++-- 2 files changed, 112 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c index 3c2c4c84264..c72fa0508db 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c @@ -255,6 +255,15 @@ test_substring_ptrplus (size_t sz, size_t off) return __builtin_dynamic_object_size (str + off, 0); } +size_t +__attribute__ ((noinline)) +__attribute__ ((access (__read_write__, 1, 2))) +test_parmsz (void *obj, size_t sz, size_t off) +{ + return __builtin_dynamic_object_size (obj + off, 0); +} + + int main (int argc, char **argv) { @@ -338,6 +347,19 @@ main (int argc, char **argv) if (test_deploop (128, 129) != 32) FAIL (); + if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1, -1)!= 0) + FAIL (); + + if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1, 0) + != __builtin_strlen (argv[0]) + 1) + FAIL (); + if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1, + __builtin_strlen (argv[0]))!= 1) + FAIL (); + if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1, + __builtin_strlen (argv[0]) + 2)!= 0) + FAIL (); + if (nfails > 0) __builtin_abort (); diff --git a/gcc/tree-dynamic-object-size.c b/gcc/tree-dynamic-object-size.c index f143a64777c..8d7283623dc 100644 --- a/gcc/tree-dynamic-object-size.c +++ b/gcc/tree-dynamic-object-size.c @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-fold.h" #include "gimple-iterator.h" #include "tree-cfg.h" +#include "tree-dfa.h" #include "stringpool.h" #include "attribs.h" #include "builtins.h" @@ -456,7 +457,7 @@ pass_through_call (const gcall *call) static void -emit_size_stmts (gimple *stmt, tree wholesize_ssa, +emit_size_stmts (object_size_info *osi, gimple *stmt, tree wholesize_ssa, tree wholesize_expr, tree size_ssa, tree size_expr) { gimple_seq seq = NULL; @@ -481,7 +482,14 @@ emit_size_stmts (gimple *stmt, tree wholesize_ssa, statements involved in evaluation of the object size expression precede the definition statement. For parameters, we don't have a definition statement, so insert into the first code basic block. */ - gimple_stmt_iterator i = gsi_for_stmt (stmt); + gimple_stmt_iterator i; + if (gimple_code (stmt) == GIMPLE_NOP) + { + basic_block first_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (osi->fun)); + i = gsi_start_bb (first_bb); + } + else + i = gsi_for_stmt (stmt); gsi_insert_seq_before (&i, seq, GSI_CONTINUE_LINKING); } @@ -542,8 +550,8 @@ size_bound_expr (tree sz) } static void -eval_size_expr (tree var, tree wholesize, tree *wholesize_expr, - tree size, tree *size_expr) +eval_size_expr (struct object_size_info *osi, tree var, tree wholesize, + tree *wholesize_expr, tree size, tree *size_expr) { if (size_expr != NULL) { @@ -560,7 +568,7 @@ eval_size_expr (tree var, tree wholesize, tree *wholesize_expr, } else { - emit_size_stmts (stmt, wholesize, *wholesize_expr, size, + emit_size_stmts (osi, stmt, wholesize, *wholesize_expr, size, size_bound_expr (*size_expr)); delete wholesize_expr; delete size_expr; @@ -611,7 +619,7 @@ gimplify_size_exprs (object_size_info *osi, tree ptr) for (int object_size_type = 0; object_size_type <= 3; object_size_type++) EXECUTE_IF_SET_IN_BITMAP (computed[object_size_type], 0, i, bi) { - eval_size_expr (ssa_name (i), + eval_size_expr (osi, ssa_name (i), object_whole_sizes[object_size_type][i], object_whole_size_exprs[object_size_type][i], object_sizes[object_size_type][i], @@ -939,6 +947,71 @@ call_object_size (struct object_size_info *osi, tree ptr, gcall *call) cache_object_size_copy (osi, SSA_NAME_VERSION (ptr), sz, sz); } +/* Find size of an object passed as a parameter to the function. */ + +static void +parm_object_size (struct object_size_info *osi, tree var) +{ + tree parm = SSA_NAME_VAR (var); + unsigned varno = SSA_NAME_VERSION (var); + tree sz = NULL_TREE, wholesz = NULL_TREE; + + if (dump_file) + { + fprintf (dump_file, "Object is a parameter: "); + print_generic_expr (dump_file, parm, dump_flags); + fprintf (dump_file, " which is %s a pointer type\n", + POINTER_TYPE_P (TREE_TYPE (parm)) ? "" : "not"); + } + + if (POINTER_TYPE_P (TREE_TYPE (parm))) + { + /* Look for access attribute. */ + rdwr_map rdwr_idx; + + tree fndecl = osi->fun->decl; + const attr_access *access = get_parm_access (rdwr_idx, parm, fndecl); + tree typesize = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (parm))); + + if (access && access->sizarg != UINT_MAX) + { + tree fnargs = DECL_ARGUMENTS (fndecl); + tree arg = NULL_TREE; + unsigned argpos = 0; + + /* Walk through the parameters to pick the size parameter and safely + scale it by the type size. */ + for (arg = fnargs; argpos != access->sizarg && arg; + arg = TREE_CHAIN (arg), ++argpos); + + if (arg != NULL_TREE && INTEGRAL_TYPE_P (TREE_TYPE (arg))) + { + tree arrsz = get_or_create_ssa_default_def (osi->fun, arg); + if (arrsz != NULL_TREE) + { + arrsz = fold_convert (sizetype, arrsz); + if (typesize) + { + tree res = fold_build2 (MULT_EXPR, sizetype, arrsz, + typesize); + tree check = fold_build2 (EXACT_DIV_EXPR, sizetype, + TYPE_MAX_VALUE (sizetype), + typesize); + check = fold_build2 (LT_EXPR, sizetype, arrsz, check); + arrsz = fold_build3 (COND_EXPR, sizetype, check, res, + size_zero_node); + } + } + sz = wholesz = arrsz; + } + } + } + else + expr_object_size (osi, parm, &sz, &wholesz); + + cache_object_size_copy (osi, varno, sz, wholesz); +} + /* Compute object sizes for VAR. - For allocation GIMPLE_CALL like malloc or calloc object size is the size @@ -948,7 +1021,9 @@ call_object_size (struct object_size_info *osi, tree ptr, gcall *call) - For GIMPLE_PHI, compute a PHI node with sizes of all branches in the PHI node of the object. - For GIMPLE_ASSIGN, return the size of the object the SSA name points - to. */ + to. + - For GIMPLE_NOP, if the variable is a function parameter, compute the size + of the parameter. */ static void collect_object_sizes_for (struct object_size_info *osi, tree var) @@ -1076,8 +1151,15 @@ collect_object_sizes_for (struct object_size_info *osi, tree var) break; } - /* Bail out for all other cases. */ case GIMPLE_NOP: + if (SSA_NAME_VAR (var) && TREE_CODE (SSA_NAME_VAR (var)) == PARM_DECL) + parm_object_size (osi, var); + else + /* Uninitialized SSA names point nowhere. */ + cache_object_size_copy (osi, varno, NULL_TREE, NULL_TREE); + break; + + /* Bail out for all other cases. */ case GIMPLE_ASM: cache_object_size_copy (osi, varno, NULL_TREE, NULL_TREE); break;