From 1c9744fb3bf2fbf7cec5722f4b187eb553d98280 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 10 Apr 2021 11:17:56 +0200 Subject: Do not release body of declare_variant_alt gcc/ChangeLog: 2021-04-10 Jan Hubicka PR lto/99857 * tree.c (free_lang_data_in_decl): Do not release body of declare_variant_alt. --- gcc/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 7c44c22..e4e74ac 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5849,7 +5849,7 @@ free_lang_data_in_decl (tree decl, class free_lang_data_d *fld) if (!(node = cgraph_node::get (decl)) || (!node->definition && !node->clones)) { - if (node) + if (node && !node->declare_variant_alt) node->release_body (); else { -- cgit v1.1 From 8f48ec0946abdc036d74a157623b45fddd864a72 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 15 Mar 2021 09:45:41 +0100 Subject: Fix clang warnings. gcc/ChangeLog: * config/i386/i386.c: Remove superfluous || TARGET_MACHO which remains to be '(... || 0)' and clang complains about it. * dwarf2out.c (AT_vms_delta): Declare conditionally. (add_AT_vms_delta): Likewise. * tree.c (fld_simplified_type): Use rather more common pattern for disabling of something (#if 0). (get_tree_code_name): Likewise. (verify_type_variant): Likewise. --- gcc/tree.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index e4e74ac..6129d91 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5538,9 +5538,11 @@ fld_simplified_type (tree t, class free_lang_data_d *fld) if (POINTER_TYPE_P (t)) return fld_incomplete_type_of (t, fld); /* FIXME: This triggers verification error, see PR88140. */ - if (TREE_CODE (t) == ARRAY_TYPE && 0) +#if 0 + if (TREE_CODE (t) == ARRAY_TYPE) return fld_process_array_type (t, fld_simplified_type (TREE_TYPE (t), fld), fld_simplified_types, fld); +#endif return t; } @@ -13451,7 +13453,7 @@ get_tree_code_name (enum tree_code code) invalid values, so force an unsigned comparison. */ if (unsigned (code) >= MAX_TREE_CODES) { - if (code == 0xa5a5) + if ((unsigned)code == 0xa5a5) return "ggc_freed"; return invalid; } @@ -14099,8 +14101,10 @@ verify_type_variant (const_tree t, tree tv) verify_variant_match (TREE_CODE); /* FIXME: Ada builds non-artificial variants of artificial types. */ - if (TYPE_ARTIFICIAL (tv) && 0) +#if 0 + if (TYPE_ARTIFICIAL (tv)) verify_variant_match (TYPE_ARTIFICIAL); +#endif if (POINTER_TYPE_P (tv)) verify_variant_match (TYPE_REF_CAN_ALIAS_ALL); /* FIXME: TYPE_SIZES_GIMPLIFIED may differs for Ada build. */ @@ -14113,8 +14117,10 @@ verify_type_variant (const_tree t, tree tv) else verify_variant_match (TYPE_SATURATING); /* FIXME: This check trigger during libstdc++ build. */ - if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t) && 0) +#if 0 + if (RECORD_OR_UNION_TYPE_P (t) && COMPLETE_TYPE_P (t)) verify_variant_match (TYPE_FINAL_P); +#endif /* tree_type_common checks. */ @@ -14149,8 +14155,10 @@ verify_type_variant (const_tree t, tree tv) that may differ BY TYPE_CONTEXT that in turn may point to TRANSLATION_UNIT_DECL. Ada also builds variants of types with different TYPE_CONTEXT. */ - if ((!in_lto_p || !TYPE_FILE_SCOPE_P (t)) && 0) +#if 0 + if (!in_lto_p || !TYPE_FILE_SCOPE_P (t)) verify_variant_match (TYPE_CONTEXT); +#endif if (TREE_CODE (t) == ARRAY_TYPE || TREE_CODE (t) == INTEGER_TYPE) verify_variant_match (TYPE_STRING_FLAG); if (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE) -- cgit v1.1 From 2de7c792569d7a227426aaeb124686a856614da7 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Apr 2021 19:01:40 -0600 Subject: Move pass free_lang_data to its own file. gcc/ChangeLog: * Makefile.in (OBJS): Add ipa-free-lang-data.o. * ipa-free-lang-data.cc: New file. * tree.c: Move pass free_lang_data to file above. (build_array_type_1): Declare extern. * tree.h (build_array_type_1): Declare. --- gcc/tree.c | 1512 ++++++++---------------------------------------------------- 1 file changed, 184 insertions(+), 1328 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 6129d91..c5506a0 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -266,8 +266,6 @@ static void print_type_hash_statistics (void); static void print_debug_expr_statistics (void); static void print_value_expr_statistics (void); -static tree build_array_type_1 (tree, tree, bool, bool, bool); - tree global_trees[TI_MAX]; tree integer_types[itk_none]; @@ -722,6 +720,112 @@ overwrite_decl_assembler_name (tree decl, tree name) lang_hooks.overwrite_decl_assembler_name (decl, name); } +/* Return true if DECL may need an assembler name to be set. */ + +static inline bool +need_assembler_name_p (tree decl) +{ + /* We use DECL_ASSEMBLER_NAME to hold mangled type names for One Definition + Rule merging. This makes type_odr_p to return true on those types during + LTO and by comparing the mangled name, we can say what types are intended + to be equivalent across compilation unit. + + We do not store names of type_in_anonymous_namespace_p. + + Record, union and enumeration type have linkage that allows use + to check type_in_anonymous_namespace_p. We do not mangle compound types + that always can be compared structurally. + + Similarly for builtin types, we compare properties of their main variant. + A special case are integer types where mangling do make differences + between char/signed char/unsigned char etc. Storing name for these makes + e.g. -fno-signed-char/-fsigned-char mismatches to be handled well. + See cp/mangle.c:write_builtin_type for details. */ + + if (TREE_CODE (decl) == TYPE_DECL) + { + if (DECL_NAME (decl) + && decl == TYPE_NAME (TREE_TYPE (decl)) + && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl) + && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) + && ((TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE + && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE) + || TYPE_CXX_ODR_P (TREE_TYPE (decl))) + && (type_with_linkage_p (TREE_TYPE (decl)) + || TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE) + && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) + return !DECL_ASSEMBLER_NAME_SET_P (decl); + return false; + } + /* Only FUNCTION_DECLs and VAR_DECLs are considered. */ + if (!VAR_OR_FUNCTION_DECL_P (decl)) + return false; + + /* If DECL already has its assembler name set, it does not need a + new one. */ + if (!HAS_DECL_ASSEMBLER_NAME_P (decl) + || DECL_ASSEMBLER_NAME_SET_P (decl)) + return false; + + /* Abstract decls do not need an assembler name. */ + if (DECL_ABSTRACT_P (decl)) + return false; + + /* For VAR_DECLs, only static, public and external symbols need an + assembler name. */ + if (VAR_P (decl) + && !TREE_STATIC (decl) + && !TREE_PUBLIC (decl) + && !DECL_EXTERNAL (decl)) + return false; + + if (TREE_CODE (decl) == FUNCTION_DECL) + { + /* Do not set assembler name on builtins. Allow RTL expansion to + decide whether to expand inline or via a regular call. */ + if (fndecl_built_in_p (decl) + && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND) + return false; + + /* Functions represented in the callgraph need an assembler name. */ + if (cgraph_node::get (decl) != NULL) + return true; + + /* Unused and not public functions don't need an assembler name. */ + if (!TREE_USED (decl) && !TREE_PUBLIC (decl)) + return false; + } + + return true; +} + +/* If T needs an assembler name, have one created for it. */ + +void +assign_assembler_name_if_needed (tree t) +{ + if (need_assembler_name_p (t)) + { + /* When setting DECL_ASSEMBLER_NAME, the C++ mangler may emit + diagnostics that use input_location to show locus + information. The problem here is that, at this point, + input_location is generally anchored to the end of the file + (since the parser is long gone), so we don't have a good + position to pin it to. + + To alleviate this problem, this uses the location of T's + declaration. Examples of this are + testsuite/g++.dg/template/cond2.C and + testsuite/g++.dg/template/pr35240.C. */ + location_t saved_location = input_location; + input_location = DECL_SOURCE_LOCATION (t); + + decl_assembler_name (t); + + input_location = saved_location; + } +} + /* When the target supports COMDAT groups, this indicates which group the DECL is associated with. This can be either an IDENTIFIER_NODE or a decl, in which case its DECL_ASSEMBLER_NAME identifies the group. */ @@ -5245,1365 +5349,117 @@ protected_set_expr_location_if_unset (tree t, location_t loc) if (t && !EXPR_HAS_LOCATION (t)) protected_set_expr_location (t, loc); } - -/* Data used when collecting DECLs and TYPEs for language data removal. */ - -class free_lang_data_d -{ -public: - free_lang_data_d () : decls (100), types (100) {} - - /* Worklist to avoid excessive recursion. */ - auto_vec worklist; - - /* Set of traversed objects. Used to avoid duplicate visits. */ - hash_set pset; - - /* Array of symbols to process with free_lang_data_in_decl. */ - auto_vec decls; - - /* Array of types to process with free_lang_data_in_type. */ - auto_vec types; -}; - - -/* Add type or decl T to one of the list of tree nodes that need their - language data removed. The lists are held inside FLD. */ + +/* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask + of the various TYPE_QUAL values. */ static void -add_tree_to_fld_list (tree t, class free_lang_data_d *fld) +set_type_quals (tree type, int type_quals) { - if (DECL_P (t)) - fld->decls.safe_push (t); - else if (TYPE_P (t)) - fld->types.safe_push (t); - else - gcc_unreachable (); + TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0; + TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0; + TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0; + TYPE_ATOMIC (type) = (type_quals & TYPE_QUAL_ATOMIC) != 0; + TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals); } -/* Push tree node T into FLD->WORKLIST. */ +/* Returns true iff CAND and BASE have equivalent language-specific + qualifiers. */ -static inline void -fld_worklist_push (tree t, class free_lang_data_d *fld) +bool +check_lang_type (const_tree cand, const_tree base) { - if (t && !is_lang_specific (t) && !fld->pset.contains (t)) - fld->worklist.safe_push ((t)); -} - - - -/* Return simplified TYPE_NAME of TYPE. */ - -static tree -fld_simplified_type_name (tree type) -{ - if (!TYPE_NAME (type) || TREE_CODE (TYPE_NAME (type)) != TYPE_DECL) - return TYPE_NAME (type); - /* Drop TYPE_DECLs in TYPE_NAME in favor of the identifier in the - TYPE_DECL if the type doesn't have linkage. - this must match fld_ */ - if (type != TYPE_MAIN_VARIANT (type) - || (!DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (type)) - && (TREE_CODE (type) != RECORD_TYPE - || !TYPE_BINFO (type) - || !BINFO_VTABLE (TYPE_BINFO (type))))) - return DECL_NAME (TYPE_NAME (type)); - return TYPE_NAME (type); -} - -/* Do same comparsion as check_qualified_type skipping lang part of type - and be more permissive about type names: we only care that names are - same (for diagnostics) and that ODR names are the same. - If INNER_TYPE is non-NULL, be sure that TREE_TYPE match it. */ - -static bool -fld_type_variant_equal_p (tree t, tree v, tree inner_type) -{ - if (TYPE_QUALS (t) != TYPE_QUALS (v) - /* We want to match incomplete variants with complete types. - In this case we need to ignore alignment. */ - || ((!RECORD_OR_UNION_TYPE_P (t) || COMPLETE_TYPE_P (v)) - && (TYPE_ALIGN (t) != TYPE_ALIGN (v) - || TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (v))) - || fld_simplified_type_name (t) != fld_simplified_type_name (v) - || !attribute_list_equal (TYPE_ATTRIBUTES (t), - TYPE_ATTRIBUTES (v)) - || (inner_type && TREE_TYPE (v) != inner_type)) - return false; - - return true; + if (lang_hooks.types.type_hash_eq == NULL) + return true; + /* type_hash_eq currently only applies to these types. */ + if (TREE_CODE (cand) != FUNCTION_TYPE + && TREE_CODE (cand) != METHOD_TYPE) + return true; + return lang_hooks.types.type_hash_eq (cand, base); } -/* Find variant of FIRST that match T and create new one if necessary. - Set TREE_TYPE to INNER_TYPE if non-NULL. */ +/* This function checks to see if TYPE matches the size one of the built-in + atomic types, and returns that core atomic type. */ static tree -fld_type_variant (tree first, tree t, class free_lang_data_d *fld, - tree inner_type = NULL) +find_atomic_core_type (const_tree type) { - if (first == TYPE_MAIN_VARIANT (t)) - return t; - for (tree v = first; v; v = TYPE_NEXT_VARIANT (v)) - if (fld_type_variant_equal_p (t, v, inner_type)) - return v; - tree v = build_variant_type_copy (first); - TYPE_READONLY (v) = TYPE_READONLY (t); - TYPE_VOLATILE (v) = TYPE_VOLATILE (t); - TYPE_ATOMIC (v) = TYPE_ATOMIC (t); - TYPE_RESTRICT (v) = TYPE_RESTRICT (t); - TYPE_ADDR_SPACE (v) = TYPE_ADDR_SPACE (t); - TYPE_NAME (v) = TYPE_NAME (t); - TYPE_ATTRIBUTES (v) = TYPE_ATTRIBUTES (t); - TYPE_CANONICAL (v) = TYPE_CANONICAL (t); - /* Variants of incomplete types should have alignment - set to BITS_PER_UNIT. Do not copy the actual alignment. */ - if (!RECORD_OR_UNION_TYPE_P (v) || COMPLETE_TYPE_P (v)) - { - SET_TYPE_ALIGN (v, TYPE_ALIGN (t)); - TYPE_USER_ALIGN (v) = TYPE_USER_ALIGN (t); - } - if (inner_type) - TREE_TYPE (v) = inner_type; - gcc_checking_assert (fld_type_variant_equal_p (t,v, inner_type)); - if (!fld->pset.add (v)) - add_tree_to_fld_list (v, fld); - return v; -} - -/* Map complete types to incomplete types. */ + tree base_atomic_type; -static hash_map *fld_incomplete_types; + /* Only handle complete types. */ + if (!tree_fits_uhwi_p (TYPE_SIZE (type))) + return NULL_TREE; -/* Map types to simplified types. */ + switch (tree_to_uhwi (TYPE_SIZE (type))) + { + case 8: + base_atomic_type = atomicQI_type_node; + break; -static hash_map *fld_simplified_types; + case 16: + base_atomic_type = atomicHI_type_node; + break; -/* Produce variant of T whose TREE_TYPE is T2. If it is main variant, - use MAP to prevent duplicates. */ + case 32: + base_atomic_type = atomicSI_type_node; + break; -static tree -fld_process_array_type (tree t, tree t2, hash_map *map, - class free_lang_data_d *fld) -{ - if (TREE_TYPE (t) == t2) - return t; + case 64: + base_atomic_type = atomicDI_type_node; + break; - if (TYPE_MAIN_VARIANT (t) != t) - { - return fld_type_variant - (fld_process_array_type (TYPE_MAIN_VARIANT (t), - TYPE_MAIN_VARIANT (t2), map, fld), - t, fld, t2); - } + case 128: + base_atomic_type = atomicTI_type_node; + break; - bool existed; - tree &array - = map->get_or_insert (t, &existed); - if (!existed) - { - array - = build_array_type_1 (t2, TYPE_DOMAIN (t), TYPE_TYPELESS_STORAGE (t), - false, false); - TYPE_CANONICAL (array) = TYPE_CANONICAL (t); - if (!fld->pset.add (array)) - add_tree_to_fld_list (array, fld); + default: + base_atomic_type = NULL_TREE; } - return array; -} -/* Return CTX after removal of contexts that are not relevant */ - -static tree -fld_decl_context (tree ctx) -{ - /* Variably modified types are needed for tree_is_indexable to decide - whether the type needs to go to local or global section. - This code is semi-broken but for now it is easiest to keep contexts - as expected. */ - if (ctx && TYPE_P (ctx) - && !variably_modified_type_p (ctx, NULL_TREE)) - { - while (ctx && TYPE_P (ctx)) - ctx = TYPE_CONTEXT (ctx); - } - return ctx; + return base_atomic_type; } -/* For T being aggregate type try to turn it into a incomplete variant. - Return T if no simplification is possible. */ +/* Returns true iff unqualified CAND and BASE are equivalent. */ -static tree -fld_incomplete_type_of (tree t, class free_lang_data_d *fld) +bool +check_base_type (const_tree cand, const_tree base) { - if (!t) - return NULL; - if (POINTER_TYPE_P (t)) + if (TYPE_NAME (cand) != TYPE_NAME (base) + /* Apparently this is needed for Objective-C. */ + || TYPE_CONTEXT (cand) != TYPE_CONTEXT (base) + || !attribute_list_equal (TYPE_ATTRIBUTES (cand), + TYPE_ATTRIBUTES (base))) + return false; + /* Check alignment. */ + if (TYPE_ALIGN (cand) == TYPE_ALIGN (base) + && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base)) + return true; + /* Atomic types increase minimal alignment. We must to do so as well + or we get duplicated canonical types. See PR88686. */ + if ((TYPE_QUALS (cand) & TYPE_QUAL_ATOMIC)) { - tree t2 = fld_incomplete_type_of (TREE_TYPE (t), fld); - if (t2 != TREE_TYPE (t)) - { - tree first; - if (TREE_CODE (t) == POINTER_TYPE) - first = build_pointer_type_for_mode (t2, TYPE_MODE (t), - TYPE_REF_CAN_ALIAS_ALL (t)); - else - first = build_reference_type_for_mode (t2, TYPE_MODE (t), - TYPE_REF_CAN_ALIAS_ALL (t)); - gcc_assert (TYPE_CANONICAL (t2) != t2 - && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t))); - if (!fld->pset.add (first)) - add_tree_to_fld_list (first, fld); - return fld_type_variant (first, t, fld); - } - return t; + /* See if this object can map to a basic atomic type. */ + tree atomic_type = find_atomic_core_type (cand); + if (atomic_type && TYPE_ALIGN (atomic_type) == TYPE_ALIGN (cand)) + return true; } - if (TREE_CODE (t) == ARRAY_TYPE) - return fld_process_array_type (t, - fld_incomplete_type_of (TREE_TYPE (t), fld), - fld_incomplete_types, fld); - if ((!RECORD_OR_UNION_TYPE_P (t) && TREE_CODE (t) != ENUMERAL_TYPE) - || !COMPLETE_TYPE_P (t)) - return t; - if (TYPE_MAIN_VARIANT (t) == t) - { - bool existed; - tree © - = fld_incomplete_types->get_or_insert (t, &existed); - - if (!existed) - { - copy = build_distinct_type_copy (t); - - /* It is possible that type was not seen by free_lang_data yet. */ - if (!fld->pset.add (copy)) - add_tree_to_fld_list (copy, fld); - TYPE_SIZE (copy) = NULL; - TYPE_USER_ALIGN (copy) = 0; - TYPE_SIZE_UNIT (copy) = NULL; - TYPE_CANONICAL (copy) = TYPE_CANONICAL (t); - TREE_ADDRESSABLE (copy) = 0; - if (AGGREGATE_TYPE_P (t)) - { - SET_TYPE_MODE (copy, VOIDmode); - SET_TYPE_ALIGN (copy, BITS_PER_UNIT); - TYPE_TYPELESS_STORAGE (copy) = 0; - TYPE_FIELDS (copy) = NULL; - TYPE_BINFO (copy) = NULL; - TYPE_FINAL_P (copy) = 0; - TYPE_EMPTY_P (copy) = 0; - } - else - { - TYPE_VALUES (copy) = NULL; - ENUM_IS_OPAQUE (copy) = 0; - ENUM_IS_SCOPED (copy) = 0; - } - - /* Build copy of TYPE_DECL in TYPE_NAME if necessary. - This is needed for ODR violation warnings to come out right (we - want duplicate TYPE_DECLs whenever the type is duplicated because - of ODR violation. Because lang data in the TYPE_DECL may not - have been freed yet, rebuild it from scratch and copy relevant - fields. */ - TYPE_NAME (copy) = fld_simplified_type_name (copy); - tree name = TYPE_NAME (copy); - - if (name && TREE_CODE (name) == TYPE_DECL) - { - gcc_checking_assert (TREE_TYPE (name) == t); - tree name2 = build_decl (DECL_SOURCE_LOCATION (name), TYPE_DECL, - DECL_NAME (name), copy); - if (DECL_ASSEMBLER_NAME_SET_P (name)) - SET_DECL_ASSEMBLER_NAME (name2, DECL_ASSEMBLER_NAME (name)); - SET_DECL_ALIGN (name2, 0); - DECL_CONTEXT (name2) = fld_decl_context - (DECL_CONTEXT (name)); - TYPE_NAME (copy) = name2; - } - } - return copy; - } - return (fld_type_variant - (fld_incomplete_type_of (TYPE_MAIN_VARIANT (t), fld), t, fld)); + return false; } -/* Simplify type T for scenarios where we do not need complete pointer - types. */ +/* Returns true iff CAND is equivalent to BASE with TYPE_QUALS. */ -static tree -fld_simplified_type (tree t, class free_lang_data_d *fld) +bool +check_qualified_type (const_tree cand, const_tree base, int type_quals) { - if (!t) - return t; - if (POINTER_TYPE_P (t)) - return fld_incomplete_type_of (t, fld); - /* FIXME: This triggers verification error, see PR88140. */ -#if 0 - if (TREE_CODE (t) == ARRAY_TYPE) - return fld_process_array_type (t, fld_simplified_type (TREE_TYPE (t), fld), - fld_simplified_types, fld); -#endif - return t; + return (TYPE_QUALS (cand) == type_quals + && check_base_type (cand, base) + && check_lang_type (cand, base)); } -/* Reset the expression *EXPR_P, a size or position. - - ??? We could reset all non-constant sizes or positions. But it's cheap - enough to not do so and refrain from adding workarounds to dwarf2out.c. - - We need to reset self-referential sizes or positions because they cannot - be gimplified and thus can contain a CALL_EXPR after the gimplification - is finished, which will run afoul of LTO streaming. And they need to be - reset to something essentially dummy but not constant, so as to preserve - the properties of the object they are attached to. */ +/* Returns true iff CAND is equivalent to BASE with ALIGN. */ -static inline void -free_lang_data_in_one_sizepos (tree *expr_p) -{ - tree expr = *expr_p; - if (CONTAINS_PLACEHOLDER_P (expr)) - *expr_p = build0 (PLACEHOLDER_EXPR, TREE_TYPE (expr)); -} - - -/* Reset all the fields in a binfo node BINFO. We only keep - BINFO_VTABLE, which is used by gimple_fold_obj_type_ref. */ - -static void -free_lang_data_in_binfo (tree binfo) -{ - unsigned i; - tree t; - - gcc_assert (TREE_CODE (binfo) == TREE_BINFO); - - BINFO_VIRTUALS (binfo) = NULL_TREE; - BINFO_BASE_ACCESSES (binfo) = NULL; - BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE; - BINFO_SUBVTT_INDEX (binfo) = NULL_TREE; - BINFO_VPTR_FIELD (binfo) = NULL_TREE; - TREE_PUBLIC (binfo) = 0; - - FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (binfo), i, t) - free_lang_data_in_binfo (t); -} - - -/* Reset all language specific information still present in TYPE. */ - -static void -free_lang_data_in_type (tree type, class free_lang_data_d *fld) -{ - gcc_assert (TYPE_P (type)); - - /* Give the FE a chance to remove its own data first. */ - lang_hooks.free_lang_data (type); - - TREE_LANG_FLAG_0 (type) = 0; - TREE_LANG_FLAG_1 (type) = 0; - TREE_LANG_FLAG_2 (type) = 0; - TREE_LANG_FLAG_3 (type) = 0; - TREE_LANG_FLAG_4 (type) = 0; - TREE_LANG_FLAG_5 (type) = 0; - TREE_LANG_FLAG_6 (type) = 0; - - TYPE_NEEDS_CONSTRUCTING (type) = 0; - - /* Purge non-marked variants from the variants chain, so that they - don't reappear in the IL after free_lang_data. */ - while (TYPE_NEXT_VARIANT (type) - && !fld->pset.contains (TYPE_NEXT_VARIANT (type))) - { - tree t = TYPE_NEXT_VARIANT (type); - TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (t); - /* Turn the removed types into distinct types. */ - TYPE_MAIN_VARIANT (t) = t; - TYPE_NEXT_VARIANT (t) = NULL_TREE; - } - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld); - /* Remove the const and volatile qualifiers from arguments. The - C++ front end removes them, but the C front end does not, - leading to false ODR violation errors when merging two - instances of the same function signature compiled by - different front ends. */ - for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p)) - { - TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld); - tree arg_type = TREE_VALUE (p); - - if (TYPE_READONLY (arg_type) || TYPE_VOLATILE (arg_type)) - { - int quals = TYPE_QUALS (arg_type) - & ~TYPE_QUAL_CONST - & ~TYPE_QUAL_VOLATILE; - TREE_VALUE (p) = build_qualified_type (arg_type, quals); - if (!fld->pset.add (TREE_VALUE (p))) - free_lang_data_in_type (TREE_VALUE (p), fld); - } - /* C++ FE uses TREE_PURPOSE to store initial values. */ - TREE_PURPOSE (p) = NULL; - } - } - else if (TREE_CODE (type) == METHOD_TYPE) - { - TREE_TYPE (type) = fld_simplified_type (TREE_TYPE (type), fld); - for (tree p = TYPE_ARG_TYPES (type); p; p = TREE_CHAIN (p)) - { - /* C++ FE uses TREE_PURPOSE to store initial values. */ - TREE_VALUE (p) = fld_simplified_type (TREE_VALUE (p), fld); - TREE_PURPOSE (p) = NULL; - } - } - else if (RECORD_OR_UNION_TYPE_P (type)) - { - /* Remove members that are not FIELD_DECLs from the field list - of an aggregate. These occur in C++. */ - for (tree *prev = &TYPE_FIELDS (type), member; (member = *prev);) - if (TREE_CODE (member) == FIELD_DECL) - prev = &DECL_CHAIN (member); - else - *prev = DECL_CHAIN (member); - - TYPE_VFIELD (type) = NULL_TREE; - - if (TYPE_BINFO (type)) - { - free_lang_data_in_binfo (TYPE_BINFO (type)); - /* We need to preserve link to bases and virtual table for all - polymorphic types to make devirtualization machinery working. */ - if (!BINFO_VTABLE (TYPE_BINFO (type))) - TYPE_BINFO (type) = NULL; - } - } - else if (INTEGRAL_TYPE_P (type) - || SCALAR_FLOAT_TYPE_P (type) - || FIXED_POINT_TYPE_P (type)) - { - if (TREE_CODE (type) == ENUMERAL_TYPE) - { - ENUM_IS_OPAQUE (type) = 0; - ENUM_IS_SCOPED (type) = 0; - /* 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_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 - register_odr_enum (type); - } - free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type)); - free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type)); - } - - TYPE_LANG_SLOT_1 (type) = NULL_TREE; - - free_lang_data_in_one_sizepos (&TYPE_SIZE (type)); - free_lang_data_in_one_sizepos (&TYPE_SIZE_UNIT (type)); - - if (TYPE_CONTEXT (type) - && TREE_CODE (TYPE_CONTEXT (type)) == BLOCK) - { - tree ctx = TYPE_CONTEXT (type); - do - { - ctx = BLOCK_SUPERCONTEXT (ctx); - } - while (ctx && TREE_CODE (ctx) == BLOCK); - TYPE_CONTEXT (type) = ctx; - } - - TYPE_STUB_DECL (type) = NULL; - TYPE_NAME (type) = fld_simplified_type_name (type); -} - - -/* Return true if DECL may need an assembler name to be set. */ - -static inline bool -need_assembler_name_p (tree decl) -{ - /* We use DECL_ASSEMBLER_NAME to hold mangled type names for One Definition - Rule merging. This makes type_odr_p to return true on those types during - LTO and by comparing the mangled name, we can say what types are intended - to be equivalent across compilation unit. - - We do not store names of type_in_anonymous_namespace_p. - - Record, union and enumeration type have linkage that allows use - to check type_in_anonymous_namespace_p. We do not mangle compound types - that always can be compared structurally. - - Similarly for builtin types, we compare properties of their main variant. - A special case are integer types where mangling do make differences - between char/signed char/unsigned char etc. Storing name for these makes - e.g. -fno-signed-char/-fsigned-char mismatches to be handled well. - See cp/mangle.c:write_builtin_type for details. */ - - if (TREE_CODE (decl) == TYPE_DECL) - { - if (DECL_NAME (decl) - && decl == TYPE_NAME (TREE_TYPE (decl)) - && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TREE_TYPE (decl) - && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) - && ((TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE - && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE) - || TYPE_CXX_ODR_P (TREE_TYPE (decl))) - && (type_with_linkage_p (TREE_TYPE (decl)) - || TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE) - && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE)) - return !DECL_ASSEMBLER_NAME_SET_P (decl); - return false; - } - /* Only FUNCTION_DECLs and VAR_DECLs are considered. */ - if (!VAR_OR_FUNCTION_DECL_P (decl)) - return false; - - /* If DECL already has its assembler name set, it does not need a - new one. */ - if (!HAS_DECL_ASSEMBLER_NAME_P (decl) - || DECL_ASSEMBLER_NAME_SET_P (decl)) - return false; - - /* Abstract decls do not need an assembler name. */ - if (DECL_ABSTRACT_P (decl)) - return false; - - /* For VAR_DECLs, only static, public and external symbols need an - assembler name. */ - if (VAR_P (decl) - && !TREE_STATIC (decl) - && !TREE_PUBLIC (decl) - && !DECL_EXTERNAL (decl)) - return false; - - if (TREE_CODE (decl) == FUNCTION_DECL) - { - /* Do not set assembler name on builtins. Allow RTL expansion to - decide whether to expand inline or via a regular call. */ - if (fndecl_built_in_p (decl) - && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND) - return false; - - /* Functions represented in the callgraph need an assembler name. */ - if (cgraph_node::get (decl) != NULL) - return true; - - /* Unused and not public functions don't need an assembler name. */ - if (!TREE_USED (decl) && !TREE_PUBLIC (decl)) - return false; - } - - return true; -} - - -/* Reset all language specific information still present in symbol - DECL. */ - -static void -free_lang_data_in_decl (tree decl, class free_lang_data_d *fld) -{ - gcc_assert (DECL_P (decl)); - - /* Give the FE a chance to remove its own data first. */ - lang_hooks.free_lang_data (decl); - - TREE_LANG_FLAG_0 (decl) = 0; - TREE_LANG_FLAG_1 (decl) = 0; - TREE_LANG_FLAG_2 (decl) = 0; - TREE_LANG_FLAG_3 (decl) = 0; - TREE_LANG_FLAG_4 (decl) = 0; - TREE_LANG_FLAG_5 (decl) = 0; - TREE_LANG_FLAG_6 (decl) = 0; - - free_lang_data_in_one_sizepos (&DECL_SIZE (decl)); - free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl)); - if (TREE_CODE (decl) == FIELD_DECL) - { - DECL_FCONTEXT (decl) = NULL; - free_lang_data_in_one_sizepos (&DECL_FIELD_OFFSET (decl)); - if (TREE_CODE (DECL_CONTEXT (decl)) == QUAL_UNION_TYPE) - DECL_QUALIFIER (decl) = NULL_TREE; - } - - if (TREE_CODE (decl) == FUNCTION_DECL) - { - struct cgraph_node *node; - /* Frontends do not set TREE_ADDRESSABLE on public variables even though - the address may be taken in other unit, so this flag has no practical - use for middle-end. - - It would make more sense if frontends set TREE_ADDRESSABLE to 0 only - for public objects that indeed cannot be adressed, but it is not - the case. Set the flag to true so we do not get merge failures for - i.e. virtual tables between units that take address of it and - units that don't. */ - if (TREE_PUBLIC (decl)) - TREE_ADDRESSABLE (decl) = true; - TREE_TYPE (decl) = fld_simplified_type (TREE_TYPE (decl), fld); - if (!(node = cgraph_node::get (decl)) - || (!node->definition && !node->clones)) - { - if (node && !node->declare_variant_alt) - node->release_body (); - else - { - release_function_body (decl); - DECL_ARGUMENTS (decl) = NULL; - DECL_RESULT (decl) = NULL; - DECL_INITIAL (decl) = error_mark_node; - } - } - if (gimple_has_body_p (decl) || (node && node->thunk)) - { - tree t; - - /* If DECL has a gimple body, then the context for its - arguments must be DECL. Otherwise, it doesn't really - matter, as we will not be emitting any code for DECL. In - general, there may be other instances of DECL created by - the front end and since PARM_DECLs are generally shared, - their DECL_CONTEXT changes as the replicas of DECL are - created. The only time where DECL_CONTEXT is important - is for the FUNCTION_DECLs that have a gimple body (since - the PARM_DECL will be used in the function's body). */ - for (t = DECL_ARGUMENTS (decl); t; t = TREE_CHAIN (t)) - DECL_CONTEXT (t) = decl; - if (!DECL_FUNCTION_SPECIFIC_TARGET (decl)) - DECL_FUNCTION_SPECIFIC_TARGET (decl) - = target_option_default_node; - if (!DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)) - DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl) - = optimization_default_node; - } - - /* DECL_SAVED_TREE holds the GENERIC representation for DECL. - At this point, it is not needed anymore. */ - DECL_SAVED_TREE (decl) = NULL_TREE; - - /* Clear the abstract origin if it refers to a method. - Otherwise dwarf2out.c will ICE as we splice functions out of - TYPE_FIELDS and thus the origin will not be output - correctly. */ - if (DECL_ABSTRACT_ORIGIN (decl) - && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)) - && RECORD_OR_UNION_TYPE_P - (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)))) - DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE; - - DECL_VINDEX (decl) = NULL_TREE; - } - else if (VAR_P (decl)) - { - /* See comment above why we set the flag for functions. */ - if (TREE_PUBLIC (decl)) - TREE_ADDRESSABLE (decl) = true; - if ((DECL_EXTERNAL (decl) - && (!TREE_STATIC (decl) || !TREE_READONLY (decl))) - || (decl_function_context (decl) && !TREE_STATIC (decl))) - DECL_INITIAL (decl) = NULL_TREE; - } - else if (TREE_CODE (decl) == TYPE_DECL) - { - DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; - DECL_VISIBILITY_SPECIFIED (decl) = 0; - TREE_PUBLIC (decl) = 0; - TREE_PRIVATE (decl) = 0; - DECL_ARTIFICIAL (decl) = 0; - TYPE_DECL_SUPPRESS_DEBUG (decl) = 0; - DECL_INITIAL (decl) = NULL_TREE; - DECL_ORIGINAL_TYPE (decl) = NULL_TREE; - DECL_MODE (decl) = VOIDmode; - SET_DECL_ALIGN (decl, 0); - /* TREE_TYPE is cleared at WPA time in free_odr_warning_data. */ - } - else if (TREE_CODE (decl) == FIELD_DECL) - { - TREE_TYPE (decl) = fld_simplified_type (TREE_TYPE (decl), fld); - DECL_INITIAL (decl) = NULL_TREE; - } - else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL - && DECL_INITIAL (decl) - && TREE_CODE (DECL_INITIAL (decl)) == BLOCK) - { - /* Strip builtins from the translation-unit BLOCK. We still have targets - without builtin_decl_explicit support and also builtins are shared - nodes and thus we can't use TREE_CHAIN in multiple lists. */ - tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl)); - while (*nextp) - { - tree var = *nextp; - if (TREE_CODE (var) == FUNCTION_DECL - && fndecl_built_in_p (var)) - *nextp = TREE_CHAIN (var); - else - nextp = &TREE_CHAIN (var); - } - } - /* We need to keep field decls associated with their trees. Otherwise tree - merging may merge some fileds and keep others disjoint wich in turn will - not do well with TREE_CHAIN pointers linking them. - - Also do not drop containing types for virtual methods and tables because - these are needed by devirtualization. - C++ destructors are special because C++ frontends sometimes produces - virtual destructor as an alias of non-virtual destructor. In - devirutalization code we always walk through aliases and we need - context to be preserved too. See PR89335 */ - if (TREE_CODE (decl) != FIELD_DECL - && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL) - || (!DECL_VIRTUAL_P (decl) - && (TREE_CODE (decl) != FUNCTION_DECL - || !DECL_CXX_DESTRUCTOR_P (decl))))) - DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl)); -} - - -/* Operand callback helper for free_lang_data_in_node. *TP is the - subtree operand being considered. */ - -static tree -find_decls_types_r (tree *tp, int *ws, void *data) -{ - tree t = *tp; - class free_lang_data_d *fld = (class free_lang_data_d *) data; - - if (TREE_CODE (t) == TREE_LIST) - return NULL_TREE; - - /* Language specific nodes will be removed, so there is no need - to gather anything under them. */ - if (is_lang_specific (t)) - { - *ws = 0; - return NULL_TREE; - } - - if (DECL_P (t)) - { - /* Note that walk_tree does not traverse every possible field in - decls, so we have to do our own traversals here. */ - add_tree_to_fld_list (t, fld); - - fld_worklist_push (DECL_NAME (t), fld); - fld_worklist_push (DECL_CONTEXT (t), fld); - fld_worklist_push (DECL_SIZE (t), fld); - fld_worklist_push (DECL_SIZE_UNIT (t), fld); - - /* We are going to remove everything under DECL_INITIAL for - TYPE_DECLs. No point walking them. */ - if (TREE_CODE (t) != TYPE_DECL) - fld_worklist_push (DECL_INITIAL (t), fld); - - fld_worklist_push (DECL_ATTRIBUTES (t), fld); - fld_worklist_push (DECL_ABSTRACT_ORIGIN (t), fld); - - if (TREE_CODE (t) == FUNCTION_DECL) - { - fld_worklist_push (DECL_ARGUMENTS (t), fld); - fld_worklist_push (DECL_RESULT (t), fld); - } - else if (TREE_CODE (t) == FIELD_DECL) - { - fld_worklist_push (DECL_FIELD_OFFSET (t), fld); - fld_worklist_push (DECL_BIT_FIELD_TYPE (t), fld); - fld_worklist_push (DECL_FIELD_BIT_OFFSET (t), fld); - fld_worklist_push (DECL_FCONTEXT (t), fld); - } - - if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL) - && DECL_HAS_VALUE_EXPR_P (t)) - fld_worklist_push (DECL_VALUE_EXPR (t), fld); - - if (TREE_CODE (t) != FIELD_DECL - && TREE_CODE (t) != TYPE_DECL) - fld_worklist_push (TREE_CHAIN (t), fld); - *ws = 0; - } - else if (TYPE_P (t)) - { - /* Note that walk_tree does not traverse every possible field in - types, so we have to do our own traversals here. */ - add_tree_to_fld_list (t, fld); - - if (!RECORD_OR_UNION_TYPE_P (t)) - fld_worklist_push (TYPE_CACHED_VALUES (t), fld); - fld_worklist_push (TYPE_SIZE (t), fld); - fld_worklist_push (TYPE_SIZE_UNIT (t), fld); - fld_worklist_push (TYPE_ATTRIBUTES (t), fld); - fld_worklist_push (TYPE_POINTER_TO (t), fld); - fld_worklist_push (TYPE_REFERENCE_TO (t), fld); - fld_worklist_push (TYPE_NAME (t), fld); - /* While we do not stream TYPE_POINTER_TO and TYPE_REFERENCE_TO - lists, we may look types up in these lists and use them while - optimizing the function body. Thus we need to free lang data - in them. */ - if (TREE_CODE (t) == POINTER_TYPE) - fld_worklist_push (TYPE_NEXT_PTR_TO (t), fld); - if (TREE_CODE (t) == REFERENCE_TYPE) - fld_worklist_push (TYPE_NEXT_REF_TO (t), fld); - if (!POINTER_TYPE_P (t)) - fld_worklist_push (TYPE_MIN_VALUE_RAW (t), fld); - /* TYPE_MAX_VALUE_RAW is TYPE_BINFO for record types. */ - if (!RECORD_OR_UNION_TYPE_P (t)) - fld_worklist_push (TYPE_MAX_VALUE_RAW (t), fld); - fld_worklist_push (TYPE_MAIN_VARIANT (t), fld); - /* Do not walk TYPE_NEXT_VARIANT. We do not stream it and thus - do not and want not to reach unused variants this way. */ - if (TYPE_CONTEXT (t)) - { - tree ctx = TYPE_CONTEXT (t); - /* We adjust BLOCK TYPE_CONTEXTs to the innermost non-BLOCK one. - So push that instead. */ - while (ctx && TREE_CODE (ctx) == BLOCK) - ctx = BLOCK_SUPERCONTEXT (ctx); - fld_worklist_push (ctx, fld); - } - fld_worklist_push (TYPE_CANONICAL (t), fld); - - if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t)) - { - unsigned i; - tree tem; - FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (TYPE_BINFO (t)), i, tem) - fld_worklist_push (TREE_TYPE (tem), fld); - fld_worklist_push (BINFO_TYPE (TYPE_BINFO (t)), fld); - fld_worklist_push (BINFO_VTABLE (TYPE_BINFO (t)), fld); - } - if (RECORD_OR_UNION_TYPE_P (t)) - { - tree tem; - /* Push all TYPE_FIELDS - there can be interleaving interesting - and non-interesting things. */ - tem = TYPE_FIELDS (t); - while (tem) - { - if (TREE_CODE (tem) == FIELD_DECL) - fld_worklist_push (tem, fld); - tem = TREE_CHAIN (tem); - } - } - if (FUNC_OR_METHOD_TYPE_P (t)) - fld_worklist_push (TYPE_METHOD_BASETYPE (t), fld); - - fld_worklist_push (TYPE_STUB_DECL (t), fld); - *ws = 0; - } - else if (TREE_CODE (t) == BLOCK) - { - for (tree *tem = &BLOCK_VARS (t); *tem; ) - { - if (TREE_CODE (*tem) != LABEL_DECL - && (TREE_CODE (*tem) != VAR_DECL - || !auto_var_in_fn_p (*tem, DECL_CONTEXT (*tem)))) - { - gcc_assert (TREE_CODE (*tem) != RESULT_DECL - && TREE_CODE (*tem) != PARM_DECL); - *tem = TREE_CHAIN (*tem); - } - else - { - fld_worklist_push (*tem, fld); - tem = &TREE_CHAIN (*tem); - } - } - for (tree tem = BLOCK_SUBBLOCKS (t); tem; tem = BLOCK_CHAIN (tem)) - fld_worklist_push (tem, fld); - fld_worklist_push (BLOCK_ABSTRACT_ORIGIN (t), fld); - } - - if (TREE_CODE (t) != IDENTIFIER_NODE - && CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)) - fld_worklist_push (TREE_TYPE (t), fld); - - return NULL_TREE; -} - - -/* Find decls and types in T. */ - -static void -find_decls_types (tree t, class free_lang_data_d *fld) -{ - while (1) - { - if (!fld->pset.contains (t)) - walk_tree (&t, find_decls_types_r, fld, &fld->pset); - if (fld->worklist.is_empty ()) - break; - t = fld->worklist.pop (); - } -} - -/* Translate all the types in LIST with the corresponding runtime - types. */ - -static tree -get_eh_types_for_runtime (tree list) -{ - tree head, prev; - - if (list == NULL_TREE) - return NULL_TREE; - - head = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list))); - prev = head; - list = TREE_CHAIN (list); - while (list) - { - tree n = build_tree_list (0, lookup_type_for_runtime (TREE_VALUE (list))); - TREE_CHAIN (prev) = n; - prev = TREE_CHAIN (prev); - list = TREE_CHAIN (list); - } - - return head; -} - - -/* Find decls and types referenced in EH region R and store them in - FLD->DECLS and FLD->TYPES. */ - -static void -find_decls_types_in_eh_region (eh_region r, class free_lang_data_d *fld) -{ - switch (r->type) - { - case ERT_CLEANUP: - break; - - case ERT_TRY: - { - eh_catch c; - - /* The types referenced in each catch must first be changed to the - EH types used at runtime. This removes references to FE types - in the region. */ - for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) - { - c->type_list = get_eh_types_for_runtime (c->type_list); - walk_tree (&c->type_list, find_decls_types_r, fld, &fld->pset); - } - } - break; - - case ERT_ALLOWED_EXCEPTIONS: - r->u.allowed.type_list - = get_eh_types_for_runtime (r->u.allowed.type_list); - walk_tree (&r->u.allowed.type_list, find_decls_types_r, fld, &fld->pset); - break; - - case ERT_MUST_NOT_THROW: - walk_tree (&r->u.must_not_throw.failure_decl, - find_decls_types_r, fld, &fld->pset); - break; - } -} - - -/* Find decls and types referenced in cgraph node N and store them in - FLD->DECLS and FLD->TYPES. Unlike pass_referenced_vars, this will - look for *every* kind of DECL and TYPE node reachable from N, - including those embedded inside types and decls (i.e,, TYPE_DECLs, - NAMESPACE_DECLs, etc). */ - -static void -find_decls_types_in_node (struct cgraph_node *n, class free_lang_data_d *fld) -{ - basic_block bb; - struct function *fn; - unsigned ix; - tree t; - - find_decls_types (n->decl, fld); - - if (!gimple_has_body_p (n->decl)) - return; - - gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); - - fn = DECL_STRUCT_FUNCTION (n->decl); - - /* Traverse locals. */ - FOR_EACH_LOCAL_DECL (fn, ix, t) - find_decls_types (t, fld); - - /* Traverse EH regions in FN. */ - { - eh_region r; - FOR_ALL_EH_REGION_FN (r, fn) - find_decls_types_in_eh_region (r, fld); - } - - /* Traverse every statement in FN. */ - FOR_EACH_BB_FN (bb, fn) - { - gphi_iterator psi; - gimple_stmt_iterator si; - unsigned i; - - for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi)) - { - gphi *phi = psi.phi (); - - for (i = 0; i < gimple_phi_num_args (phi); i++) - { - tree *arg_p = gimple_phi_arg_def_ptr (phi, i); - find_decls_types (*arg_p, fld); - } - } - - for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) - { - gimple *stmt = gsi_stmt (si); - - if (is_gimple_call (stmt)) - find_decls_types (gimple_call_fntype (stmt), fld); - - for (i = 0; i < gimple_num_ops (stmt); i++) - { - tree arg = gimple_op (stmt, i); - find_decls_types (arg, fld); - /* find_decls_types doesn't walk TREE_PURPOSE of TREE_LISTs, - which we need for asm stmts. */ - if (arg - && TREE_CODE (arg) == TREE_LIST - && TREE_PURPOSE (arg) - && gimple_code (stmt) == GIMPLE_ASM) - find_decls_types (TREE_PURPOSE (arg), fld); - } - } - } -} - - -/* Find decls and types referenced in varpool node N and store them in - FLD->DECLS and FLD->TYPES. Unlike pass_referenced_vars, this will - look for *every* kind of DECL and TYPE node reachable from N, - including those embedded inside types and decls (i.e,, TYPE_DECLs, - NAMESPACE_DECLs, etc). */ - -static void -find_decls_types_in_var (varpool_node *v, class free_lang_data_d *fld) -{ - find_decls_types (v->decl, fld); -} - -/* If T needs an assembler name, have one created for it. */ - -void -assign_assembler_name_if_needed (tree t) -{ - if (need_assembler_name_p (t)) - { - /* When setting DECL_ASSEMBLER_NAME, the C++ mangler may emit - diagnostics that use input_location to show locus - information. The problem here is that, at this point, - input_location is generally anchored to the end of the file - (since the parser is long gone), so we don't have a good - position to pin it to. - - To alleviate this problem, this uses the location of T's - declaration. Examples of this are - testsuite/g++.dg/template/cond2.C and - testsuite/g++.dg/template/pr35240.C. */ - location_t saved_location = input_location; - input_location = DECL_SOURCE_LOCATION (t); - - decl_assembler_name (t); - - input_location = saved_location; - } -} - - -/* Free language specific information for every operand and expression - in every node of the call graph. This process operates in three stages: - - 1- Every callgraph node and varpool node is traversed looking for - decls and types embedded in them. This is a more exhaustive - search than that done by find_referenced_vars, because it will - also collect individual fields, decls embedded in types, etc. - - 2- All the decls found are sent to free_lang_data_in_decl. - - 3- All the types found are sent to free_lang_data_in_type. - - The ordering between decls and types is important because - free_lang_data_in_decl sets assembler names, which includes - mangling. So types cannot be freed up until assembler names have - been set up. */ - -static void -free_lang_data_in_cgraph (class free_lang_data_d *fld) -{ - struct cgraph_node *n; - varpool_node *v; - tree t; - unsigned i; - alias_pair *p; - - /* Find decls and types in the body of every function in the callgraph. */ - FOR_EACH_FUNCTION (n) - find_decls_types_in_node (n, fld); - - FOR_EACH_VEC_SAFE_ELT (alias_pairs, i, p) - find_decls_types (p->decl, fld); - - /* Find decls and types in every varpool symbol. */ - FOR_EACH_VARIABLE (v) - find_decls_types_in_var (v, fld); - - /* Set the assembler name on every decl found. We need to do this - now because free_lang_data_in_decl will invalidate data needed - for mangling. This breaks mangling on interdependent decls. */ - FOR_EACH_VEC_ELT (fld->decls, i, t) - assign_assembler_name_if_needed (t); - - /* Traverse every decl found freeing its language data. */ - FOR_EACH_VEC_ELT (fld->decls, i, t) - free_lang_data_in_decl (t, fld); - - /* Traverse every type found freeing its language data. */ - FOR_EACH_VEC_ELT (fld->types, i, t) - free_lang_data_in_type (t, fld); -} - - -/* Free resources that are used by FE but are not needed once they are done. */ - -static unsigned -free_lang_data (void) -{ - unsigned i; - class free_lang_data_d fld; - - /* If we are the LTO frontend we have freed lang-specific data already. */ - if (in_lto_p - || (!flag_generate_lto && !flag_generate_offload)) - { - /* Rebuild type inheritance graph even when not doing LTO to get - consistent profile data. */ - rebuild_type_inheritance_graph (); - return 0; - } - - fld_incomplete_types = new hash_map; - fld_simplified_types = new hash_map; - - /* Provide a dummy TRANSLATION_UNIT_DECL if the FE failed to provide one. */ - if (vec_safe_is_empty (all_translation_units)) - build_translation_unit_decl (NULL_TREE); - - /* Allocate and assign alias sets to the standard integer types - while the slots are still in the way the frontends generated them. */ - for (i = 0; i < itk_none; ++i) - if (integer_types[i]) - TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]); - - /* Traverse the IL resetting language specific information for - operands, expressions, etc. */ - free_lang_data_in_cgraph (&fld); - - /* Create gimple variants for common types. */ - for (unsigned i = 0; - i < sizeof (builtin_structptr_types) / sizeof (builtin_structptr_type); - ++i) - builtin_structptr_types[i].node = builtin_structptr_types[i].base; - - /* Reset some langhooks. Do not reset types_compatible_p, it may - still be used indirectly via the get_alias_set langhook. */ - lang_hooks.dwarf_name = lhd_dwarf_name; - lang_hooks.decl_printable_name = gimple_decl_printable_name; - lang_hooks.gimplify_expr = lhd_gimplify_expr; - lang_hooks.overwrite_decl_assembler_name = lhd_overwrite_decl_assembler_name; - lang_hooks.print_xnode = lhd_print_tree_nothing; - lang_hooks.print_decl = lhd_print_tree_nothing; - lang_hooks.print_type = lhd_print_tree_nothing; - lang_hooks.print_identifier = lhd_print_tree_nothing; - - lang_hooks.tree_inlining.var_mod_type_p = hook_bool_tree_tree_false; - - if (flag_checking) - { - int i; - tree t; - - FOR_EACH_VEC_ELT (fld.types, i, t) - verify_type (t); - } - - /* We do not want the default decl_assembler_name implementation, - rather if we have fixed everything we want a wrapper around it - asserting that all non-local symbols already got their assembler - name and only produce assembler names for local symbols. Or rather - make sure we never call decl_assembler_name on local symbols and - devise a separate, middle-end private scheme for it. */ - - /* Reset diagnostic machinery. */ - tree_diagnostics_defaults (global_dc); - - rebuild_type_inheritance_graph (); - - delete fld_incomplete_types; - delete fld_simplified_types; - - return 0; -} - - -namespace { - -const pass_data pass_data_ipa_free_lang_data = -{ - SIMPLE_IPA_PASS, /* type */ - "*free_lang_data", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - TV_IPA_FREE_LANG_DATA, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_ipa_free_lang_data : public simple_ipa_opt_pass -{ -public: - pass_ipa_free_lang_data (gcc::context *ctxt) - : simple_ipa_opt_pass (pass_data_ipa_free_lang_data, ctxt) - {} - - /* opt_pass methods: */ - virtual unsigned int execute (function *) { return free_lang_data (); } - -}; // class pass_ipa_free_lang_data - -} // anon namespace - -simple_ipa_opt_pass * -make_pass_ipa_free_lang_data (gcc::context *ctxt) -{ - return new pass_ipa_free_lang_data (ctxt); -} - -/* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask - of the various TYPE_QUAL values. */ - -static void -set_type_quals (tree type, int type_quals) -{ - TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0; - TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0; - TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0; - TYPE_ATOMIC (type) = (type_quals & TYPE_QUAL_ATOMIC) != 0; - TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals); -} - -/* Returns true iff CAND and BASE have equivalent language-specific - qualifiers. */ - -bool -check_lang_type (const_tree cand, const_tree base) -{ - if (lang_hooks.types.type_hash_eq == NULL) - return true; - /* type_hash_eq currently only applies to these types. */ - if (TREE_CODE (cand) != FUNCTION_TYPE - && TREE_CODE (cand) != METHOD_TYPE) - return true; - return lang_hooks.types.type_hash_eq (cand, base); -} - -/* This function checks to see if TYPE matches the size one of the built-in - atomic types, and returns that core atomic type. */ - -static tree -find_atomic_core_type (const_tree type) -{ - tree base_atomic_type; - - /* Only handle complete types. */ - if (!tree_fits_uhwi_p (TYPE_SIZE (type))) - return NULL_TREE; - - switch (tree_to_uhwi (TYPE_SIZE (type))) - { - case 8: - base_atomic_type = atomicQI_type_node; - break; - - case 16: - base_atomic_type = atomicHI_type_node; - break; - - case 32: - base_atomic_type = atomicSI_type_node; - break; - - case 64: - base_atomic_type = atomicDI_type_node; - break; - - case 128: - base_atomic_type = atomicTI_type_node; - break; - - default: - base_atomic_type = NULL_TREE; - } - - return base_atomic_type; -} - -/* Returns true iff unqualified CAND and BASE are equivalent. */ - -bool -check_base_type (const_tree cand, const_tree base) -{ - if (TYPE_NAME (cand) != TYPE_NAME (base) - /* Apparently this is needed for Objective-C. */ - || TYPE_CONTEXT (cand) != TYPE_CONTEXT (base) - || !attribute_list_equal (TYPE_ATTRIBUTES (cand), - TYPE_ATTRIBUTES (base))) - return false; - /* Check alignment. */ - if (TYPE_ALIGN (cand) == TYPE_ALIGN (base) - && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base)) - return true; - /* Atomic types increase minimal alignment. We must to do so as well - or we get duplicated canonical types. See PR88686. */ - if ((TYPE_QUALS (cand) & TYPE_QUAL_ATOMIC)) - { - /* See if this object can map to a basic atomic type. */ - tree atomic_type = find_atomic_core_type (cand); - if (atomic_type && TYPE_ALIGN (atomic_type) == TYPE_ALIGN (cand)) - return true; - } - return false; -} - -/* Returns true iff CAND is equivalent to BASE with TYPE_QUALS. */ - -bool -check_qualified_type (const_tree cand, const_tree base, int type_quals) -{ - return (TYPE_QUALS (cand) == type_quals - && check_base_type (cand, base) - && check_lang_type (cand, base)); -} - -/* Returns true iff CAND is equivalent to BASE with ALIGN. */ - -static bool -check_aligned_type (const_tree cand, const_tree base, unsigned int align) +static bool +check_aligned_type (const_tree cand, const_tree base, unsigned int align) { return (TYPE_QUALS (cand) == TYPE_QUALS (base) && TYPE_NAME (cand) == TYPE_NAME (base) @@ -8263,7 +7119,7 @@ subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval) If SHARED is true, reuse such a type that has already been constructed. If SET_CANONICAL is true, compute TYPE_CANONICAL from the element type. */ -static tree +tree build_array_type_1 (tree elt_type, tree index_type, bool typeless_storage, bool shared, bool set_canonical) { -- cgit v1.1 From 6ba3079dce89d9b63bf5dbd5e320ea2bf96f196b Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 17 Mar 2021 16:36:44 +0100 Subject: Come up with startswith function. gcc/ada/ChangeLog: * gcc-interface/utils.c (def_builtin_1): Use startswith function instead of strncmp. gcc/analyzer/ChangeLog: * sm-file.cc (is_file_using_fn_p): Use startswith function instead of strncmp. gcc/ChangeLog: * builtins.c (is_builtin_name): Use startswith function instead of strncmp. * collect2.c (main): Likewise. (has_lto_section): Likewise. (scan_libraries): Likewise. * coverage.c (coverage_checksum_string): Likewise. (coverage_init): Likewise. * dwarf2out.c (is_cxx): Likewise. (gen_compile_unit_die): Likewise. * gcc-ar.c (main): Likewise. * gcc.c (init_spec): Likewise. (read_specs): Likewise. (execute): Likewise. (check_live_switch): Likewise. * genattrtab.c (write_attr_case): Likewise. (IS_ATTR_GROUP): Likewise. * gencfn-macros.c (main): Likewise. * gengtype.c (type_for_name): Likewise. (gen_rtx_next): Likewise. (get_file_langdir): Likewise. (write_local): Likewise. * genmatch.c (get_operator): Likewise. (get_operand_type): Likewise. (expr::gen_transform): Likewise. * genoutput.c (validate_optab_operands): Likewise. * incpath.c (add_sysroot_to_chain): Likewise. * langhooks.c (lang_GNU_C): Likewise. (lang_GNU_CXX): Likewise. (lang_GNU_Fortran): Likewise. (lang_GNU_OBJC): Likewise. * lto-wrapper.c (run_gcc): Likewise. * omp-general.c (omp_max_simt_vf): Likewise. * omp-low.c (omp_runtime_api_call): Likewise. * opts-common.c (parse_options_from_collect_gcc_options): Likewise. * read-rtl-function.c (function_reader::read_rtx_operand_r): Likewise. * real.c (real_from_string): Likewise. * selftest.c (assert_str_startswith): Likewise. * timevar.c (timer::validate_phases): Likewise. * tree.c (get_file_function_name): Likewise. * ubsan.c (ubsan_use_new_style_p): Likewise. * varasm.c (default_function_rodata_section): Likewise. (incorporeal_function_p): Likewise. (default_section_type_flags): Likewise. * system.h (startswith): Define startswith. gcc/c-family/ChangeLog: * c-ada-spec.c (print_destructor): Use startswith function instead of strncmp. (dump_ada_declaration): Likewise. * c-common.c (disable_builtin_function): Likewise. (def_builtin_1): Likewise. * c-format.c (check_tokens): Likewise. (check_plain): Likewise. (convert_format_name_to_system_name): Likewise. gcc/c/ChangeLog: * c-aux-info.c (affix_data_type): Use startswith function instead of strncmp. * c-typeck.c (build_function_call_vec): Likewise. * gimple-parser.c (c_parser_gimple_parse_bb_spec): Likewise. gcc/cp/ChangeLog: * decl.c (duplicate_decls): Use startswith function instead of strncmp. (cxx_builtin_function): Likewise. (omp_declare_variant_finalize_one): Likewise. (grokfndecl): Likewise. * error.c (dump_decl_name): Likewise. * mangle.c (find_decomp_unqualified_name): Likewise. (write_guarded_var_name): Likewise. (decl_tls_wrapper_p): Likewise. * parser.c (cp_parser_simple_type_specifier): Likewise. (cp_parser_tx_qualifier_opt): Likewise. * pt.c (template_parm_object_p): Likewise. (dguide_name_p): Likewise. gcc/d/ChangeLog: * d-builtins.cc (do_build_builtin_fn): Use startswith function instead of strncmp. * dmd/dinterpret.c (evaluateIfBuiltin): Likewise. * dmd/dmangle.c: Likewise. * dmd/hdrgen.c: Likewise. * dmd/identifier.c (Identifier::toHChars2): Likewise. gcc/fortran/ChangeLog: * decl.c (variable_decl): Use startswith function instead of strncmp. (gfc_match_end): Likewise. * gfortran.h (gfc_str_startswith): Likewise. * module.c (load_omp_udrs): Likewise. (read_module): Likewise. * options.c (gfc_handle_runtime_check_option): Likewise. * primary.c (match_arg_list_function): Likewise. * trans-decl.c (gfc_get_symbol_decl): Likewise. * trans-expr.c (gfc_conv_procedure_call): Likewise. * trans-intrinsic.c (gfc_conv_ieee_arithmetic_function): Likewise. gcc/go/ChangeLog: * gofrontend/runtime.cc (Runtime::name_to_code): Use startswith function instead of strncmp. gcc/objc/ChangeLog: * objc-act.c (objc_string_ref_type_p): Use startswith function instead of strncmp. * objc-encoding.c (encode_type): Likewise. * objc-next-runtime-abi-02.c (has_load_impl): Likewise. --- gcc/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index c5506a0..01eda55 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8583,7 +8583,7 @@ get_file_function_name (const char *type) We also assign sub_I and sub_D sufixes to constructors called from the global static constructors. These are always local. */ else if (((type[0] == 'I' || type[0] == 'D') && targetm.have_ctors_dtors) - || (strncmp (type, "sub_", 4) == 0 + || (startswith (type, "sub_") && (type[4] == 'I' || type[4] == 'D'))) { const char *file = main_input_filename; -- cgit v1.1 From e0a5daf81f2c79a0275eccd7c1a25349990a7a4d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 17 May 2021 13:56:14 +0200 Subject: middle-end/100582 - fix array_at_struct_end_p for vector indexing Vector indexing leaves us with ARRAY_REFs of VIEW_CONVERT_EXPRs, sth which array_at_struct_end_p considers a array-at-struct-end even when there's an underlying decl visible. The following fixes the latter. 2021-05-17 Richard Biener PR middle-end/100582 * tree.c (array_at_struct_end_p): Get to the base of the reference before looking for the underlying decl. * gcc.target/i386/pr100582.c: New testcase. --- gcc/tree.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 01eda55..8afba59 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -12550,13 +12550,11 @@ array_at_struct_end_p (tree ref) || ! TYPE_MAX_VALUE (TYPE_DOMAIN (atype))) return true; - if (TREE_CODE (ref) == MEM_REF - && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR) - ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); - /* If the reference is based on a declared entity, the size of the array is constrained by its given domain. (Do not trust commons PR/69368). */ - if (DECL_P (ref) + ref = get_base_address (ref); + if (ref + && DECL_P (ref) && !(flag_unconstrained_commons && VAR_P (ref) && DECL_COMMON (ref)) && DECL_SIZE_UNIT (ref) -- cgit v1.1 From 720dff974ea0487c35c0a4bfa527f30df5066ce1 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Tue, 27 Apr 2021 10:09:06 +0200 Subject: PR100281 C++: Fix SImode pointer handling The problem appears to be triggered by two locations in the front-end where non-POINTER_SIZE pointers aren't handled right now. 1. An assertion in strip_typedefs is triggered because the alignment of the types don't match. This in turn is caused by creating the new type with build_pointer_type instead of taking the type of the original pointer into account. 2. An assertion in cp_convert_to_pointer is triggered which expects the target type to always have POINTER_SIZE. gcc/cp/ChangeLog: PR c++/100281 * cvt.c (cp_convert_to_pointer): Use the size of the target pointer type. * tree.c (cp_build_reference_type): Call cp_build_reference_type_for_mode with VOIDmode. (cp_build_reference_type_for_mode): Rename from cp_build_reference_type. Add MODE argument and invoke build_reference_type_for_mode. (strip_typedefs): Use build_pointer_type_for_mode and cp_build_reference_type_for_mode for pointers and references. gcc/ChangeLog: PR c++/100281 * tree.c (build_reference_type_for_mode) (build_pointer_type_for_mode): Pick pointer mode if MODE argument is VOIDmode. (build_reference_type, build_pointer_type): Invoke build_*_type_for_mode with VOIDmode. gcc/testsuite/ChangeLog: PR c++/100281 * g++.target/s390/pr100281-1.C: New test. * g++.target/s390/pr100281-2.C: New test. --- gcc/tree.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 8afba59..31ac424 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6792,9 +6792,10 @@ operation_no_trapping_overflow (tree type, enum tree_code code) constructed by language-dependent code, not here.) */ /* Construct, lay out and return the type of pointers to TO_TYPE with - mode MODE. If CAN_ALIAS_ALL is TRUE, indicate this type can - reference all of memory. If such a type has already been - constructed, reuse it. */ + mode MODE. If MODE is VOIDmode, a pointer mode for the address + space of TO_TYPE will be picked. If CAN_ALIAS_ALL is TRUE, + indicate this type can reference all of memory. If such a type has + already been constructed, reuse it. */ tree build_pointer_type_for_mode (tree to_type, machine_mode mode, @@ -6806,6 +6807,12 @@ build_pointer_type_for_mode (tree to_type, machine_mode mode, if (to_type == error_mark_node) return error_mark_node; + if (mode == VOIDmode) + { + addr_space_t as = TYPE_ADDR_SPACE (to_type); + mode = targetm.addr_space.pointer_mode (as); + } + /* If the pointed-to type has the may_alias attribute set, force a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) @@ -6857,10 +6864,7 @@ build_pointer_type_for_mode (tree to_type, machine_mode mode, tree build_pointer_type (tree to_type) { - addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC - : TYPE_ADDR_SPACE (to_type); - machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); - return build_pointer_type_for_mode (to_type, pointer_mode, false); + return build_pointer_type_for_mode (to_type, VOIDmode, false); } /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE. */ @@ -6875,6 +6879,12 @@ build_reference_type_for_mode (tree to_type, machine_mode mode, if (to_type == error_mark_node) return error_mark_node; + if (mode == VOIDmode) + { + addr_space_t as = TYPE_ADDR_SPACE (to_type); + mode = targetm.addr_space.pointer_mode (as); + } + /* If the pointed-to type has the may_alias attribute set, force a TYPE_REF_CAN_ALIAS_ALL pointer to be generated. */ if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (to_type))) @@ -6926,10 +6936,7 @@ build_reference_type_for_mode (tree to_type, machine_mode mode, tree build_reference_type (tree to_type) { - addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC - : TYPE_ADDR_SPACE (to_type); - machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); - return build_reference_type_for_mode (to_type, pointer_mode, false); + return build_reference_type_for_mode (to_type, VOIDmode, false); } #define MAX_INT_CACHED_PREC \ -- cgit v1.1 From 2e6ad1ba532fe684633edac766c598be19ad3b59 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 19 May 2021 10:20:37 +0200 Subject: Enable more WITH_SIZE_EXPR processing This enables the alias machinery for WITH_SIZE_EXPR which can appear in call LHS and arguments. In particular this drops the NULL return from get_base_address and it adjusts get_ref_base_and_extent and friends to use the size information in WITH_SIZE_EXPR and look through it for further processing. 2021-05-19 Richard Biener * builtins.c (get_object_alignment_1): Strip outer WITH_SIZE_EXPR. * tree-dfa.c (get_ref_base_and_extent): Handle outer WITH_SIZE_EXPR for size processing and process the containing ref. * tree-ssa-alias.c (ao_ref_base_alias_set): Strip outer WITH_SIZE_EXPR. (ao_ref_base_alias_ptr_type): Likewise. (refs_may_alias_p_2): Allow WITH_SIZE_EXPR in ref->ref and handle that accordingly, stripping it for the core alias workers. * tree.c (get_base_address): Handle WITH_SIZE_EXPR by looking through it instead of returning NULL. --- gcc/tree.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 31ac424..bdb29b8 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -12382,6 +12382,8 @@ drop_tree_overflow (tree t) tree get_base_address (tree t) { + if (TREE_CODE (t) == WITH_SIZE_EXPR) + t = TREE_OPERAND (t, 0); while (handled_component_p (t)) t = TREE_OPERAND (t, 0); @@ -12390,11 +12392,6 @@ get_base_address (tree t) && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR) t = TREE_OPERAND (TREE_OPERAND (t, 0), 0); - /* ??? Either the alias oracle or all callers need to properly deal - with WITH_SIZE_EXPRs before we can look through those. */ - if (TREE_CODE (t) == WITH_SIZE_EXPR) - return NULL_TREE; - return t; } -- cgit v1.1 From 45f4e2b01b82c72b3a11ff4ad184d7edcf0e63d4 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 19 May 2021 18:44:08 +0200 Subject: Convert remaining passes to get_range_query. This patch converts the remaining users of get_range_info and get_ptr_nonnull to the get_range_query API. No effort was made to move passes away from VR_ANTI_RANGE, or any other use of deprecated methods. This was a straight up conversion to the new API, nothing else. gcc/ChangeLog: * builtins.c (check_nul_terminated_array): Convert to get_range_query. (expand_builtin_strnlen): Same. (determine_block_size): Same. * fold-const.c (expr_not_equal_to): Same. * gimple-fold.c (size_must_be_zero_p): Same. * gimple-match-head.c: Include gimple-range.h. * gimple-pretty-print.c (dump_ssaname_info): Convert to get_range_query. * gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): Same. * graphite-sese-to-poly.c (add_param_constraints): Same. * internal-fn.c (get_min_precision): Same. * ipa-fnsummary.c (set_switch_stmt_execution_predicate): Same. * ipa-prop.c (ipa_compute_jump_functions_for_edge): Same. * match.pd: Same. * tree-data-ref.c (split_constant_offset): Same. (dr_step_indicator): Same. * tree-dfa.c (get_ref_base_and_extent): Same. * tree-scalar-evolution.c (iv_can_overflow_p): Same. * tree-ssa-loop-niter.c (refine_value_range_using_guard): Same. (determine_value_range): Same. (record_nonwrapping_iv): Same. (infer_loop_bounds_from_signedness): Same. (scev_var_range_cant_overflow): Same. * tree-ssa-phiopt.c (two_value_replacement): Same. * tree-ssa-pre.c (insert_into_preds_of_block): Same. * tree-ssa-reassoc.c (optimize_range_tests_to_bit_test): Same. * tree-ssa-strlen.c (handle_builtin_stxncpy_strncat): Same. (get_range): Same. (dump_strlen_info): Same. (set_strlen_range): Same. (maybe_diag_stxncpy_trunc): Same. (get_len_or_size): Same. (handle_integral_assign): Same. * tree-ssa-structalias.c (find_what_p_points_to): Same. * tree-ssa-uninit.c (find_var_cmp_const): Same. * tree-switch-conversion.c (bit_test_cluster::emit): Same. * tree-vect-patterns.c (vect_get_range_info): Same. (vect_recog_divmod_pattern): Same. * tree-vrp.c (intersect_range_with_nonzero_bits): Same. (register_edge_assert_for_2): Same. (determine_value_range_1): Same. * tree.c (get_range_pos_neg): Same. * vr-values.c (vr_values::get_lattice_entry): Same. (vr_values::update_value_range): Same. (simplify_conversion_using_ranges): Same. --- gcc/tree.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index bdb29b8..9cafe43 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-vector-builder.h" #include "gimple-fold.h" #include "escaped_string.h" +#include "gimple-range.h" /* Tree code classes. */ @@ -13831,8 +13832,8 @@ get_range_pos_neg (tree arg) if (TREE_CODE (arg) != SSA_NAME) return 3; - wide_int arg_min, arg_max; - while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE) + value_range r; + while (!get_global_range_query ()->range_of_expr (r, arg) || r.kind () != VR_RANGE) { gimple *g = SSA_NAME_DEF_STMT (arg); if (is_gimple_assign (g) @@ -13858,16 +13859,16 @@ get_range_pos_neg (tree arg) { /* For unsigned values, the "positive" range comes below the "negative" range. */ - if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED)) + if (!wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED)) return 1; - if (wi::neg_p (wi::sext (arg_min, prec), SIGNED)) + if (wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED)) return 2; } else { - if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED)) + if (!wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED)) return 1; - if (wi::neg_p (wi::sext (arg_max, prec), SIGNED)) + if (wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED)) return 2; } return 3; -- cgit v1.1 From 9a5de4d5af1c10a8c097de30ee4c71457216e975 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Fri, 28 May 2021 10:01:19 +0200 Subject: OpenMP: Add iterator support to Fortran's depend; add affinity clause gcc/c-family/ChangeLog: * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_AFFINITY. gcc/c/ChangeLog: * c-parser.c (c_parser_omp_clause_affinity): New. (c_parser_omp_clause_name, c_parser_omp_variable_list, c_parser_omp_all_clauses, OMP_TASK_CLAUSE_MASK): Handle affinity clause. * c-typeck.c (handle_omp_array_sections_1, handle_omp_array_sections, c_finish_omp_clauses): Likewise. gcc/cp/ChangeLog: * parser.c (cp_parser_omp_clause_affinity): New. (cp_parser_omp_clause_name, cp_parser_omp_var_list_no_open, cp_parser_omp_all_clauses, OMP_TASK_CLAUSE_MASK): Handle affinity clause. * semantics.c (handle_omp_array_sections_1, handle_omp_array_sections, finish_omp_clauses): Likewise. gcc/fortran/ChangeLog: * dump-parse-tree.c (show_iterator): New. (show_omp_namelist): Handle iterators. (show_omp_clauses): Handle affinity. * gfortran.h (gfc_free_omp_namelist): New union with 'udr' and new 'ns'. * match.c (gfc_free_omp_namelist): Add are to choose union element. * openmp.c (gfc_free_omp_clauses, gfc_match_omp_detach, gfc_match_omp_clause_reduction, gfc_match_omp_flush): Update call to gfc_free_omp_namelist. (gfc_match_omp_variable_list): Likewise; permit preceeding whitespace. (enum omp_mask1): Add OMP_CLAUSE_AFFINITY. (gfc_match_iterator): New. (gfc_match_omp_clauses): Use it; update call to gfc_free_omp_namelist. (OMP_TASK_CLAUSES): Add OMP_CLAUSE_AFFINITY. (gfc_match_omp_taskwait): Match depend clause. (resolve_omp_clauses): Handle affinity; update for udr/union change. (gfc_resolve_omp_directive): Resolve clauses of taskwait. * st.c (gfc_free_statement): Update gfc_free_omp_namelist call. * trans-openmp.c (gfc_trans_omp_array_reduction_or_udr): Likewise (handle_iterator): New. (gfc_trans_omp_clauses): Handle iterators for depend/affinity clause. (gfc_trans_omp_taskwait): Handle depend clause. (gfc_trans_omp_directive): Update call. gcc/ChangeLog: * gimplify.c (gimplify_omp_affinity): New. (gimplify_scan_omp_clauses): Call it; remove affinity clause afterwards. * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_AFFINITY. * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_AFFINITY. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add clause. (walk_tree_1): Handle OMP_CLAUSE_AFFINITY. libgomp/ChangeLog: * testsuite/libgomp.fortran/depend-iterator-2.f90: New test. gcc/testsuite/ChangeLog: * c-c++-common/gomp/affinity-1.c: New test. * c-c++-common/gomp/affinity-2.c: New test. * c-c++-common/gomp/affinity-3.c: New test. * c-c++-common/gomp/affinity-4.c: New test. * c-c++-common/gomp/affinity-5.c: New test. * c-c++-common/gomp/affinity-6.c: New test. * c-c++-common/gomp/affinity-7.c: New test. * gfortran.dg/gomp/affinity-clause-1.f90: New test. * gfortran.dg/gomp/affinity-clause-2.f90: New test. * gfortran.dg/gomp/affinity-clause-3.f90: New test. * gfortran.dg/gomp/affinity-clause-4.f90: New test. * gfortran.dg/gomp/affinity-clause-5.f90: New test. * gfortran.dg/gomp/affinity-clause-6.f90: New test. * gfortran.dg/gomp/depend-iterator-1.f90: New test. * gfortran.dg/gomp/depend-iterator-2.f90: New test. * gfortran.dg/gomp/depend-iterator-3.f90: New test. * gfortran.dg/gomp/taskwait.f90: New test. --- gcc/tree.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 9cafe43..1aa6e55 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -289,6 +289,7 @@ unsigned const char omp_clause_num_ops[] = 1, /* OMP_CLAUSE_COPYIN */ 1, /* OMP_CLAUSE_COPYPRIVATE */ 3, /* OMP_CLAUSE_LINEAR */ + 1, /* OMP_CLAUSE_AFFINITY */ 2, /* OMP_CLAUSE_ALIGNED */ 2, /* OMP_CLAUSE_ALLOCATE */ 1, /* OMP_CLAUSE_DEPEND */ @@ -375,6 +376,7 @@ const char * const omp_clause_code_name[] = "copyin", "copyprivate", "linear", + "affinity", "aligned", "allocate", "depend", @@ -11091,6 +11093,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1)); /* FALLTHRU */ + case OMP_CLAUSE_AFFINITY: case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: case OMP_CLAUSE_WORKER: -- cgit v1.1 From 00dcc88a0ed7bd148ea86d900b6c93574a2e1f26 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 20 Jul 2021 11:14:19 -0600 Subject: Adjust by-value function vec arguments to by-reference. gcc/c-family/ChangeLog: * c-common.c (c_build_shufflevector): Adjust by-value argument to by-const-reference. * c-common.h (c_build_shufflevector): Same. gcc/c/ChangeLog: * c-tree.h (c_build_function_call_vec): Adjust by-value argument to by-const-reference. * c-typeck.c (c_build_function_call_vec): Same. gcc/ChangeLog: * cfgloop.h (single_likely_exit): Adjust by-value argument to by-const-reference. * cfgloopanal.c (single_likely_exit): Same. * cgraph.h (struct cgraph_node): Same. * cgraphclones.c (cgraph_node::create_virtual_clone): Same. * genautomata.c (merge_states): Same. * genextract.c (VEC_char_to_string): Same. * genmatch.c (dt_node::gen_kids_1): Same. (walk_captures): Adjust by-value argument to by-reference. * gimple-ssa-store-merging.c (check_no_overlap): Adjust by-value argument to by-const-reference. * gimple.c (gimple_build_call_vec): Same. (gimple_build_call_internal_vec): Same. (gimple_build_switch): Same. (sort_case_labels): Same. (preprocess_case_label_vec_for_gimple): Adjust by-value argument to by-reference. * gimple.h (gimple_build_call_vec): Adjust by-value argument to by-const-reference. (gimple_build_call_internal_vec): Same. (gimple_build_switch): Same. (sort_case_labels): Same. (preprocess_case_label_vec_for_gimple): Adjust by-value argument to by-reference. * haifa-sched.c (calc_priorities): Adjust by-value argument to by-const-reference. (sched_init_luids): Same. (haifa_init_h_i_d): Same. * ipa-cp.c (ipa_get_indirect_edge_target_1): Same. (adjust_callers_for_value_intersection): Adjust by-value argument to by-reference. (find_more_scalar_values_for_callers_subset): Adjust by-value argument to by-const-reference. (find_more_contexts_for_caller_subset): Same. (find_aggregate_values_for_callers_subset): Same. (copy_useful_known_contexts): Same. * ipa-fnsummary.c (remap_edge_summaries): Same. (remap_freqcounting_predicate): Same. * ipa-inline.c (add_new_edges_to_heap): Adjust by-value argument to by-reference. * ipa-predicate.c (predicate::remap_after_inlining): Adjust by-value argument to by-const-reference. * ipa-predicate.h (predicate::remap_after_inlining): Same. * ipa-prop.c (ipa_find_agg_cst_for_param): Same. * ipa-prop.h (ipa_find_agg_cst_for_param): Same. * ira-build.c (ira_loop_tree_body_rev_postorder): Same. * read-rtl.c (add_overload_instance): Same. * rtl.h (native_decode_rtx): Same. (native_decode_vector_rtx): Same. * sched-int.h (sched_init_luids): Same. (haifa_init_h_i_d): Same. * simplify-rtx.c (native_decode_vector_rtx): Same. (native_decode_rtx): Same. * tree-call-cdce.c (gen_shrink_wrap_conditions): Same. (shrink_wrap_one_built_in_call_with_conds): Same. (shrink_wrap_conditional_dead_built_in_calls): Same. * tree-data-ref.c (create_runtime_alias_checks): Same. (compute_all_dependences): Same. * tree-data-ref.h (compute_all_dependences): Same. (create_runtime_alias_checks): Same. (index_in_loop_nest): Same. * tree-if-conv.c (mask_exists): Same. * tree-loop-distribution.c (class loop_distribution): Same. (loop_distribution::create_rdg_vertices): Same. (dump_rdg_partitions): Same. (debug_rdg_partitions): Same. (partition_contains_all_rw): Same. (loop_distribution::distribute_loop): Same. * tree-parloops.c (oacc_entry_exit_ok_1): Same. (oacc_entry_exit_single_gang): Same. * tree-ssa-loop-im.c (hoist_memory_references): Same. (loop_suitable_for_sm): Same. * tree-ssa-loop-niter.c (bound_index): Same. * tree-ssa-reassoc.c (update_ops): Same. (swap_ops_for_binary_stmt): Same. (rewrite_expr_tree): Same. (rewrite_expr_tree_parallel): Same. * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): Same. * tree-ssa-sccvn.h (ao_ref_init_from_vn_reference): Same. * tree-ssa-structalias.c (process_all_all_constraints): Same. (make_constraints_to): Same. (handle_lhs_call): Same. (find_func_aliases_for_builtin_call): Same. (sort_fieldstack): Same. (check_for_overlaps): Same. * tree-vect-loop-manip.c (vect_create_cond_for_align_checks): Same. (vect_create_cond_for_unequal_addrs): Same. (vect_create_cond_for_lower_bounds): Same. (vect_create_cond_for_alias_checks): Same. * tree-vect-slp-patterns.c (vect_validate_multiplication): Same. * tree-vect-slp.c (vect_analyze_slp_instance): Same. (vect_make_slp_decision): Same. (vect_slp_bbs): Same. (duplicate_and_interleave): Same. (vect_transform_slp_perm_load): Same. (vect_schedule_slp): Same. * tree-vectorizer.h (vect_transform_slp_perm_load): Same. (vect_schedule_slp): Same. (duplicate_and_interleave): Same. * tree.c (build_vector_from_ctor): Same. (build_vector): Same. (check_vector_cst): Same. (check_vector_cst_duplicate): Same. (check_vector_cst_fill): Same. (check_vector_cst_stepped): Same. * tree.h (build_vector_from_ctor): Same. --- gcc/tree.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 1aa6e55..bead1ac 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2047,7 +2047,7 @@ make_vector (unsigned log2_npatterns, are extracted from V, a vector of CONSTRUCTOR_ELT. */ tree -build_vector_from_ctor (tree type, vec *v) +build_vector_from_ctor (tree type, const vec *v) { if (vec_safe_length (v) == 0) return build_zero_cst (type); @@ -14428,7 +14428,7 @@ test_labels () are given by VALS. */ static tree -build_vector (tree type, vec vals MEM_STAT_DECL) +build_vector (tree type, const vec &vals MEM_STAT_DECL) { gcc_assert (known_eq (vals.length (), TYPE_VECTOR_SUBPARTS (type))); tree_vector_builder builder (type, vals.length (), 1); @@ -14439,7 +14439,7 @@ build_vector (tree type, vec vals MEM_STAT_DECL) /* Check that VECTOR_CST ACTUAL contains the elements in EXPECTED. */ static void -check_vector_cst (vec expected, tree actual) +check_vector_cst (const vec &expected, tree actual) { ASSERT_KNOWN_EQ (expected.length (), TYPE_VECTOR_SUBPARTS (TREE_TYPE (actual))); @@ -14452,7 +14452,7 @@ check_vector_cst (vec expected, tree actual) and that its elements match EXPECTED. */ static void -check_vector_cst_duplicate (vec expected, tree actual, +check_vector_cst_duplicate (const vec &expected, tree actual, unsigned int npatterns) { ASSERT_EQ (npatterns, VECTOR_CST_NPATTERNS (actual)); @@ -14468,7 +14468,7 @@ check_vector_cst_duplicate (vec expected, tree actual, EXPECTED. */ static void -check_vector_cst_fill (vec expected, tree actual, +check_vector_cst_fill (const vec &expected, tree actual, unsigned int npatterns) { ASSERT_EQ (npatterns, VECTOR_CST_NPATTERNS (actual)); @@ -14483,7 +14483,7 @@ check_vector_cst_fill (vec expected, tree actual, and that its elements match EXPECTED. */ static void -check_vector_cst_stepped (vec expected, tree actual, +check_vector_cst_stepped (const vec &expected, tree actual, unsigned int npatterns) { ASSERT_EQ (npatterns, VECTOR_CST_NPATTERNS (actual)); -- cgit v1.1 From a61f6afbee370785cf091fe46e2e022748528307 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Wed, 21 Jul 2021 18:30:00 +0200 Subject: OpenACC 'nohost' clause Do not "compile a version of this procedure for the host". gcc/ * tree-core.h (omp_clause_code): Add 'OMP_CLAUSE_NOHOST'. * tree.c (omp_clause_num_ops, omp_clause_code_name, walk_tree_1): Handle it. * tree-pretty-print.c (dump_omp_clause): Likewise. * omp-general.c (oacc_verify_routine_clauses): Likewise. * gimplify.c (gimplify_scan_omp_clauses) (gimplify_adjust_omp_clauses): Likewise. * tree-nested.c (convert_nonlocal_omp_clauses) (convert_local_omp_clauses): Likewise. * omp-low.c (scan_sharing_clauses): Likewise. * omp-offload.c (execute_oacc_device_lower): Update. gcc/c-family/ * c-pragma.h (pragma_omp_clause): Add 'PRAGMA_OACC_CLAUSE_NOHOST'. gcc/c/ * c-parser.c (c_parser_omp_clause_name): Handle 'nohost'. (c_parser_oacc_all_clauses): Handle 'PRAGMA_OACC_CLAUSE_NOHOST'. (OACC_ROUTINE_CLAUSE_MASK): Add 'PRAGMA_OACC_CLAUSE_NOHOST'. * c-typeck.c (c_finish_omp_clauses): Handle 'OMP_CLAUSE_NOHOST'. gcc/cp/ * parser.c (cp_parser_omp_clause_name): Handle 'nohost'. (cp_parser_oacc_all_clauses): Handle 'PRAGMA_OACC_CLAUSE_NOHOST'. (OACC_ROUTINE_CLAUSE_MASK): Add 'PRAGMA_OACC_CLAUSE_NOHOST'. * pt.c (tsubst_omp_clauses): Handle 'OMP_CLAUSE_NOHOST'. * semantics.c (finish_omp_clauses): Likewise. gcc/fortran/ * dump-parse-tree.c (show_attr): Update. * gfortran.h (symbol_attribute): Add 'oacc_routine_nohost' member. (gfc_omp_clauses): Add 'nohost' member. * module.c (ab_attribute): Add 'AB_OACC_ROUTINE_NOHOST'. (attr_bits, mio_symbol_attribute): Update. * openmp.c (omp_mask2): Add 'OMP_CLAUSE_NOHOST'. (gfc_match_omp_clauses): Handle 'OMP_CLAUSE_NOHOST'. (OACC_ROUTINE_CLAUSES): Add 'OMP_CLAUSE_NOHOST'. (gfc_match_oacc_routine): Update. * trans-decl.c (add_attributes_to_decl): Update. * trans-openmp.c (gfc_trans_omp_clauses): Likewise. gcc/testsuite/ * c-c++-common/goacc/classify-routine-nohost.c: New file. * c-c++-common/goacc/classify-routine.c: Update. * c-c++-common/goacc/routine-2.c: Likewise. * c-c++-common/goacc/routine-nohost-1.c: New file. * c-c++-common/goacc/routine-nohost-2.c: Likewise. * g++.dg/goacc/template.C: Update. * gfortran.dg/goacc/classify-routine-nohost.f95: New file. * gfortran.dg/goacc/classify-routine.f95: Update. * gfortran.dg/goacc/pure-elemental-procedures-2.f90: Likewise. * gfortran.dg/goacc/routine-6.f90: Likewise. * gfortran.dg/goacc/routine-intrinsic-2.f: Likewise. * gfortran.dg/goacc/routine-module-1.f90: Likewise. * gfortran.dg/goacc/routine-module-2.f90: Likewise. * gfortran.dg/goacc/routine-module-3.f90: Likewise. * gfortran.dg/goacc/routine-module-mod-1.f90: Likewise. * gfortran.dg/goacc/routine-multiple-directives-1.f90: Likewise. * gfortran.dg/goacc/routine-multiple-directives-2.f90: Likewise. libgomp/ * testsuite/libgomp.oacc-c-c++-common/routine-nohost-1.c: New file. * testsuite/libgomp.oacc-c-c++-common/routine-nohost-2.c: Likewise. * testsuite/libgomp.oacc-c-c++-common/routine-nohost-2_2.c: Likewise. * testsuite/libgomp.oacc-fortran/routine-nohost-1.f90: Likewise. Co-Authored-By: Joseph Myers Co-Authored-By: Cesar Philippidis --- gcc/tree.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index bead1ac..c621f87 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -361,6 +361,7 @@ unsigned const char omp_clause_num_ops[] = 3, /* OMP_CLAUSE_TILE */ 0, /* OMP_CLAUSE_IF_PRESENT */ 0, /* OMP_CLAUSE_FINALIZE */ + 0, /* OMP_CLAUSE_NOHOST */ }; const char * const omp_clause_code_name[] = @@ -448,6 +449,7 @@ const char * const omp_clause_code_name[] = "tile", "if_present", "finalize", + "nohost", }; @@ -11165,6 +11167,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE__SIMT_: case OMP_CLAUSE_IF_PRESENT: case OMP_CLAUSE_FINALIZE: + case OMP_CLAUSE_NOHOST: WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); case OMP_CLAUSE_LASTPRIVATE: -- cgit v1.1 From 2a837de28ee94b4ec201059a9a7aaa852e6808da Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 28 Jul 2021 15:28:10 -0600 Subject: Add new gimple-ssa-warn-access pass. gcc/ChangeLog: * Makefile.in (OBJS): Add gimple-ssa-warn-access.o and pointer-query.o. * attribs.h (fndecl_dealloc_argno): Move fndecl_dealloc_argno to tree.h. * builtins.c (compute_objsize_r): Move to pointer-query.cc. (access_ref::access_ref): Same. (access_ref::phi): Same. (access_ref::get_ref): Same. (access_ref::size_remaining): Same. (access_ref::offset_in_range): Same. (access_ref::add_offset): Same. (access_ref::inform_access): Same. (ssa_name_limit_t::visit_phi): Same. (ssa_name_limit_t::leave_phi): Same. (ssa_name_limit_t::next): Same. (ssa_name_limit_t::next_phi): Same. (ssa_name_limit_t::~ssa_name_limit_t): Same. (pointer_query::pointer_query): Same. (pointer_query::get_ref): Same. (pointer_query::put_ref): Same. (pointer_query::flush_cache): Same. (warn_string_no_nul): Move to gimple-ssa-warn-access.cc. (check_nul_terminated_array): Same. (unterminated_array): Same. (maybe_warn_for_bound): Same. (check_read_access): Same. (warn_for_access): Same. (get_size_range): Same. (check_access): Same. (gimple_call_alloc_size): Move to tree.c. (gimple_parm_array_size): Move to pointer-query.cc. (get_offset_range): Same. (gimple_call_return_array): Same. (handle_min_max_size): Same. (handle_array_ref): Same. (handle_mem_ref): Same. (compute_objsize): Same. (gimple_call_alloc_p): Move to gimple-ssa-warn-access.cc. (call_dealloc_argno): Same. (fndecl_dealloc_argno): Same. (new_delete_mismatch_p): Same. (matching_alloc_calls_p): Same. (warn_dealloc_offset): Same. (maybe_emit_free_warning): Same. * builtins.h (check_nul_terminated_array): Move to gimple-ssa-warn-access.h. (check_nul_terminated_array): Same. (warn_string_no_nul): Same. (unterminated_array): Same. (class ssa_name_limit_t): Same. (class pointer_query): Same. (struct access_ref): Same. (class range_query): Same. (struct access_data): Same. (gimple_call_alloc_size): Same. (gimple_parm_array_size): Same. (compute_objsize): Same. (class access_data): Same. (maybe_emit_free_warning): Same. * calls.c (initialize_argument_information): Remove call to maybe_emit_free_warning. * gimple-array-bounds.cc: Include new header.. * gimple-fold.c: Same. * gimple-ssa-sprintf.c: Same. * gimple-ssa-warn-restrict.c: Same. * passes.def: Add pass_warn_access. * tree-pass.h (make_pass_warn_access): Declare. * tree-ssa-strlen.c: Include new headers. * tree.c (fndecl_dealloc_argno): Move here from builtins.c. * tree.h (fndecl_dealloc_argno): Move here from attribs.h. * gimple-ssa-warn-access.cc: New file. * gimple-ssa-warn-access.h: New file. * pointer-query.cc: New file. * pointer-query.h: New file. gcc/cp/ChangeLog: * init.c: Include new header. --- gcc/tree.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index c621f87..e923e67 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -14380,6 +14380,65 @@ valid_new_delete_pair_p (tree new_asm, tree delete_asm) return false; } +/* Return the zero-based number corresponding to the argument being + deallocated if FNDECL is a deallocation function or an out-of-bounds + value if it isn't. */ + +unsigned +fndecl_dealloc_argno (tree fndecl) +{ + /* A call to operator delete isn't recognized as one to a built-in. */ + if (DECL_IS_OPERATOR_DELETE_P (fndecl)) + { + if (DECL_IS_REPLACEABLE_OPERATOR (fndecl)) + return 0; + + /* Avoid placement delete that's not been inlined. */ + tree fname = DECL_ASSEMBLER_NAME (fndecl); + if (id_equal (fname, "_ZdlPvS_") // ordinary form + || id_equal (fname, "_ZdaPvS_")) // array form + return UINT_MAX; + return 0; + } + + /* TODO: Handle user-defined functions with attribute malloc? Handle + known non-built-ins like fopen? */ + if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)) + { + switch (DECL_FUNCTION_CODE (fndecl)) + { + case BUILT_IN_FREE: + case BUILT_IN_REALLOC: + return 0; + default: + break; + } + return UINT_MAX; + } + + tree attrs = DECL_ATTRIBUTES (fndecl); + if (!attrs) + return UINT_MAX; + + for (tree atfree = attrs; + (atfree = lookup_attribute ("*dealloc", atfree)); + atfree = TREE_CHAIN (atfree)) + { + tree alloc = TREE_VALUE (atfree); + if (!alloc) + continue; + + tree pos = TREE_CHAIN (alloc); + if (!pos) + return 0; + + pos = TREE_VALUE (pos); + return TREE_INT_CST_LOW (pos) - 1; + } + + return UINT_MAX; +} + #if CHECKING_P namespace selftest { -- cgit v1.1 From d0befed793b94f3f407be44e6f69f81a02f5f073 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 Aug 2021 22:41:17 +0200 Subject: openmp: Add support for OpenMP 5.1 masked construct This construct has been introduced as a replacement for master construct, but unlike that construct is slightly more general, has an optional clause which allows to choose which thread will be the one running the region, it can be some other thread than the master (primary) thread with number 0, or it could be no threads or multiple threads (then of course one needs to be careful about data races). It is way too early to deprecate the master construct though, we don't even have OpenMP 5.0 fully implemented, it has been deprecated in 5.1, will be also in 5.2 and removed in 6.0. But even then it will likely be a good idea to just -Wdeprecated warn about it and still accept it. The patch also contains something I should have done much earlier, for clauses that accept some integral expression where we only care about the value, forces during gimplification that value into either a min invariant (as before), SSA_NAME or a fresh temporary, but never e.g. a user VAR_DECL, so that for those clauses we don't need to worry about adjusting it. 2021-08-12 Jakub Jelinek gcc/ * tree.def (OMP_MASKED): New tree code. * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_FILTER. * tree.h (OMP_MASKED_BODY, OMP_MASKED_CLAUSES, OMP_MASKED_COMBINED, OMP_CLAUSE_FILTER_EXPR): Define. * tree.c (omp_clause_num_ops): Add OMP_CLAUSE_FILTER entry. (omp_clause_code_name): Likewise. (walk_tree_1): Handle OMP_CLAUSE_FILTER. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Handle OMP_CLAUSE_FILTER. (convert_nonlocal_reference_stmt, convert_local_reference_stmt, convert_gimple_call): Handle GIMPLE_OMP_MASTER. * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_FILTER. (dump_generic_node): Handle OMP_MASTER. * gimple.def (GIMPLE_OMP_MASKED): New gimple code. * gimple.c (gimple_build_omp_masked): New function. (gimple_copy): Handle GIMPLE_OMP_MASKED. * gimple.h (gimple_build_omp_masked): Declare. (gimple_has_substatements): Handle GIMPLE_OMP_MASKED. (gimple_omp_masked_clauses, gimple_omp_masked_clauses_ptr, gimple_omp_masked_set_clauses): New inline functions. (CASE_GIMPLE_OMP): Add GIMPLE_OMP_MASKED. * gimple-pretty-print.c (dump_gimple_omp_masked): New function. (pp_gimple_stmt_1): Handle GIMPLE_OMP_MASKED. * gimple-walk.c (walk_gimple_stmt): Likewise. * gimple-low.c (lower_stmt): Likewise. * gimplify.c (is_gimple_stmt): Handle OMP_MASTER. (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_FILTER. For clauses that take one expression rather than decl or constant, force gimplification of that into a SSA_NAME or temporary unless min invariant. (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_FILTER. (gimplify_expr): Handle OMP_MASKED. * tree-inline.c (remap_gimple_stmt): Handle GIMPLE_OMP_MASKED. (estimate_num_insns): Likewise. * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_FILTER. (check_omp_nesting_restrictions): Handle GIMPLE_OMP_MASKED. Adjust diagnostics for existence of masked construct. (scan_omp_1_stmt, lower_omp_master, lower_omp_1, diagnose_sb_1, diagnose_sb_2): Handle GIMPLE_OMP_MASKED. * omp-expand.c (expand_omp_synch, expand_omp, omp_make_gimple_edges): Likewise. gcc/c-family/ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_MASKED. (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_FILTER. * c-pragma.c (omp_pragmas_simd): Add masked construct. * c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_MASKED enumerator. (c_finish_omp_masked): Declare. * c-omp.c (c_finish_omp_masked): New function. (c_omp_split_clauses): Handle combined masked constructs. gcc/c/ * c-parser.c (c_parser_omp_clause_name): Parse filter clause name. (c_parser_omp_clause_filter): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER. (OMP_MASKED_CLAUSE_MASK): Define. (c_parser_omp_masked): New function. (c_parser_omp_parallel): Handle parallel masked. (c_parser_omp_construct): Handle PRAGMA_OMP_MASKED. * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_FILTER. gcc/cp/ * parser.c (cp_parser_omp_clause_name): Parse filter clause name. (cp_parser_omp_clause_filter): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_FILTER. (OMP_MASKED_CLAUSE_MASK): Define. (cp_parser_omp_masked): New function. (cp_parser_omp_parallel): Handle parallel masked. (cp_parser_omp_construct, cp_parser_pragma): Handle PRAGMA_OMP_MASKED. * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_FILTER. * pt.c (tsubst_omp_clauses): Likewise. (tsubst_expr): Handle OMP_MASKED. gcc/testsuite/ * c-c++-common/gomp/clauses-1.c (bar): Add tests for combined masked constructs with clauses. * c-c++-common/gomp/clauses-5.c (foo): Add testcase for filter clause. * c-c++-common/gomp/clause-dups-1.c (f1): Likewise. * c-c++-common/gomp/masked-1.c: New test. * c-c++-common/gomp/masked-2.c: New test. * c-c++-common/gomp/masked-combined-1.c: New test. * c-c++-common/gomp/masked-combined-2.c: New test. * c-c++-common/goacc/uninit-if-clause.c: Remove xfails. * g++.dg/gomp/block-11.C: New test. * g++.dg/gomp/tpl-masked-1.C: New test. * g++.dg/gomp/attrs-1.C (bar): Add tests for masked construct and combined masked constructs with clauses in attribute syntax. * g++.dg/gomp/attrs-2.C (bar): Likewise. * gcc.dg/gomp/nesting-1.c (f1, f2): Add tests for masked construct nesting. * gfortran.dg/goacc/host_data-tree.f95: Allow also SSA_NAMEs in if clause. * gfortran.dg/goacc/kernels-tree.f95: Likewise. libgomp/ * testsuite/libgomp.c-c++-common/masked-1.c: New test. --- gcc/tree.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index e923e67..a0ff794 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -350,6 +350,7 @@ unsigned const char omp_clause_num_ops[] = 0, /* OMP_CLAUSE_DEFAULTMAP */ 0, /* OMP_CLAUSE_ORDER */ 0, /* OMP_CLAUSE_BIND */ + 1, /* OMP_CLAUSE_FILTER */ 1, /* OMP_CLAUSE__SIMDUID_ */ 0, /* OMP_CLAUSE__SIMT_ */ 0, /* OMP_CLAUSE_INDEPENDENT */ @@ -438,6 +439,7 @@ const char * const omp_clause_code_name[] = "defaultmap", "order", "bind", + "filter", "_simduid_", "_simt_", "independent", @@ -11126,6 +11128,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE_GRAINSIZE: case OMP_CLAUSE_NUM_TASKS: case OMP_CLAUSE_HINT: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_TO_DECLARE: case OMP_CLAUSE_LINK: case OMP_CLAUSE_DETACH: -- cgit v1.1 From 96194a07bdbc57dd9733892a791d87dbe25f0802 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Sat, 14 Aug 2021 13:25:41 -0600 Subject: Diagnose mismatches between array and scalar new and delete [PR101791]. Resolves: PR middle-end/101791 - missing warning on a mismatch between scalar and array forms of new and delete gcc/ChangeLog: PR middle-end/101791 * gimple-ssa-warn-access.cc (new_delete_mismatch_p): Use new argument to valid_new_delete_pair_p. * tree.c (valid_new_delete_pair_p): Add argument. * tree.h (valid_new_delete_pair_p): Same. gcc/testsuite/ChangeLog: PR middle-end/101791 * g++.dg/warn/Wmismatched-new-delete-6.C: New test. * g++.dg/warn/Wmismatched-new-delete-7.C: New test. --- gcc/tree.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index a0ff794..6ec8a97 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -14314,17 +14314,28 @@ verify_type_context (location_t loc, type_context_kind context, || targetm.verify_type_context (loc, context, type, silent_p)); } -/* Return that NEW_ASM and DELETE_ASM name a valid pair of new and - delete operators. */ +/* Return true if NEW_ASM and DELETE_ASM name a valid pair of new and + delete operators. Return false if they may or may not name such + a pair and, when nonnull, set *PCERTAIN to true if they certainly + do not. */ bool -valid_new_delete_pair_p (tree new_asm, tree delete_asm) +valid_new_delete_pair_p (tree new_asm, tree delete_asm, + bool *pcertain /* = NULL */) { + bool certain; + if (!pcertain) + pcertain = &certain; + const char *new_name = IDENTIFIER_POINTER (new_asm); const char *delete_name = IDENTIFIER_POINTER (delete_asm); unsigned int new_len = IDENTIFIER_LENGTH (new_asm); unsigned int delete_len = IDENTIFIER_LENGTH (delete_asm); + /* The following failures are due to invalid names so they're not + considered certain mismatches. */ + *pcertain = false; + if (new_len < 5 || delete_len < 6) return false; if (new_name[0] == '_') @@ -14337,11 +14348,19 @@ valid_new_delete_pair_p (tree new_asm, tree delete_asm) ++delete_name, --delete_len; if (new_len < 4 || delete_len < 5) return false; + + /* The following failures are due to names of user-defined operators + so they're also not considered certain mismatches. */ + /* *_len is now just the length after initial underscores. */ if (new_name[0] != 'Z' || new_name[1] != 'n') return false; if (delete_name[0] != 'Z' || delete_name[1] != 'd') return false; + + /* The following failures are certain mismatches. */ + *pcertain = true; + /* _Znw must match _Zdl, _Zna must match _Zda. */ if ((new_name[2] != 'w' || delete_name[2] != 'l') && (new_name[2] != 'a' || delete_name[2] != 'a')) @@ -14380,6 +14399,9 @@ valid_new_delete_pair_p (tree new_asm, tree delete_asm) && !memcmp (delete_name + 5, "St11align_val_tRKSt9nothrow_t", 29)) return true; } + + /* The negative result is conservative. */ + *pcertain = false; return false; } -- cgit v1.1 From b48d4e6818674898f90d9358378c127511ef0f9f Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 17 Aug 2021 14:49:05 -0600 Subject: Move more warning code to gimple-ssa-warn-access etc. Also resolves: PR middle-end/101854 - Invalid warning -Wstringop-overflow wrong argument gcc/ChangeLog: PR middle-end/101854 * builtins.c (expand_builtin_alloca): Move warning code to check_alloca in gimple-ssa-warn-access.cc. * calls.c (alloc_max_size): Move code to check_alloca. (get_size_range): Move to pointer-query.cc. (maybe_warn_alloc_args_overflow): Move to gimple-ssa-warn-access.cc. (get_attr_nonstring_decl): Move to tree.c. (fntype_argno_type): Move to gimple-ssa-warn-access.cc. (append_attrname): Same. (maybe_warn_rdwr_sizes): Same. (initialize_argument_information): Move code to gimple-ssa-warn-access.cc. * calls.h (maybe_warn_alloc_args_overflow): Move to gimple-ssa-warn-access.h. (get_attr_nonstring_decl): Move to tree.h. (maybe_warn_nonstring_arg): Move to gimple-ssa-warn-access.h. (enum size_range_flags): Move to pointer-query.h. (get_size_range): Same. * gimple-ssa-warn-access.cc (has_location): Remove unused overload to avoid Clang -Wunused-function. (get_size_range): Declare static. (maybe_emit_free_warning): Rename... (maybe_check_dealloc_call): ...to this for consistency. (class pass_waccess): Add members. (pass_waccess::~pass_waccess): Defined. (alloc_max_size): Move here from calls.c. (maybe_warn_alloc_args_overflow): Same. (check_alloca): New function. (check_alloc_size_call): New function. (check_strncat): Handle another warning flag. (pass_waccess::check_builtin): Handle alloca. (fntype_argno_type): Move here from calls.c. (append_attrname): Same. (maybe_warn_rdwr_sizes): Same. (pass_waccess::check_call): Define. (check_nonstring_args): New function. (pass_waccess::check): Call new member functions. (pass_waccess::execute): Enable ranger. * gimple-ssa-warn-access.h (get_size_range): Move here from calls.h. (maybe_warn_nonstring_arg): Same. * gimple-ssa-warn-restrict.c: Remove #include. * pointer-query.cc (get_size_range): Move here from calls.c. * pointer-query.h (enum size_range_flags): Same. (get_size_range): Same. * tree.c (get_attr_nonstring_decl): Move here from calls.c. * tree.h (get_attr_nonstring_decl): Move here from calls.h. gcc/testsuite/ChangeLog: * gcc.dg/attr-alloc_size-5.c: Adjust optimization to -O1. * gcc.dg/attr-alloc_size-7.c: Use #pragmas to adjust optimization. * gcc.dg/attr-alloc_size-8.c: Adjust optimization to -O1. PR middle-end/101854 * gcc.dg/Wstringop-overflow-72.c: New test. --- gcc/tree.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 6ec8a97..cba3bca 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -14464,6 +14464,60 @@ fndecl_dealloc_argno (tree fndecl) return UINT_MAX; } +/* If EXPR refers to a character array or pointer declared attribute + nonstring, return a decl for that array or pointer and set *REF + to the referenced enclosing object or pointer. Otherwise return + null. */ + +tree +get_attr_nonstring_decl (tree expr, tree *ref) +{ + tree decl = expr; + tree var = NULL_TREE; + if (TREE_CODE (decl) == SSA_NAME) + { + gimple *def = SSA_NAME_DEF_STMT (decl); + + if (is_gimple_assign (def)) + { + tree_code code = gimple_assign_rhs_code (def); + if (code == ADDR_EXPR + || code == COMPONENT_REF + || code == VAR_DECL) + decl = gimple_assign_rhs1 (def); + } + else + var = SSA_NAME_VAR (decl); + } + + if (TREE_CODE (decl) == ADDR_EXPR) + decl = TREE_OPERAND (decl, 0); + + /* To simplify calling code, store the referenced DECL regardless of + the attribute determined below, but avoid storing the SSA_NAME_VAR + obtained above (it's not useful for dataflow purposes). */ + if (ref) + *ref = decl; + + /* Use the SSA_NAME_VAR that was determined above to see if it's + declared nonstring. Otherwise drill down into the referenced + DECL. */ + if (var) + decl = var; + else if (TREE_CODE (decl) == ARRAY_REF) + decl = TREE_OPERAND (decl, 0); + else if (TREE_CODE (decl) == COMPONENT_REF) + decl = TREE_OPERAND (decl, 1); + else if (TREE_CODE (decl) == MEM_REF) + return get_attr_nonstring_decl (TREE_OPERAND (decl, 0), ref); + + if (DECL_P (decl) + && lookup_attribute ("nonstring", DECL_ATTRIBUTES (decl))) + return decl; + + return NULL_TREE; +} + #if CHECKING_P namespace selftest { -- cgit v1.1 From 92dc5d844a2088db79bc4521be3ecb4e2f284444 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Fri, 27 Aug 2021 07:49:35 +0200 Subject: Fix 'OMP_CLAUSE_TILE' operands handling in 'gcc/tree.c:walk_tree_1' In r245300 (commit 02889d23ee3b02854dff203dd87b9a25e30b61b4) "OpenACC tile clause support" that one had changed to three operands, similar to 'OMP_CLAUSE_COLLAPSE'. There is no (existing) test case where this seems to matter (likewise for 'OMP_CLAUSE_COLLAPSE'), but it's good to be consistent. gcc/ * tree.c (walk_tree_1) : Handle three operands. --- gcc/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index cba3bca..4c7e03b 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -11166,7 +11166,6 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE_BIND: case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: - case OMP_CLAUSE_TILE: case OMP_CLAUSE__SIMT_: case OMP_CLAUSE_IF_PRESENT: case OMP_CLAUSE_FINALIZE: @@ -11179,6 +11178,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); case OMP_CLAUSE_COLLAPSE: + case OMP_CLAUSE_TILE: { int i; for (i = 0; i < 3; i++) -- cgit v1.1 From 8433baadec88e5f31fa141b6d78094e91256079d Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sun, 8 Nov 2020 09:04:07 +0000 Subject: C-family: Add attribute 'unavailable'. If an interface is marked 'deprecated' then, presumably, at some point it will be withdrawn and no longer available. The 'unavailable' attribute makes it possible to mark up interfaces to indicate this status. It is used quite extensively in some codebases where a single set of headers can be used to permit code generation for multiple system versions. From a configuration perspective, it also allows a compile test to determine that an interface is missing - rather than requiring a link test. The implementation follows the pattern of attribute deprecated, but produces an error (where deprecation produces a warning). This attribute has been implemented in clang for some years. Signed-off-by: Iain Sandoe gcc/c-family/ChangeLog: * c-attribs.c (handle_unavailable_attribute): New. gcc/c/ChangeLog: * c-decl.c (enum deprecated_states): Add unavailable state. (merge_decls): Copy unavailability. (quals_from_declspecs): Handle unavailable case. (start_decl): Amend the logic handling suppression of nested deprecation states to include unavailability. (smallest_type_quals_location): Amend comment. (grokdeclarator): Handle the unavailable deprecation state. (declspecs_add_type): Set TREE_UNAVAILABLE from the decl specs. * c-tree.h (struct c_declspecs): Add unavailable_p. * c-typeck.c (build_component_ref): Handle unavailability. (build_external_ref): Likewise. gcc/cp/ChangeLog: * call.c (build_over_call): Handle unavailable state in addition to deprecation. * class.c (type_build_ctor_call): Likewise. (type_build_dtor_call): Likewise. * cp-tree.h: Rename cp_warn_deprecated_use to cp_handle_deprecated_or_unavailable. * decl.c (duplicate_decls): Merge unavailability. (grokdeclarator): Handle unavailability in addition to deprecation. (type_is_unavailable): New. (grokparms): Handle unavailability in addition to deprecation. * decl.h (enum deprecated_states): Add UNAVAILABLE_DEPRECATED_SUPPRESS. * decl2.c (cplus_decl_attributes): Propagate unavailability to templates. (cp_warn_deprecated_use): Rename to ... (cp_handle_deprecated_or_unavailable): ... this and amend to handle the unavailable case. It remains a warning in the case of deprecation but becomes an error in the case of unavailability. (cp_warn_deprecated_use_scopes): Handle unavailability. (mark_used): Likewise. * parser.c (cp_parser_template_name): Likewise. (cp_parser_template_argument): Likewise. (cp_parser_parameter_declaration_list): Likewise. * typeck.c (build_class_member_access_expr): Likewise. (finish_class_member_access_expr): Likewise. * typeck2.c (build_functional_cast_1): Likewise. gcc/ChangeLog: * doc/extend.texi: Document unavailable attribute. * print-tree.c (print_node): Handle unavailable attribute. * tree-core.h (struct tree_base): Add a bit to carry unavailability. * tree.c (error_unavailable_use): New. * tree.h (TREE_UNAVAILABLE): New. (error_unavailable_use): New. gcc/objc/ChangeLog: * objc-act.c (objc_add_property_declaration): Register unavailable attribute. (maybe_make_artificial_property_decl): Set available. (objc_maybe_build_component_ref): Generalise to the method prototype to count availability. (objc_build_class_component_ref): Likewise. (build_private_template): Likewise. (objc_decl_method_attributes): Handle unavailable attribute. (lookup_method_in_hash_lists): Amend comments. (objc_finish_message_expr): Handle unavailability in addition to deprecation. (start_class): Likewise. (finish_class): Likewise. (lookup_protocol): Likewise. (objc_declare_protocol): Likewise. (start_protocol): Register unavailable attribute. (really_start_method): Likewise. (objc_gimplify_property_ref): Emit error on encountering an unavailable entity (and a warning for a deprecated one). gcc/testsuite/ChangeLog: * g++.dg/ext/attr-unavailable-1.C: New test. * g++.dg/ext/attr-unavailable-2.C: New test. * g++.dg/ext/attr-unavailable-3.C: New test. * g++.dg/ext/attr-unavailable-4.C: New test. * g++.dg/ext/attr-unavailable-5.C: New test. * g++.dg/ext/attr-unavailable-6.C: New test. * g++.dg/ext/attr-unavailable-7.C: New test. * g++.dg/ext/attr-unavailable-8.C: New test. * g++.dg/ext/attr-unavailable-9.C: New test. * gcc.dg/attr-unavailable-1.c: New test. * gcc.dg/attr-unavailable-2.c: New test. * gcc.dg/attr-unavailable-3.c: New test. * gcc.dg/attr-unavailable-4.c: New test. * gcc.dg/attr-unavailable-5.c: New test. * gcc.dg/attr-unavailable-6.c: New test. * obj-c++.dg/attributes/method-unavailable-1.mm: New test. * obj-c++.dg/attributes/method-unavailable-2.mm: New test. * obj-c++.dg/attributes/method-unavailable-3.mm: New test. * obj-c++.dg/property/at-property-unavailable-1.mm: New test. * obj-c++.dg/property/at-property-unavailable-2.mm: New test. * obj-c++.dg/property/dotsyntax-unavailable-1.mm: New test. * objc.dg/attributes/method-unavailable-1.m: New test. * objc.dg/attributes/method-unavailable-2.m: New test. * objc.dg/attributes/method-unavailable-3.m: New test. * objc.dg/property/at-property-unavailable-1.m: New test. * objc.dg/property/at-property-unavailable-2.m: New test. * objc.dg/property/dotsyntax-unavailable-1.m: New test. --- gcc/tree.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 4c7e03b..03a424a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -12154,6 +12154,78 @@ warn_deprecated_use (tree node, tree attr) return w; } +/* Error out with an identifier which was marked 'unavailable'. */ +void +error_unavailable_use (tree node, tree attr) +{ + escaped_string msg; + + if (node == 0) + return; + + if (!attr) + { + if (DECL_P (node)) + attr = DECL_ATTRIBUTES (node); + else if (TYPE_P (node)) + { + tree decl = TYPE_STUB_DECL (node); + if (decl) + attr = lookup_attribute ("unavailable", + TYPE_ATTRIBUTES (TREE_TYPE (decl))); + } + } + + if (attr) + attr = lookup_attribute ("unavailable", attr); + + if (attr) + msg.escape (TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)))); + + if (DECL_P (node)) + { + auto_diagnostic_group d; + if (msg) + error ("%qD is unavailable: %s", node, (const char *) msg); + else + error ("%qD is unavailable", node); + inform (DECL_SOURCE_LOCATION (node), "declared here"); + } + else if (TYPE_P (node)) + { + tree what = NULL_TREE; + tree decl = TYPE_STUB_DECL (node); + + if (TYPE_NAME (node)) + { + if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) + what = TYPE_NAME (node); + else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL + && DECL_NAME (TYPE_NAME (node))) + what = DECL_NAME (TYPE_NAME (node)); + } + + auto_diagnostic_group d; + if (what) + { + if (msg) + error ("%qE is unavailable: %s", what, (const char *) msg); + else + error ("%qE is unavailable", what); + } + else + { + if (msg) + error ("type is unavailable: %s", (const char *) msg); + else + error ("type is unavailable"); + } + + if (decl) + inform (DECL_SOURCE_LOCATION (decl), "declared here"); + } +} + /* Return true if REF has a COMPONENT_REF with a bit-field field declaration somewhere in it. */ -- cgit v1.1 From 424e46015762920b37e23670b7c518d9891348ed Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Fri, 27 Aug 2021 07:49:55 +0200 Subject: Simplify 'gcc/tree.c:walk_tree_1' handling of 'OMP_CLAUSE' No behavioral change, other than that for a few clauses, operands are now walked in a different order, and 'OMP_CLAUSE_ERROR' now no longer runs into 'default: gcc_unreachable ();' here (but instead will at some later stage). Follow-up for r110243 (commit aaf46ef9792bbc562175b606bd1c3f225ea56924) "Fix PR 25886. Convert OMP_CLAUSE_* into sub-codes". gcc/ * tree.c (walk_tree_1) : Simplify. --- gcc/tree.c | 134 ++++--------------------------------------------------------- 1 file changed, 8 insertions(+), 126 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 03a424a..a89d50a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -275,7 +275,7 @@ struct int_n_trees_t int_n_trees [NUM_INT_N_ENTS]; bool tree_contains_struct[MAX_TREE_CODES][64]; -/* Number of operands for each OpenMP clause. */ +/* Number of operands for each OMP clause. */ unsigned const char omp_clause_num_ops[] = { 0, /* OMP_CLAUSE_ERROR */ @@ -10289,7 +10289,7 @@ build_empty_stmt (location_t loc) } -/* Build an OpenMP clause with code CODE. LOC is the location of the +/* Build an OMP clause with code CODE. LOC is the location of the clause. */ tree @@ -11091,130 +11091,12 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, break; case OMP_CLAUSE: - switch (OMP_CLAUSE_CODE (*tp)) - { - case OMP_CLAUSE_GANG: - WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1)); - /* FALLTHRU */ - - case OMP_CLAUSE_AFFINITY: - case OMP_CLAUSE_ASYNC: - case OMP_CLAUSE_WAIT: - case OMP_CLAUSE_WORKER: - case OMP_CLAUSE_VECTOR: - case OMP_CLAUSE_NUM_GANGS: - case OMP_CLAUSE_NUM_WORKERS: - case OMP_CLAUSE_VECTOR_LENGTH: - case OMP_CLAUSE_PRIVATE: - case OMP_CLAUSE_SHARED: - case OMP_CLAUSE_FIRSTPRIVATE: - case OMP_CLAUSE_COPYIN: - case OMP_CLAUSE_COPYPRIVATE: - case OMP_CLAUSE_FINAL: - case OMP_CLAUSE_IF: - case OMP_CLAUSE_NUM_THREADS: - case OMP_CLAUSE_SCHEDULE: - case OMP_CLAUSE_UNIFORM: - case OMP_CLAUSE_DEPEND: - case OMP_CLAUSE_NONTEMPORAL: - case OMP_CLAUSE_NUM_TEAMS: - case OMP_CLAUSE_THREAD_LIMIT: - case OMP_CLAUSE_DEVICE: - case OMP_CLAUSE_DIST_SCHEDULE: - case OMP_CLAUSE_SAFELEN: - case OMP_CLAUSE_SIMDLEN: - case OMP_CLAUSE_ORDERED: - case OMP_CLAUSE_PRIORITY: - case OMP_CLAUSE_GRAINSIZE: - case OMP_CLAUSE_NUM_TASKS: - case OMP_CLAUSE_HINT: - case OMP_CLAUSE_FILTER: - case OMP_CLAUSE_TO_DECLARE: - case OMP_CLAUSE_LINK: - case OMP_CLAUSE_DETACH: - case OMP_CLAUSE_USE_DEVICE_PTR: - case OMP_CLAUSE_USE_DEVICE_ADDR: - case OMP_CLAUSE_IS_DEVICE_PTR: - case OMP_CLAUSE_INCLUSIVE: - case OMP_CLAUSE_EXCLUSIVE: - case OMP_CLAUSE__LOOPTEMP_: - case OMP_CLAUSE__REDUCTEMP_: - case OMP_CLAUSE__CONDTEMP_: - case OMP_CLAUSE__SCANTEMP_: - case OMP_CLAUSE__SIMDUID_: - WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0)); - /* FALLTHRU */ - - case OMP_CLAUSE_INDEPENDENT: - case OMP_CLAUSE_NOWAIT: - case OMP_CLAUSE_DEFAULT: - case OMP_CLAUSE_UNTIED: - case OMP_CLAUSE_MERGEABLE: - case OMP_CLAUSE_PROC_BIND: - case OMP_CLAUSE_DEVICE_TYPE: - case OMP_CLAUSE_INBRANCH: - case OMP_CLAUSE_NOTINBRANCH: - case OMP_CLAUSE_FOR: - case OMP_CLAUSE_PARALLEL: - case OMP_CLAUSE_SECTIONS: - case OMP_CLAUSE_TASKGROUP: - case OMP_CLAUSE_NOGROUP: - case OMP_CLAUSE_THREADS: - case OMP_CLAUSE_SIMD: - case OMP_CLAUSE_DEFAULTMAP: - case OMP_CLAUSE_ORDER: - case OMP_CLAUSE_BIND: - case OMP_CLAUSE_AUTO: - case OMP_CLAUSE_SEQ: - case OMP_CLAUSE__SIMT_: - case OMP_CLAUSE_IF_PRESENT: - case OMP_CLAUSE_FINALIZE: - case OMP_CLAUSE_NOHOST: - WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); - - case OMP_CLAUSE_LASTPRIVATE: - WALK_SUBTREE (OMP_CLAUSE_DECL (*tp)); - WALK_SUBTREE (OMP_CLAUSE_LASTPRIVATE_STMT (*tp)); - WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); - - case OMP_CLAUSE_COLLAPSE: - case OMP_CLAUSE_TILE: - { - int i; - for (i = 0; i < 3; i++) - WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i)); - WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); - } - - case OMP_CLAUSE_LINEAR: - WALK_SUBTREE (OMP_CLAUSE_DECL (*tp)); - WALK_SUBTREE (OMP_CLAUSE_LINEAR_STEP (*tp)); - WALK_SUBTREE (OMP_CLAUSE_LINEAR_STMT (*tp)); - WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); - - case OMP_CLAUSE_ALIGNED: - case OMP_CLAUSE_ALLOCATE: - case OMP_CLAUSE_FROM: - case OMP_CLAUSE_TO: - case OMP_CLAUSE_MAP: - case OMP_CLAUSE__CACHE_: - WALK_SUBTREE (OMP_CLAUSE_DECL (*tp)); - WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1)); - WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); - - case OMP_CLAUSE_REDUCTION: - case OMP_CLAUSE_TASK_REDUCTION: - case OMP_CLAUSE_IN_REDUCTION: - { - int i; - for (i = 0; i < 5; i++) - WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i)); - WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); - } - - default: - gcc_unreachable (); - } + { + int len = omp_clause_num_ops[OMP_CLAUSE_CODE (*tp)]; + for (int i = 0; i < len; i++) + WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i)); + WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp)); + } break; case TARGET_EXPR: -- cgit v1.1 From f19a327077ecc34a51487761378b9edb43c82997 Mon Sep 17 00:00:00 2001 From: liuhongt Date: Mon, 2 Aug 2021 10:56:45 +0800 Subject: Support -fexcess-precision=16 which will enable FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 when backend supports _Float16. gcc/ada/ChangeLog: * gcc-interface/misc.c (gnat_post_options): Issue an error for -fexcess-precision=16. gcc/c-family/ChangeLog: * c-common.c (excess_precision_mode_join): Update below comments. (c_ts18661_flt_eval_method): Set excess_precision_type to EXCESS_PRECISION_TYPE_FLOAT16 when -fexcess-precision=16. * c-cppbuiltin.c (cpp_atomic_builtins): Update below comments. (c_cpp_flt_eval_method_iec_559): Set excess_precision_type to EXCESS_PRECISION_TYPE_FLOAT16 when -fexcess-precision=16. gcc/ChangeLog: * common.opt: Support -fexcess-precision=16. * config/aarch64/aarch64.c (aarch64_excess_precision): Return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16 when EXCESS_PRECISION_TYPE_FLOAT16. * config/arm/arm.c (arm_excess_precision): Ditto. * config/i386/i386.c (ix86_get_excess_precision): Ditto. * config/m68k/m68k.c (m68k_excess_precision): Issue an error when EXCESS_PRECISION_TYPE_FLOAT16. * config/s390/s390.c (s390_excess_precision): Ditto. * coretypes.h (enum excess_precision_type): Add EXCESS_PRECISION_TYPE_FLOAT16. * doc/tm.texi (TARGET_C_EXCESS_PRECISION): Update documents. * doc/tm.texi.in (TARGET_C_EXCESS_PRECISION): Ditto. * doc/extend.texi (Half-Precision): Document -fexcess-precision=16. * flag-types.h (enum excess_precision): Add EXCESS_PRECISION_FLOAT16. * target.def (excess_precision): Update document. * tree.c (excess_precision_type): Set excess_precision_type to EXCESS_PRECISION_FLOAT16 when -fexcess-precision=16. gcc/fortran/ChangeLog: * options.c (gfc_post_options): Issue an error for -fexcess-precision=16. gcc/testsuite/ChangeLog: * gcc.target/i386/float16-6.c: New test. * gcc.target/i386/float16-7.c: New test. --- gcc/tree.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index a89d50a..486cdb0 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -7637,7 +7637,8 @@ excess_precision_type (tree type) enum excess_precision_type requested_type = (flag_excess_precision == EXCESS_PRECISION_FAST ? EXCESS_PRECISION_TYPE_FAST - : EXCESS_PRECISION_TYPE_STANDARD); + : (flag_excess_precision == EXCESS_PRECISION_FLOAT16 + ? EXCESS_PRECISION_TYPE_FLOAT16 :EXCESS_PRECISION_TYPE_STANDARD)); enum flt_eval_method target_flt_eval_method = targetm.c.excess_precision (requested_type); -- cgit v1.1 From a25e0b5e6ac8a77a71c229e0a7b744603365b0e9 Mon Sep 17 00:00:00 2001 From: qing zhao Date: Thu, 9 Sep 2021 15:44:49 -0700 Subject: Add -ftrivial-auto-var-init option and uninitialized variable attribute. Initialize automatic variables with either a pattern or with zeroes to increase the security and predictability of a program by preventing uninitialized memory disclosure and use. GCC still considers an automatic variable that doesn't have an explicit initializer as uninitialized, -Wuninitialized will still report warning messages on such automatic variables. With this option, GCC will also initialize any padding of automatic variables that have structure or union types to zeroes. You can control this behavior for a specific variable by using the variable attribute "uninitialized" to control runtime overhead. gcc/ChangeLog: 2021-09-09 qing zhao * builtins.c (expand_builtin_memset): Make external visible. * builtins.h (expand_builtin_memset): Declare extern. * common.opt (ftrivial-auto-var-init=): New option. * doc/extend.texi: Document the uninitialized attribute. * doc/invoke.texi: Document -ftrivial-auto-var-init. * flag-types.h (enum auto_init_type): New enumerated type auto_init_type. * gimple-fold.c (clear_padding_type): Add one new parameter. (clear_padding_union): Likewise. (clear_padding_emit_loop): Likewise. (clear_type_padding_in_mask): Likewise. (gimple_fold_builtin_clear_padding): Handle this new parameter. * gimplify.c (gimple_add_init_for_auto_var): New function. (gimple_add_padding_init_for_auto_var): New function. (is_var_need_auto_init): New function. (gimplify_decl_expr): Add initialization to automatic variables per users' requests. (gimplify_call_expr): Add one new parameter for call to __builtin_clear_padding. (gimplify_init_constructor): Add padding initialization in the end. * internal-fn.c (INIT_PATTERN_VALUE): New macro. (expand_DEFERRED_INIT): New function. * internal-fn.def (DEFERRED_INIT): New internal function. * tree-cfg.c (verify_gimple_call): Verify calls to .DEFERRED_INIT. * tree-sra.c (generate_subtree_deferred_init): New function. (scan_function): Avoid setting cannot_scalarize_away_bitmap for calls to .DEFERRED_INIT. (sra_modify_deferred_init): New function. (sra_modify_function_body): Handle calls to DEFERRED_INIT specially. * tree-ssa-structalias.c (find_func_aliases_for_call): Likewise. * tree-ssa-uninit.c (warn_uninit): Handle calls to DEFERRED_INIT specially. (check_defs): Likewise. (warn_uninitialized_vars): Likewise. * tree-ssa.c (ssa_undefined_value_p): Likewise. * tree.c (build_common_builtin_nodes): Build tree node for BUILT_IN_CLEAR_PADDING when needed. gcc/c-family/ChangeLog: 2021-09-09 qing zhao * c-attribs.c (handle_uninitialized_attribute): New function. (c_common_attribute_table): Add "uninitialized" attribute. gcc/testsuite/ChangeLog: 2021-09-09 qing zhao * c-c++-common/auto-init-1.c: New test. * c-c++-common/auto-init-10.c: New test. * c-c++-common/auto-init-11.c: New test. * c-c++-common/auto-init-12.c: New test. * c-c++-common/auto-init-13.c: New test. * c-c++-common/auto-init-14.c: New test. * c-c++-common/auto-init-15.c: New test. * c-c++-common/auto-init-16.c: New test. * c-c++-common/auto-init-2.c: New test. * c-c++-common/auto-init-3.c: New test. * c-c++-common/auto-init-4.c: New test. * c-c++-common/auto-init-5.c: New test. * c-c++-common/auto-init-6.c: New test. * c-c++-common/auto-init-7.c: New test. * c-c++-common/auto-init-8.c: New test. * c-c++-common/auto-init-9.c: New test. * c-c++-common/auto-init-esra.c: New test. * c-c++-common/auto-init-padding-1.c: New test. * c-c++-common/auto-init-padding-2.c: New test. * c-c++-common/auto-init-padding-3.c: New test. * g++.dg/auto-init-uninit-pred-1_a.C: New test. * g++.dg/auto-init-uninit-pred-2_a.C: New test. * g++.dg/auto-init-uninit-pred-3_a.C: New test. * g++.dg/auto-init-uninit-pred-4.C: New test. * gcc.dg/auto-init-sra-1.c: New test. * gcc.dg/auto-init-sra-2.c: New test. * gcc.dg/auto-init-uninit-1.c: New test. * gcc.dg/auto-init-uninit-12.c: New test. * gcc.dg/auto-init-uninit-13.c: New test. * gcc.dg/auto-init-uninit-14.c: New test. * gcc.dg/auto-init-uninit-15.c: New test. * gcc.dg/auto-init-uninit-16.c: New test. * gcc.dg/auto-init-uninit-17.c: New test. * gcc.dg/auto-init-uninit-18.c: New test. * gcc.dg/auto-init-uninit-19.c: New test. * gcc.dg/auto-init-uninit-2.c: New test. * gcc.dg/auto-init-uninit-20.c: New test. * gcc.dg/auto-init-uninit-21.c: New test. * gcc.dg/auto-init-uninit-22.c: New test. * gcc.dg/auto-init-uninit-23.c: New test. * gcc.dg/auto-init-uninit-24.c: New test. * gcc.dg/auto-init-uninit-25.c: New test. * gcc.dg/auto-init-uninit-26.c: New test. * gcc.dg/auto-init-uninit-3.c: New test. * gcc.dg/auto-init-uninit-34.c: New test. * gcc.dg/auto-init-uninit-36.c: New test. * gcc.dg/auto-init-uninit-37.c: New test. * gcc.dg/auto-init-uninit-4.c: New test. * gcc.dg/auto-init-uninit-5.c: New test. * gcc.dg/auto-init-uninit-6.c: New test. * gcc.dg/auto-init-uninit-8.c: New test. * gcc.dg/auto-init-uninit-9.c: New test. * gcc.dg/auto-init-uninit-A.c: New test. * gcc.dg/auto-init-uninit-B.c: New test. * gcc.dg/auto-init-uninit-C.c: New test. * gcc.dg/auto-init-uninit-H.c: New test. * gcc.dg/auto-init-uninit-I.c: New test. * gcc.target/aarch64/auto-init-1.c: New test. * gcc.target/aarch64/auto-init-2.c: New test. * gcc.target/aarch64/auto-init-3.c: New test. * gcc.target/aarch64/auto-init-4.c: New test. * gcc.target/aarch64/auto-init-5.c: New test. * gcc.target/aarch64/auto-init-6.c: New test. * gcc.target/aarch64/auto-init-7.c: New test. * gcc.target/aarch64/auto-init-8.c: New test. * gcc.target/aarch64/auto-init-padding-1.c: New test. * gcc.target/aarch64/auto-init-padding-10.c: New test. * gcc.target/aarch64/auto-init-padding-11.c: New test. * gcc.target/aarch64/auto-init-padding-12.c: New test. * gcc.target/aarch64/auto-init-padding-2.c: New test. * gcc.target/aarch64/auto-init-padding-3.c: New test. * gcc.target/aarch64/auto-init-padding-4.c: New test. * gcc.target/aarch64/auto-init-padding-5.c: New test. * gcc.target/aarch64/auto-init-padding-6.c: New test. * gcc.target/aarch64/auto-init-padding-7.c: New test. * gcc.target/aarch64/auto-init-padding-8.c: New test. * gcc.target/aarch64/auto-init-padding-9.c: New test. * gcc.target/i386/auto-init-1.c: New test. * gcc.target/i386/auto-init-2.c: New test. * gcc.target/i386/auto-init-21.c: New test. * gcc.target/i386/auto-init-22.c: New test. * gcc.target/i386/auto-init-23.c: New test. * gcc.target/i386/auto-init-24.c: New test. * gcc.target/i386/auto-init-3.c: New test. * gcc.target/i386/auto-init-4.c: New test. * gcc.target/i386/auto-init-5.c: New test. * gcc.target/i386/auto-init-6.c: New test. * gcc.target/i386/auto-init-7.c: New test. * gcc.target/i386/auto-init-8.c: New test. * gcc.target/i386/auto-init-padding-1.c: New test. * gcc.target/i386/auto-init-padding-10.c: New test. * gcc.target/i386/auto-init-padding-11.c: New test. * gcc.target/i386/auto-init-padding-12.c: New test. * gcc.target/i386/auto-init-padding-2.c: New test. * gcc.target/i386/auto-init-padding-3.c: New test. * gcc.target/i386/auto-init-padding-4.c: New test. * gcc.target/i386/auto-init-padding-5.c: New test. * gcc.target/i386/auto-init-padding-6.c: New test. * gcc.target/i386/auto-init-padding-7.c: New test. * gcc.target/i386/auto-init-padding-8.c: New test. * gcc.target/i386/auto-init-padding-9.c: New test. --- gcc/tree.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 486cdb0..3d15948 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9511,6 +9511,19 @@ build_common_builtin_nodes (void) tree tmp, ftype; int ecf_flags; + if (!builtin_decl_explicit_p (BUILT_IN_CLEAR_PADDING)) + { + ftype = build_function_type_list (void_type_node, + ptr_type_node, + ptr_type_node, + integer_type_node, + NULL_TREE); + local_define_builtin ("__builtin_clear_padding", ftype, + BUILT_IN_CLEAR_PADDING, + "__builtin_clear_padding", + ECF_LEAF | ECF_NOTHROW); + } + if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE) || !builtin_decl_explicit_p (BUILT_IN_ABORT)) { -- cgit v1.1