aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
committerAldy Hernandez <aldyh@redhat.com>2020-06-17 07:50:57 -0400
commitb9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch)
treeed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/tree.c
parent1957047ed1c94bf17cf993a2b1866965f493ba87 (diff)
parent56638b9b1853666f575928f8baf17f70e4ed3517 (diff)
downloadgcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.zip
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.gz
gcc-b9e67f2840ce0d8859d96e7f8df8fe9584af5eba.tar.bz2
Merge from trunk at:
commit 56638b9b1853666f575928f8baf17f70e4ed3517 Author: GCC Administrator <gccadmin@gcc.gnu.org> Date: Wed Jun 17 00:16:36 2020 +0000 Daily bump.
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c206
1 files changed, 125 insertions, 81 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 0ddf002..805f669 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3351,51 +3351,6 @@ int_byte_position (const_tree field)
return tree_to_shwi (byte_position (field));
}
-/* Return the strictest alignment, in bits, that T is known to have. */
-
-unsigned int
-expr_align (const_tree t)
-{
- unsigned int align0, align1;
-
- switch (TREE_CODE (t))
- {
- CASE_CONVERT: case NON_LVALUE_EXPR:
- /* If we have conversions, we know that the alignment of the
- object must meet each of the alignments of the types. */
- align0 = expr_align (TREE_OPERAND (t, 0));
- align1 = TYPE_ALIGN (TREE_TYPE (t));
- return MAX (align0, align1);
-
- case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR:
- case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR:
- case CLEANUP_POINT_EXPR:
- /* These don't change the alignment of an object. */
- return expr_align (TREE_OPERAND (t, 0));
-
- case COND_EXPR:
- /* The best we can do is say that the alignment is the least aligned
- of the two arms. */
- align0 = expr_align (TREE_OPERAND (t, 1));
- align1 = expr_align (TREE_OPERAND (t, 2));
- return MIN (align0, align1);
-
- /* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set
- meaningfully, it's always 1. */
- case LABEL_DECL: case CONST_DECL:
- case VAR_DECL: case PARM_DECL: case RESULT_DECL:
- case FUNCTION_DECL:
- gcc_assert (DECL_ALIGN (t) != 0);
- return DECL_ALIGN (t);
-
- default:
- break;
- }
-
- /* Otherwise take the alignment from that of the type. */
- return TYPE_ALIGN (TREE_TYPE (t));
-}
-
/* Return, as a tree node, the number of elements for TYPE (which is an
ARRAY_TYPE) minus one. This counts only elements of the top array. */
@@ -5146,6 +5101,23 @@ protected_set_expr_location (tree t, location_t loc)
{
if (CAN_HAVE_LOCATION_P (t))
SET_EXPR_LOCATION (t, loc);
+ else if (t && TREE_CODE (t) == STATEMENT_LIST)
+ {
+ t = expr_single (t);
+ if (t && CAN_HAVE_LOCATION_P (t))
+ SET_EXPR_LOCATION (t, loc);
+ }
+}
+
+/* Like PROTECTED_SET_EXPR_LOCATION, but only do that if T has
+ UNKNOWN_LOCATION. */
+
+void
+protected_set_expr_location_if_unset (tree t, location_t loc)
+{
+ t = expr_single (t);
+ if (t && !EXPR_HAS_LOCATION (t))
+ protected_set_expr_location (t, loc);
}
/* Data used when collecting DECLs and TYPEs for language data removal. */
@@ -5589,15 +5561,14 @@ free_lang_data_in_type (tree type, class free_lang_data_d *fld)
/* Type values are used only for C++ ODR checking. Drop them
for all type variants and non-ODR types.
For ODR types the data is freed in free_odr_warning_data. */
- if (TYPE_MAIN_VARIANT (type) != type
- || !type_with_linkage_p (type))
+ if (!TYPE_VALUES (type))
+ ;
+ else if (TYPE_MAIN_VARIANT (type) != type
+ || !type_with_linkage_p (type)
+ || type_in_anonymous_namespace_p (type))
TYPE_VALUES (type) = NULL;
else
- /* Simplify representation by recording only values rather
- than const decls. */
- for (tree e = TYPE_VALUES (type); e; e = TREE_CHAIN (e))
- if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL)
- TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e));
+ register_odr_enum (type);
}
free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type));
free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type));
@@ -5803,7 +5774,7 @@ free_lang_data_in_decl (tree decl, class free_lang_data_d *fld)
}
else if (VAR_P (decl))
{
- /* See comment above why we set the flag for functoins. */
+ /* See comment above why we set the flag for functions. */
if (TREE_PUBLIC (decl))
TREE_ADDRESSABLE (decl) = true;
if ((DECL_EXTERNAL (decl)
@@ -8862,6 +8833,25 @@ get_narrower (tree op, int *unsignedp_ptr)
tree win = op;
bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
+ if (TREE_CODE (op) == COMPOUND_EXPR)
+ {
+ do
+ op = TREE_OPERAND (op, 1);
+ while (TREE_CODE (op) == COMPOUND_EXPR);
+ tree ret = get_narrower (op, unsignedp_ptr);
+ if (ret == op)
+ return win;
+ auto_vec <tree, 16> v;
+ unsigned int i;
+ for (op = win; TREE_CODE (op) == COMPOUND_EXPR;
+ op = TREE_OPERAND (op, 1))
+ v.safe_push (op);
+ FOR_EACH_VEC_ELT_REVERSE (v, i, op)
+ ret = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR,
+ TREE_TYPE (win), TREE_OPERAND (op, 0),
+ ret);
+ return ret;
+ }
while (TREE_CODE (op) == NOP_EXPR)
{
int bitschange
@@ -9206,8 +9196,18 @@ variably_modified_type_p (tree type, tree fn)
RETURN_TRUE_IF_VAR (DECL_SIZE (t));
RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t));
+ /* If the type is a qualified union, then the DECL_QUALIFIER
+ of fields can also be an expression containing a variable. */
if (TREE_CODE (type) == QUAL_UNION_TYPE)
RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t));
+
+ /* If the field is a qualified union, then it's only a container
+ for what's inside so we look into it. That's necessary in LTO
+ mode because the sizes of the field tested above have been set
+ to PLACEHOLDER_EXPRs by free_lang_data. */
+ if (TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE
+ && variably_modified_type_p (TREE_TYPE (t), fn))
+ return true;
}
break;
@@ -10329,6 +10329,8 @@ build_common_tree_nodes (bool signed_char)
uint16_type_node = make_or_reuse_type (16, 1);
uint32_type_node = make_or_reuse_type (32, 1);
uint64_type_node = make_or_reuse_type (64, 1);
+ if (targetm.scalar_mode_supported_p (TImode))
+ uint128_type_node = make_or_reuse_type (128, 1);
/* Decimal float types. */
if (targetm.decimal_float_supported_p ())
@@ -11477,6 +11479,7 @@ build_call_expr_internal_loc_array (location_t loc, internal_fn ifn,
CALL_EXPR_ARG (t, i) = args[i];
SET_EXPR_LOCATION (t, loc);
CALL_EXPR_IFN (t) = ifn;
+ process_call_operands (t);
return t;
}
@@ -12209,6 +12212,12 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
Note that DECLs get walked as part of processing the BIND_EXPR. */
if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
{
+ /* Call the function for the decl so e.g. copy_tree_body_r can
+ replace it with the remapped one. */
+ result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data);
+ if (result || !walk_subtrees)
+ return result;
+
tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
if (TREE_CODE (*type_p) == ERROR_MARK)
return NULL_TREE;
@@ -13374,7 +13383,9 @@ array_ref_low_bound (tree exp)
return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
/* Otherwise, return a zero of the appropriate type. */
- return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
+ tree idxtype = TREE_TYPE (TREE_OPERAND (exp, 1));
+ return (idxtype == error_mark_node
+ ? integer_zero_node : build_int_cst (idxtype, 0));
}
/* Return a tree representing the upper bound of the array mentioned in
@@ -13596,6 +13607,10 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
if (!interior_zero_length)
interior_zero_length = &int_0_len;
+ /* The object/argument referenced by the COMPONENT_REF and its type. */
+ tree arg = TREE_OPERAND (ref, 0);
+ tree argtype = TREE_TYPE (arg);
+ /* The referenced member. */
tree member = TREE_OPERAND (ref, 1);
tree memsize = DECL_SIZE_UNIT (member);
@@ -13607,7 +13622,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
bool trailing = array_at_struct_end_p (ref);
bool zero_length = integer_zerop (memsize);
- if (!trailing && (!interior_zero_length || !zero_length))
+ if (!trailing && !zero_length)
/* MEMBER is either an interior array or is an array with
more than one element. */
return memsize;
@@ -13626,9 +13641,14 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
offset_int minidx = wi::to_offset (min);
offset_int maxidx = wi::to_offset (max);
if (maxidx - minidx > 0)
- /* MEMBER is an array with more than 1 element. */
+ /* MEMBER is an array with more than one element. */
return memsize;
}
+
+ /* For a refernce to a zero- or one-element array member of a union
+ use the size of the union instead of the size of the member. */
+ if (TREE_CODE (argtype) == UNION_TYPE)
+ memsize = TYPE_SIZE_UNIT (argtype);
}
/* MEMBER is either a bona fide flexible array member, or a zero-length
@@ -13643,28 +13663,27 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
if (!*interior_zero_length)
return NULL_TREE;
- if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF)
+ if (TREE_CODE (arg) != COMPONENT_REF)
return NULL_TREE;
- base = TREE_OPERAND (ref, 0);
+ base = arg;
while (TREE_CODE (base) == COMPONENT_REF)
base = TREE_OPERAND (base, 0);
baseoff = tree_to_poly_int64 (byte_position (TREE_OPERAND (ref, 1)));
}
/* BASE is the declared object of which MEMBER is either a member
- or that is is cast to REFTYPE (e.g., a char buffer used to store
- a REFTYPE object). */
- tree reftype = TREE_TYPE (TREE_OPERAND (ref, 0));
+ or that is cast to ARGTYPE (e.g., a char buffer used to store
+ an ARGTYPE object). */
tree basetype = TREE_TYPE (base);
/* Determine the base type of the referenced object. If it's
- the same as REFTYPE and MEMBER has a known size, return it. */
+ the same as ARGTYPE and MEMBER has a known size, return it. */
tree bt = basetype;
if (!*interior_zero_length)
while (TREE_CODE (bt) == ARRAY_TYPE)
bt = TREE_TYPE (bt);
- bool typematch = useless_type_conversion_p (reftype, bt);
+ bool typematch = useless_type_conversion_p (argtype, bt);
if (memsize && typematch)
return memsize;
@@ -13674,24 +13693,25 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */)
/* MEMBER is a true flexible array member. Compute its size from
the initializer of the BASE object if it has one. */
if (tree init = DECL_P (base) ? DECL_INITIAL (base) : NULL_TREE)
- {
- init = get_initializer_for (init, member);
- if (init)
- {
- memsize = TYPE_SIZE_UNIT (TREE_TYPE (init));
- if (tree refsize = TYPE_SIZE_UNIT (reftype))
- {
- /* Use the larger of the initializer size and the tail
- padding in the enclosing struct. */
- poly_int64 rsz = tree_to_poly_int64 (refsize);
- rsz -= baseoff;
- if (known_lt (tree_to_poly_int64 (memsize), rsz))
- memsize = wide_int_to_tree (TREE_TYPE (memsize), rsz);
- }
+ if (init != error_mark_node)
+ {
+ init = get_initializer_for (init, member);
+ if (init)
+ {
+ memsize = TYPE_SIZE_UNIT (TREE_TYPE (init));
+ if (tree refsize = TYPE_SIZE_UNIT (argtype))
+ {
+ /* Use the larger of the initializer size and the tail
+ padding in the enclosing struct. */
+ poly_int64 rsz = tree_to_poly_int64 (refsize);
+ rsz -= baseoff;
+ if (known_lt (tree_to_poly_int64 (memsize), rsz))
+ memsize = wide_int_to_tree (TREE_TYPE (memsize), rsz);
+ }
- baseoff = 0;
- }
- }
+ baseoff = 0;
+ }
+ }
if (!memsize)
{
@@ -13801,6 +13821,30 @@ vector_type_mode (const_tree t)
return mode;
}
+/* Return the size in bits of each element of vector type TYPE. */
+
+unsigned int
+vector_element_bits (const_tree type)
+{
+ gcc_checking_assert (VECTOR_TYPE_P (type));
+ if (VECTOR_BOOLEAN_TYPE_P (type))
+ return vector_element_size (tree_to_poly_uint64 (TYPE_SIZE (type)),
+ TYPE_VECTOR_SUBPARTS (type));
+ return tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type)));
+}
+
+/* Calculate the size in bits of each element of vector type TYPE
+ and return the result as a tree of type bitsizetype. */
+
+tree
+vector_element_bits_tree (const_tree type)
+{
+ gcc_checking_assert (VECTOR_TYPE_P (type));
+ if (VECTOR_BOOLEAN_TYPE_P (type))
+ return bitsize_int (vector_element_bits (type));
+ return TYPE_SIZE (TREE_TYPE (type));
+}
+
/* Verify that basic properties of T match TV and thus T can be a variant of
TV. TV should be the more specified variant (i.e. the main variant). */
@@ -13881,9 +13925,9 @@ verify_type_variant (const_tree t, tree tv)
debug_tree (TYPE_SIZE_UNIT (t));
return false;
}
+ verify_variant_match (TYPE_NEEDS_CONSTRUCTING);
}
verify_variant_match (TYPE_PRECISION);
- verify_variant_match (TYPE_NEEDS_CONSTRUCTING);
if (RECORD_OR_UNION_TYPE_P (t))
verify_variant_match (TYPE_TRANSPARENT_AGGR);
else if (TREE_CODE (t) == ARRAY_TYPE)