diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-17 07:50:57 -0400 |
commit | b9e67f2840ce0d8859d96e7f8df8fe9584af5eba (patch) | |
tree | ed3b7284ff15c802583f6409b9c71b3739642d15 /gcc/tree.c | |
parent | 1957047ed1c94bf17cf993a2b1866965f493ba87 (diff) | |
parent | 56638b9b1853666f575928f8baf17f70e4ed3517 (diff) | |
download | gcc-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.c | 206 |
1 files changed, 125 insertions, 81 deletions
@@ -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) |