From: Richard Sandiford Date: Tue, 13 Aug 2019 21:35:10 +0000 (+0000) Subject: Protect some checks of DECL_FUNCTION_CODE X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cb1180d547e3b28547134a06ee020163afa59cc3;p=gcc.git Protect some checks of DECL_FUNCTION_CODE This patch protects various uses of DECL_FUNCTION_CODE that didn't obviously check for BUILT_IN_NORMAL first (either directly or in callers). They could therefore trigger for functions that either aren't built-ins or are a different kind of built-in. Also, the patch removes a redundant GIMPLE_CALL check from optimize_stdarg_builtin, since it gave the impression that the stmt was less well checked than it actually is. 2019-08-13 Richard Sandiford gcc/ PR middle-end/91421 * attribs.c (decl_attributes): Check the DECL_BUILT_IN_CLASS before the DECL_FUNCTION_CODE. * calls.c (maybe_warn_alloc_args_overflow): Use fndecl_built_in_p to check for a BUILT_IN_ALLOCA call. * ipa-cp.c (ipa_get_indirect_edge_target_1): Likewise for BUILT_IN_UNREACHABLE. Don't check for a FUNCTION_TYPE. * ipa-devirt.c (possible_polymorphic_call_target_p): Likewise. * ipa-prop.c (try_make_edge_direct_virtual_call): Likewise. * gimple-ssa-isolate-paths.c (is_addr_local): Check specifically for BUILT_IN_NORMAL functions. * trans-mem.c (expand_block_edges): Use gimple_call_builtin_p to test for BUILT_IN_TM_ABORT. * tree-ssa-ccp.c (optimize_stack_restore): Use fndecl_built_in_p to check for a BUILT_IN_STACK_RESTORE call. (optimize_stdarg_builtin): Remove redundant check for GIMPLE_CALL. * tree-ssa-threadedge.c (record_temporary_equivalences_from_stmts_at_dest): Check for a BUILT_IN_NORMAL decl before checking its DECL_FUNCTION_CODE. * tree-vect-patterns.c (vect_recog_pow_pattern): Use a positive test for a BUILT_IN_NORMAL call instead of a negative test for an internal function call. gcc/c/ PR middle-end/91421 * c-decl.c (header_for_builtin_fn): Take a FUNCTION_DECL instead of a built_in_function. (diagnose_mismatched_decls, implicitly_declare): Update accordingly. From-SVN: r274403 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 307f5360ea0..272d0841284 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2019-08-13 Richard Sandiford + + PR middle-end/91421 + * attribs.c (decl_attributes): Check the DECL_BUILT_IN_CLASS + before the DECL_FUNCTION_CODE. + * calls.c (maybe_warn_alloc_args_overflow): Use fndecl_built_in_p + to check for a BUILT_IN_ALLOCA call. + * ipa-cp.c (ipa_get_indirect_edge_target_1): Likewise for + BUILT_IN_UNREACHABLE. Don't check for a FUNCTION_TYPE. + * ipa-devirt.c (possible_polymorphic_call_target_p): Likewise. + * ipa-prop.c (try_make_edge_direct_virtual_call): Likewise. + * gimple-ssa-isolate-paths.c (is_addr_local): Check specifically + for BUILT_IN_NORMAL functions. + * trans-mem.c (expand_block_edges): Use gimple_call_builtin_p to + test for BUILT_IN_TM_ABORT. + * tree-ssa-ccp.c (optimize_stack_restore): Use fndecl_built_in_p + to check for a BUILT_IN_STACK_RESTORE call. + (optimize_stdarg_builtin): Remove redundant check for GIMPLE_CALL. + * tree-ssa-threadedge.c + (record_temporary_equivalences_from_stmts_at_dest): Check for a + BUILT_IN_NORMAL decl before checking its DECL_FUNCTION_CODE. + * tree-vect-patterns.c (vect_recog_pow_pattern): Use a positive + test for a BUILT_IN_NORMAL call instead of a negative test for + an internal function call. + 2019-08-13 Richard Sandiford * tree.h (build_vector_a_then_b): Declare. diff --git a/gcc/attribs.c b/gcc/attribs.c index f4777c6a823..b89be5834de 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -691,6 +691,7 @@ decl_attributes (tree *node, tree attributes, int flags, if (!built_in || !DECL_P (*anode) + || DECL_BUILT_IN_CLASS (*anode) != BUILT_IN_NORMAL || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE && (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE))) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 335801b3697..ada2e4b7200 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2019-08-13 Richard Sandiford + + PR middle-end/91421 + * c-decl.c (header_for_builtin_fn): Take a FUNCTION_DECL instead + of a built_in_function. + (diagnose_mismatched_decls, implicitly_declare): Update accordingly. + 2019-08-10 Jakub Jelinek * c-parser.c (c_parser_omp_clause_name): Parse device_type. diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 9859cc7b22f..18a97db198d 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -605,7 +605,7 @@ static tree grokparms (struct c_arg_info *, bool); static void layout_array_type (tree); static void warn_defaults_to (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); -static const char *header_for_builtin_fn (enum built_in_function); +static const char *header_for_builtin_fn (tree); /* T is a statement. Add it to the statement-tree. This is the C/ObjC version--C++ has a slightly different version of this @@ -1953,7 +1953,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, if (!comptypes (oldtype, newtype)) { if (TREE_CODE (olddecl) == FUNCTION_DECL - && fndecl_built_in_p (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl)) + && fndecl_built_in_p (olddecl, BUILT_IN_NORMAL) + && !C_DECL_DECLARED_BUILTIN (olddecl)) { /* Accept "harmless" mismatches in function types such as missing qualifiers or pointer vs same size integer @@ -1975,8 +1976,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* If types don't match for a built-in, throw away the built-in. No point in calling locate_old_decl here, it won't print anything. */ - const char *header - = header_for_builtin_fn (DECL_FUNCTION_CODE (olddecl)); + const char *header = header_for_builtin_fn (olddecl); location_t loc = DECL_SOURCE_LOCATION (newdecl); if (warning_at (loc, OPT_Wbuiltin_declaration_mismatch, "conflicting types for built-in function %q+D; " @@ -3339,13 +3339,17 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl) hint.suppress (); } -/* This function represents mapping of a function code FCODE - to its respective header. */ +/* Return the name of the header file that declares built-in function + FNDECL, or null if either we don't know or don't expect to see an + explicit declaration. */ static const char * -header_for_builtin_fn (enum built_in_function fcode) +header_for_builtin_fn (tree fndecl) { - switch (fcode) + if (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL) + return NULL; + + switch (DECL_FUNCTION_CODE (fndecl)) { CASE_FLT_FN (BUILT_IN_ACOS): CASE_FLT_FN (BUILT_IN_ACOSH): @@ -3595,8 +3599,7 @@ implicitly_declare (location_t loc, tree functionid) "declaration of built-in " "function %qD", decl); /* See if we can hint which header to include. */ - const char *header - = header_for_builtin_fn (DECL_FUNCTION_CODE (decl)); + const char *header = header_for_builtin_fn (decl); if (header != NULL && warned) { rich_location richloc (line_table, loc); diff --git a/gcc/calls.c b/gcc/calls.c index 7507b698e27..54e30e6cb0d 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1350,7 +1350,6 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2]) location_t loc = EXPR_LOCATION (exp); tree fntype = fn ? TREE_TYPE (fn) : TREE_TYPE (TREE_TYPE (exp)); - built_in_function fncode = fn ? DECL_FUNCTION_CODE (fn) : BUILT_IN_NONE; bool warned = false; /* Validate each argument individually. */ @@ -1376,11 +1375,10 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2]) friends. Also avoid issuing the warning for calls to function named "alloca". */ - if ((fncode == BUILT_IN_ALLOCA - && IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6) - || (fncode != BUILT_IN_ALLOCA - && !lookup_attribute ("returns_nonnull", - TYPE_ATTRIBUTES (fntype)))) + if (fn && fndecl_built_in_p (fn, BUILT_IN_ALLOCA) + ? IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6 + : !lookup_attribute ("returns_nonnull", + TYPE_ATTRIBUTES (fntype))) warned = warning_at (loc, OPT_Walloc_zero, "%Kargument %i value is zero", exp, idx[i] + 1); diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c index 72e6c779c34..aca5304b10a 100644 --- a/gcc/gimple-ssa-isolate-paths.c +++ b/gcc/gimple-ssa-isolate-paths.c @@ -502,7 +502,7 @@ is_addr_local (gimple *return_stmt, tree exp, locmap_t *plocmap, } if (code == GIMPLE_CALL - && gimple_call_builtin_p (def_stmt)) + && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)) { /* Handle alloca and friends that return pointers to automatic storage. */ diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index b20a6d08794..34e68544fe6 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -2436,8 +2436,7 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, if (can_refer) { if (!target - || (TREE_CODE (TREE_TYPE (target)) == FUNCTION_TYPE - && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE) + || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE) || !possible_polymorphic_call_target_p (ie, cgraph_node::get (target))) { diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 0eeb2534290..e5028bc6150 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -3426,12 +3426,10 @@ possible_polymorphic_call_target_p (tree otr_type, { vec targets; unsigned int i; - enum built_in_function fcode; bool final; - if (TREE_CODE (TREE_TYPE (n->decl)) == FUNCTION_TYPE - && ((fcode = DECL_FUNCTION_CODE (n->decl)) == BUILT_IN_UNREACHABLE - || fcode == BUILT_IN_TRAP)) + if (fndecl_built_in_p (n->decl, BUILT_IN_UNREACHABLE) + || fndecl_built_in_p (n->decl, BUILT_IN_TRAP)) return true; if (is_cxa_pure_virtual_p (n->decl)) diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index ce669f80083..1a0e12e6c0c 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -3331,8 +3331,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie, if (can_refer) { if (!t - || (TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE - && DECL_FUNCTION_CODE (t) == BUILT_IN_UNREACHABLE) + || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE) || !possible_polymorphic_call_target_p (ie, cgraph_node::get (t))) { diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index 35d4fab64b8..c39d6d0235b 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -3237,8 +3237,7 @@ expand_block_edges (struct tm_region *const region, basic_block bb) || (gimple_call_flags (call_stmt) & ECF_TM_BUILTIN) == 0) continue; - if (DECL_FUNCTION_CODE (gimple_call_fndecl (call_stmt)) - == BUILT_IN_TM_ABORT) + if (gimple_call_builtin_p (call_stmt, BUILT_IN_TM_ABORT)) { // If we have a ``_transaction_cancel [[outer]]'', there is only // one abnormal edge: to the transaction marked OUTER. diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index f25e6c8c9a9..458b2184d3f 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2598,7 +2598,7 @@ optimize_stack_restore (gimple_stmt_iterator i) || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee))) return NULL_TREE; - if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE) + if (fndecl_built_in_p (callee, BUILT_IN_STACK_RESTORE)) goto second_stack_restore; } @@ -2657,9 +2657,6 @@ optimize_stdarg_builtin (gimple *call) bool va_list_simple_ptr; location_t loc = gimple_location (call); - if (gimple_code (call) != GIMPLE_CALL) - return NULL_TREE; - callee = gimple_call_fndecl (call); cfun_va_list = targetm.fn_abi_va_list (callee); diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 39ea22f0554..be6a2742579 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -331,6 +331,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e, { tree fndecl = gimple_call_fndecl (stmt); if (fndecl + && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL) && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)) continue; diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 8430c98acc6..ccb2e1edecd 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -1297,7 +1297,7 @@ vect_recog_pow_pattern (stmt_vec_info stmt_vinfo, tree *type_out) { if (flag_unsafe_math_optimizations && TREE_CODE (base) == REAL_CST - && !gimple_call_internal_p (last_stmt)) + && gimple_call_builtin_p (last_stmt, BUILT_IN_NORMAL)) { combined_fn log_cfn; built_in_function exp_bfn;