Protect some checks of DECL_FUNCTION_CODE
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 13 Aug 2019 21:35:10 +0000 (21:35 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 13 Aug 2019 21:35:10 +0000 (21:35 +0000)
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  <richard.sandiford@arm.com>

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

13 files changed:
gcc/ChangeLog
gcc/attribs.c
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/calls.c
gcc/gimple-ssa-isolate-paths.c
gcc/ipa-cp.c
gcc/ipa-devirt.c
gcc/ipa-prop.c
gcc/trans-mem.c
gcc/tree-ssa-ccp.c
gcc/tree-ssa-threadedge.c
gcc/tree-vect-patterns.c

index 307f5360ea0db2d124e9b8fb51f68fe8b4d91efe..272d084128486526c573d641fb3a63b76ecabc13 100644 (file)
@@ -1,3 +1,28 @@
+2019-08-13  Richard Sandiford  <richard.sandiford@arm.com>
+
+       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  <richard.sandiford@arm.com>
 
        * tree.h (build_vector_a_then_b): Declare.
index f4777c6a823364fc37b6f2cdc922f1b6e3e8334b..b89be5834de7e3cbb8810c7f980da8150e8a1708 100644 (file)
@@ -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)))
index 335801b36979c3af38896fdc5bc38cc79ae53be2..ada2e4b7200f8c2e754a9af0045d7cfb47edc145 100644 (file)
@@ -1,3 +1,10 @@
+2019-08-13  Richard Sandiford  <richard.sandiford@arm.com>
+
+       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  <jakub@redhat.com>
 
        * c-parser.c (c_parser_omp_clause_name): Parse device_type.
index 9859cc7b22f7822d942a649e6b0f67f78c446c58..18a97db198daf96391723e2ebbbfa1ea732072ca 100644 (file)
@@ -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);
 \f
 /* 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);
index 7507b698e27496e226088678832a67d468e00400..54e30e6cb0dc304b0e4e584dab0b250fb5063802 100644 (file)
@@ -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);
index 72e6c779c34e0ef00730eb1fa91b53e99d98d623..aca5304b10aad66a27cb5500666ea892c500e1b6 100644 (file)
@@ -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.  */
index b20a6d0879493fb0a87fd2a3c6a7a543d0dbc09a..34e68544fe6fc5d445f03d34ce23fbe6770532da 100644 (file)
@@ -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)))
                {
index 0eeb25342907a376f3ff27544b9d3d047c9cc449..e5028bc6150f59e159a32af2323f34fc7e3ed36a 100644 (file)
@@ -3426,12 +3426,10 @@ possible_polymorphic_call_target_p (tree otr_type,
 {
   vec <cgraph_node *> 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))
index ce669f800839217478cf2b90316240784ae6b483..1a0e12e6c0c5afdd5f084ed70458077399d48f70 100644 (file)
@@ -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)))
                {
index 35d4fab64b85f15c06bdd9c5c46a7ae94db6fc7f..c39d6d0235ba7f11b6a932eff9e2eefa357b5f09 100644 (file)
@@ -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.
index f25e6c8c9a99aa13f68a3fd32b0f99dfa5bdc4d1..458b2184d3f4191b5fa0a925d6c639b4b1b7479c 100644 (file)
@@ -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);
index 39ea22f0554143d4e49810de15c8ef7919c3786d..be6a27425798b763911dab77a95efb6268ef1bd0 100644 (file)
@@ -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;
index 8430c98acc68de4894c5563677895e48746ee045..ccb2e1edecda09db786c0d98ccd25f5be107c7e4 100644 (file)
@@ -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;