From b659c00e54ff3bee736f502e7fa4dc233a814b66 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Wed, 12 Jun 2019 12:22:36 +0200
Subject: [PATCH] Do not warn with warn_unused_result for alloca(0).

gcc/ChangeLog:

2019-06-12  Martin Liska  <mliska@suse.cz>

	* calls.c (special_function_p): Make it global.
	* calls.h (special_function_p): Declare.
	* tree-cfg.c (do_warn_unused_result): Do not
	warn for alloca(0).

gcc/testsuite/ChangeLog:

2019-06-12  Martin Liska  <mliska@suse.cz>

	* gcc.dg/pr78902.c: Add testing of alloca(0).
	* gcc.dg/attr-alloc_size-5.c: Do not warn
	about alloca(0).
---
 gcc/calls.c                              |  3 +--
 gcc/calls.h                              |  1 +
 gcc/testsuite/gcc.dg/attr-alloc_size-5.c |  2 +-
 gcc/testsuite/gcc.dg/pr78902.c           |  1 +
 gcc/tree-cfg.c                           | 16 ++++++++++++----
 5 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/gcc/calls.c b/gcc/calls.c
index c8a42680041..be9b2ff046a 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -153,7 +153,6 @@ static void compute_argument_addresses (struct arg_data *, rtx, int);
 static rtx rtx_for_function_call (tree, tree);
 static void load_register_parameters (struct arg_data *, int, rtx *, int,
 				      int, int *);
-static int special_function_p (const_tree, int);
 static int check_sibcall_argument_overlap_1 (rtx);
 static int check_sibcall_argument_overlap (rtx_insn *, struct arg_data *, int);
 
@@ -578,7 +577,7 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
    Set ECF_MAY_BE_ALLOCA for any memory allocation function that might allocate
    space from the stack such as alloca.  */
 
-static int
+int
 special_function_p (const_tree fndecl, int flags)
 {
   tree name_decl = DECL_NAME (fndecl);
diff --git a/gcc/calls.h b/gcc/calls.h
index 128bb513074..0d2bc888b26 100644
--- a/gcc/calls.h
+++ b/gcc/calls.h
@@ -42,5 +42,6 @@ extern tree get_attr_nonstring_decl (tree, tree * = NULL);
 extern void maybe_warn_nonstring_arg (tree, tree);
 extern bool get_size_range (tree, tree[2], bool = false);
 extern rtx rtx_for_static_chain (const_tree, bool);
+extern int special_function_p (const_tree, int);
 
 #endif // GCC_CALLS_H
diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
index 7aa7cbf0c72..26ee43f87de 100644
--- a/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
+++ b/gcc/testsuite/gcc.dg/attr-alloc_size-5.c
@@ -230,5 +230,5 @@ test_alloca (size_t n)
 {
   extern void* alloca (size_t);
 
-  alloca (0); /* { dg-warning "ignoring return value of '.*' declared with attribute 'warn_unused_result'" } */
+  alloca (0);
 }
diff --git a/gcc/testsuite/gcc.dg/pr78902.c b/gcc/testsuite/gcc.dg/pr78902.c
index 49efc970475..f0f4314d684 100644
--- a/gcc/testsuite/gcc.dg/pr78902.c
+++ b/gcc/testsuite/gcc.dg/pr78902.c
@@ -7,6 +7,7 @@ void foo(void)
  __builtin_malloc (1); /* { dg-warning "ignoring return value of '__builtin_malloc' declared with attribute 'warn_unused_result'" } */
  __builtin_calloc (10, 20); /* { dg-warning "ignoring return value of '__builtin_calloc' declared with attribute 'warn_unused_result'" } */
  __builtin_alloca (10); /* { dg-warning "ignoring return value of '__builtin_alloca' declared with attribute 'warn_unused_result'" } */
+ __builtin_alloca (0);
  __builtin_realloc (ptr, 100); /* { dg-warning "ignoring return value of '__builtin_realloc' declared with attribute 'warn_unused_result'" } */
  __builtin_aligned_alloc (10, 16); /* { dg-warning "ignoring return value of '__builtin_aligned_alloc' declared with attribute 'warn_unused_result'" } */
  __builtin_strdup ("pes"); /* { dg-warning "ignoring return value of '__builtin_strdup' declared with attribute 'warn_unused_result'" } */
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index a585efea3d8..9419de8a756 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "opts.h"
 #include "asan.h"
 #include "profile.h"
+#include "calls.h"
 
 /* This file contains functions for building the Control Flow Graph (CFG)
    for a function tree.  */
@@ -9447,10 +9448,17 @@ do_warn_unused_result (gimple_seq seq)
 	      location_t loc = gimple_location (g);
 
 	      if (fdecl)
-		warning_at (loc, OPT_Wunused_result,
-			    "ignoring return value of %qD "
-			    "declared with attribute %<warn_unused_result%>",
-			    fdecl);
+		{
+		  if ((special_function_p (fdecl, 0) & ECF_MAY_BE_ALLOCA)
+		      && TREE_CODE (gimple_call_arg (g, 0)) == INTEGER_CST
+		      && wi::to_wide (gimple_call_arg (g, 0)) == 0)
+		    ;
+		  else
+		    warning_at (loc, OPT_Wunused_result,
+				"ignoring return value of %qD declared "
+				"with attribute %<warn_unused_result%>",
+				fdecl);
+		}
 	      else
 		warning_at (loc, OPT_Wunused_result,
 			    "ignoring return value of function "
-- 
2.21.0

