Protect some checks of DECL_FUNCTION_CODE
diff mbox series

Message ID mptftm5tnn4.fsf@arm.com
State New
Headers show
Series
  • Protect some checks of DECL_FUNCTION_CODE
Related show

Commit Message

Richard Sandiford Aug. 13, 2019, 9:34 a.m. UTC
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.

Tested on aarch64-linux-gnu and x86_64-linux-gnu (--enable-languages=all
--enable-host-shared).  OK to install?

Richard


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.

Comments

Jeff Law Aug. 13, 2019, 3:07 p.m. UTC | #1
On 8/13/19 3:34 AM, Richard Sandiford wrote:
> 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.
> 
> Tested on aarch64-linux-gnu and x86_64-linux-gnu (--enable-languages=all
> --enable-host-shared).  OK to install?
> 
> Richard
> 
> 
> 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.
OK
jeff

Patch
diff mbox series

Index: gcc/attribs.c
===================================================================
--- gcc/attribs.c	2019-07-18 09:22:13.409771785 +0100
+++ gcc/attribs.c	2019-08-13 10:31:18.211019996 +0100
@@ -691,6 +691,7 @@  decl_attributes (tree *node, tree attrib
 
 	  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: gcc/calls.c
===================================================================
--- gcc/calls.c	2019-07-29 09:39:49.750165306 +0100
+++ gcc/calls.c	2019-08-13 10:31:18.215019968 +0100
@@ -1350,7 +1350,6 @@  maybe_warn_alloc_args_overflow (tree fn,
   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,
 		 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: gcc/ipa-cp.c
===================================================================
--- gcc/ipa-cp.c	2019-07-16 09:11:05.561423510 +0100
+++ gcc/ipa-cp.c	2019-08-13 10:31:18.219019937 +0100
@@ -2436,8 +2436,7 @@  ipa_get_indirect_edge_target_1 (struct c
 	  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: gcc/ipa-devirt.c
===================================================================
--- gcc/ipa-devirt.c	2019-08-05 17:46:20.173727579 +0100
+++ gcc/ipa-devirt.c	2019-08-13 10:31:18.219019937 +0100
@@ -3426,12 +3426,10 @@  possible_polymorphic_call_target_p (tree
 {
   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: gcc/ipa-prop.c
===================================================================
--- gcc/ipa-prop.c	2019-08-07 14:18:27.207914346 +0100
+++ gcc/ipa-prop.c	2019-08-13 10:31:18.219019937 +0100
@@ -3331,8 +3331,7 @@  try_make_edge_direct_virtual_call (struc
 	  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: gcc/gimple-ssa-isolate-paths.c
===================================================================
--- gcc/gimple-ssa-isolate-paths.c	2019-07-10 19:41:26.387898094 +0100
+++ gcc/gimple-ssa-isolate-paths.c	2019-08-13 10:31:18.215019968 +0100
@@ -502,7 +502,7 @@  is_addr_local (gimple *return_stmt, tree
 	}
 
       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: gcc/trans-mem.c
===================================================================
--- gcc/trans-mem.c	2019-06-18 09:35:54.921869466 +0100
+++ gcc/trans-mem.c	2019-08-13 10:31:18.219019937 +0100
@@ -3237,8 +3237,7 @@  expand_block_edges (struct tm_region *co
 	  || (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: gcc/tree-ssa-ccp.c
===================================================================
--- gcc/tree-ssa-ccp.c	2019-08-05 17:46:43.025559703 +0100
+++ gcc/tree-ssa-ccp.c	2019-08-13 10:31:18.223019909 +0100
@@ -2598,7 +2598,7 @@  optimize_stack_restore (gimple_stmt_iter
 	  || 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: gcc/tree-ssa-threadedge.c
===================================================================
--- gcc/tree-ssa-threadedge.c	2019-07-01 09:37:07.416522846 +0100
+++ gcc/tree-ssa-threadedge.c	2019-08-13 10:31:18.223019909 +0100
@@ -331,6 +331,7 @@  record_temporary_equivalences_from_stmts
 	{
 	  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: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c	2019-07-10 19:41:27.155891943 +0100
+++ gcc/tree-vect-patterns.c	2019-08-13 10:31:18.223019909 +0100
@@ -1297,7 +1297,7 @@  vect_recog_pow_pattern (stmt_vec_info st
     {
       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;
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	2019-08-08 18:11:58.055263688 +0100
+++ gcc/c/c-decl.c	2019-08-13 10:31:18.215019968 +0100
@@ -605,7 +605,7 @@  static tree grokparms (struct c_arg_info
 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 @@  #define DECL_EXTERN_INLINE(DECL) (DECL_D
   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 @@  #define DECL_EXTERN_INLINE(DECL) (DECL_D
 	      /* 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, t
     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
 					    "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);