diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
commit | a926878ddbd5a98b272c22171ce58663fc04c3e0 (patch) | |
tree | 86af256e5d9a9c06263c00adc90e5fe348008c43 /gcc/tree-object-size.c | |
parent | 542730f087133690b47e036dfd43eb0db8a650ce (diff) | |
parent | 07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff) | |
download | gcc-devel/autopar_devel.zip gcc-devel/autopar_devel.tar.gz gcc-devel/autopar_devel.tar.bz2 |
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'gcc/tree-object-size.c')
-rw-r--r-- | gcc/tree-object-size.c | 79 |
1 files changed, 64 insertions, 15 deletions
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 255ea63..bc55b27 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -166,6 +166,42 @@ compute_object_offset (const_tree expr, const_tree var) return size_binop (code, base, off); } +/* Returns the size of the object designated by DECL considering its + initializer if it either has one or if it would not affect its size, + otherwise the size of the object without the initializer when MIN + is true, else null. An object's initializer affects the object's + size if it's a struct type with a flexible array member. */ + +tree +decl_init_size (tree decl, bool min) +{ + tree size = DECL_SIZE_UNIT (decl); + tree type = TREE_TYPE (decl); + if (TREE_CODE (type) != RECORD_TYPE) + return size; + + tree last = last_field (type); + if (!last) + return size; + + tree last_type = TREE_TYPE (last); + if (TREE_CODE (last_type) != ARRAY_TYPE + || TYPE_SIZE (last_type)) + return size; + + /* Use TYPE_SIZE_UNIT; DECL_SIZE_UNIT sometimes reflects the size + of the initializer and sometimes doesn't. */ + size = TYPE_SIZE_UNIT (type); + tree ref = build3 (COMPONENT_REF, type, decl, last, NULL_TREE); + tree compsize = component_ref_size (ref); + if (!compsize) + return min ? size : NULL_TREE; + + /* The size includes tail padding and initializer elements. */ + tree pos = byte_position (last); + size = fold_build2 (PLUS_EXPR, TREE_TYPE (size), pos, compsize); + return size; +} /* Compute __builtin_object_size for PTR, which is a ADDR_EXPR. OBJECT_SIZE_TYPE is the second argument from __builtin_object_size. @@ -194,8 +230,10 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, while (handled_component_p (pt_var)) pt_var = TREE_OPERAND (pt_var, 0); - if (pt_var - && TREE_CODE (pt_var) == MEM_REF) + if (!pt_var) + return false; + + if (TREE_CODE (pt_var) == MEM_REF) { unsigned HOST_WIDE_INT sz; @@ -221,6 +259,11 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, offset_int mem_offset; if (mem_ref_offset (pt_var).is_constant (&mem_offset)) { + if (*poff) + *poff = wide_int_to_tree (ptrdiff_type_node, + mem_offset + wi::to_offset (*poff)); + else + *poff = wide_int_to_tree (ptrdiff_type_node, mem_offset); offset_int dsz = wi::sub (sz, mem_offset); if (wi::neg_p (dsz)) sz = 0; @@ -236,24 +279,26 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, if (sz != unknown[object_size_type] && sz < offset_limit) pt_var_size = size_int (sz); } - else if (pt_var - && DECL_P (pt_var) - && tree_fits_uhwi_p (DECL_SIZE_UNIT (pt_var)) - && tree_to_uhwi (DECL_SIZE_UNIT (pt_var)) < offset_limit) + else if (DECL_P (pt_var)) { *pdecl = pt_var; - pt_var_size = DECL_SIZE_UNIT (pt_var); + pt_var_size = decl_init_size (pt_var, object_size_type & 2); + if (!pt_var_size) + return false; } - else if (pt_var - && TREE_CODE (pt_var) == STRING_CST - && TYPE_SIZE_UNIT (TREE_TYPE (pt_var)) - && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (pt_var))) - && tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (pt_var))) - < offset_limit) + else if (TREE_CODE (pt_var) == STRING_CST) pt_var_size = TYPE_SIZE_UNIT (TREE_TYPE (pt_var)); else return false; + if (pt_var_size) + { + /* Validate the size determined above. */ + if (!tree_fits_uhwi_p (pt_var_size) + || tree_to_uhwi (pt_var_size) >= offset_limit) + return false; + } + if (pt_var != TREE_OPERAND (ptr, 0)) { tree var; @@ -373,12 +418,12 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var); if (bytes != error_mark_node) { + *poff = bytes; if (TREE_CODE (bytes) == INTEGER_CST && tree_int_cst_lt (var_size, bytes)) bytes = size_zero_node; else bytes = size_binop (MINUS_EXPR, var_size, bytes); - *poff = bytes; } if (var != pt_var && pt_var_size @@ -401,7 +446,11 @@ addr_object_size (struct object_size_info *osi, const_tree ptr, else if (!pt_var_size) return false; else - bytes = pt_var_size; + { + bytes = pt_var_size; + if (!*poff) + *poff = size_zero_node; + } if (tree_fits_uhwi_p (bytes)) { |