From: Siddhesh Poyarekar <siddhesh@gotplt.org>
To: gcc-patches@gcc.gnu.org
Cc: jakub@redhat.com
Subject: [PATCH 6/8] tree-dynamic-object-size: Handle function parameters
Date: Fri, 8 Oct 2021 03:44:30 +0530 [thread overview]
Message-ID: <20211007221432.1029249-7-siddhesh@gotplt.org> (raw)
In-Reply-To: <20211007221432.1029249-1-siddhesh@gotplt.org>
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 <siddhesh@gotplt.org>
---
.../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;
--
2.31.1
next prev parent reply other threads:[~2021-10-07 22:15 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-07 22:14 [PATCH 0/8] __builtin_dynamic_object_size and more Siddhesh Poyarekar
2021-10-07 22:14 ` [PATCH 1/8] __builtin_dynamic_object_size: Recognize builtin name Siddhesh Poyarekar
2021-10-12 13:42 ` Jakub Jelinek
2021-10-12 14:22 ` Siddhesh Poyarekar
2021-10-07 22:14 ` [PATCH 2/8] tree-dynamic-object-size: New pass Siddhesh Poyarekar
2021-10-08 4:05 ` Siddhesh Poyarekar
2021-10-12 13:58 ` Jakub Jelinek
2021-10-12 14:28 ` Siddhesh Poyarekar
2021-10-07 22:14 ` [PATCH 3/8] tree-dynamic-object-size: Handle GIMPLE_PHI Siddhesh Poyarekar
2021-10-07 22:14 ` [PATCH 4/8] tree-dynamic-object-size: Support ADDR_EXPR Siddhesh Poyarekar
2021-10-07 22:14 ` [PATCH 5/8] tree-dynamic-object-size: Handle GIMPLE_ASSIGN Siddhesh Poyarekar
2021-10-07 22:14 ` Siddhesh Poyarekar [this message]
2021-10-20 16:56 ` [PATCH 6/8] tree-dynamic-object-size: Handle function parameters Martin Sebor
2021-10-20 16:59 ` Siddhesh Poyarekar
2021-10-07 22:14 ` [PATCH 7/8] tree-dynamic-object-size: Get subobject sizes Siddhesh Poyarekar
2021-10-07 22:14 ` [PATCH 8/8] tree-dynamic-object-size: Add test wrappers to extend testing Siddhesh Poyarekar
2021-10-08 4:50 ` [PATCH 0/8] __builtin_dynamic_object_size and more Siddhesh Poyarekar
2021-10-17 19:57 ` Jeff Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211007221432.1029249-7-siddhesh@gotplt.org \
--to=siddhesh@gotplt.org \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).