public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PR c/16351 Extend Wnonnull for returns_nonnull
@ 2015-07-22 15:44 Manuel López-Ibáñez
  2015-07-23 17:52 ` Jeff Law
  0 siblings, 1 reply; 18+ messages in thread
From: Manuel López-Ibáñez @ 2015-07-22 15:44 UTC (permalink / raw)
  To: Gcc Patch List, Jason Merrill, Joseph S. Myers, Jeff Law

[-- Attachment #1: Type: text/plain, Size: 1156 bytes --]

While looking at PR c/16351, I noticed that all tests proposed for
-Wnull-attribute
(https://gcc.gnu.org/ml/gcc-patches/2014-01/msg01715.html) could be
warned from the FEs by simply extending the existing Wnonnull.

Bootstrapped and regression tested on x86_64-linux-gnu.

OK?


gcc/ChangeLog:

2015-07-22  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c/16351
    * doc/invoke.texi (Wnonnull): Document behavior for
    returns_nonnull.

gcc/testsuite/ChangeLog:

2015-07-22  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c/16351
    * c-c++-common/wnonnull-1.c: New test.

gcc/cp/ChangeLog:

2015-07-22  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c/16351
    * typeck.c (check_return_expr): Call maybe_warn_returns_nonnull.


gcc/c-family/ChangeLog:

2015-07-22  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c/16351
    * c-common.c (maybe_warn_returns_nonnull): New.
    * c-common.h (maybe_warn_returns_nonnull): Declare.

gcc/c/ChangeLog:

2015-07-22  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c/16351
    * c-typeck.c (c_finish_return): Call maybe_warn_returns_nonnull.

[-- Attachment #2: wnonnull-1.diff --]
[-- Type: text/plain, Size: 4780 bytes --]

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 225868)
+++ gcc/doc/invoke.texi	(working copy)
@@ -3709,11 +3709,13 @@ formats that may yield only a two-digit 
 
 @item -Wnonnull
 @opindex Wnonnull
 @opindex Wno-nonnull
 Warn about passing a null pointer for arguments marked as
-requiring a non-null value by the @code{nonnull} function attribute.
+requiring a non-null value by the @code{nonnull} function attribute
+or returning a null pointer from a function declared with the attribute
+@code{returns_nonnull}.
 
 @option{-Wnonnull} is included in @option{-Wall} and @option{-Wformat}.  It
 can be disabled with the @option{-Wno-nonnull} option.
 
 @item -Winit-self @r{(C, C++, Objective-C and Objective-C++ only)}
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 225868)
+++ gcc/c-family/c-common.c	(working copy)
@@ -9508,10 +9508,22 @@ check_nonnull_arg (void * ARG_UNUSED (ct
   if (integer_zerop (param))
     warning (OPT_Wnonnull, "null argument where non-null required "
 	     "(argument %lu)", (unsigned long) param_num);
 }
 
+/* Possibly warn if RETVAL is a null pointer and FNDECL is declared
+   with attribute returns_nonnull.  LOC is the location of RETVAL.  */
+
+void
+maybe_warn_returns_nonnull (location_t loc, tree fndecl, tree retval)
+{
+  if (integer_zerop (retval)
+      && lookup_attribute ("returns_nonnull",
+			   TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+    warning_at (loc, OPT_Wnonnull, "null return value where non-null required");
+}
+
 /* Helper for nonnull attribute handling; fetch the operand number
    from the attribute argument list.  */
 
 static bool
 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 225868)
+++ gcc/c-family/c-common.h	(working copy)
@@ -1049,10 +1049,11 @@ extern void do_warn_double_promotion (tr
 extern void set_underlying_type (tree);
 extern void record_types_used_by_current_var_decl (tree);
 extern void record_locally_defined_typedef (tree);
 extern void maybe_record_typedef_use (tree);
 extern void maybe_warn_unused_local_typedefs (void);
+extern void maybe_warn_returns_nonnull (location_t, tree, tree);
 extern void maybe_warn_bool_compare (location_t, enum tree_code, tree, tree);
 extern vec<tree, va_gc> *make_tree_vector (void);
 extern void release_tree_vector (vec<tree, va_gc> *);
 extern vec<tree, va_gc> *make_tree_vector_single (tree);
 extern vec<tree, va_gc> *make_tree_vector_from_list (tree);
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c	(revision 225868)
+++ gcc/c/c-typeck.c	(working copy)
@@ -9372,10 +9372,11 @@ c_finish_return (location_t loc, tree re
 	{
 	  semantic_type = TREE_TYPE (retval);
 	  retval = TREE_OPERAND (retval, 0);
 	}
       retval = c_fully_fold (retval, false, NULL);
+      maybe_warn_returns_nonnull (loc, current_function_decl, retval);
       if (semantic_type)
 	retval = build1 (EXCESS_PRECISION_EXPR, semantic_type, retval);
     }
 
   if (!retval)
Index: gcc/testsuite/c-c++-common/wnonnull-1.c
===================================================================
--- gcc/testsuite/c-c++-common/wnonnull-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/wnonnull-1.c	(revision 0)
@@ -0,0 +1,42 @@
+/* { dg-do compile } */ 
+/* { dg-options "-Wnonnull" } */
+
+
+extern void foo(void *) __attribute__ ((__nonnull__ (1)));
+
+int z;
+int y;
+
+void
+com (int a)
+{
+  foo (a == 42 ? &z  : (void *) 0); /* { dg-warning "null" } */
+}
+
+void
+bar (void)
+{
+  foo ((void *)0); /* { dg-warning "null" } */
+}
+
+int * foo_r(int a) __attribute__((returns_nonnull));
+int * bar_r(void) __attribute__((returns_nonnull));
+
+int *
+foo_r(int a)
+{
+  switch (a)
+    {
+      case 0:
+        return &z;
+      default:
+        return (int *)0; /* { dg-warning "null" } */
+    }
+}
+
+int *
+bar_r (void)
+{
+  return 0;		/* { dg-warning "null" } */
+}
+
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 225868)
+++ gcc/cp/typeck.c	(working copy)
@@ -8702,10 +8702,12 @@ check_return_expr (tree retval, bool *no
   /* We don't need to do any conversions when there's nothing being
      returned.  */
   if (!retval)
     return NULL_TREE;
 
+  maybe_warn_returns_nonnull (input_location, current_function_decl, retval);
+
   /* Do any required conversions.  */
   if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
     /* No conversions are required.  */
     ;
   else

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2015-07-25 17:02 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-22 15:44 PR c/16351 Extend Wnonnull for returns_nonnull Manuel López-Ibáñez
2015-07-23 17:52 ` Jeff Law
2015-07-23 23:19   ` Bernhard Reutner-Fischer
2015-07-24  7:05     ` Jeff Law
2015-07-24  8:09       ` Bernhard Reutner-Fischer
2015-07-24 19:11         ` Jeff Law
2015-07-24 14:26   ` Manuel López-Ibáñez
2015-07-24 19:56     ` Jeff Law
2015-07-24 22:17       ` Manuel López-Ibáñez
2015-07-24 22:26         ` Patrick Palka
2015-07-24 23:15           ` Manuel López-Ibáñez
2015-07-25  2:20             ` Jeff Law
2015-07-25  1:29           ` Jeff Law
2015-07-25  0:01         ` Trevor Saunders
2015-07-25  0:48           ` Manuel López-Ibáñez
2015-07-25  6:54           ` Jeff Law
2015-07-25 18:43           ` Bernhard Reutner-Fischer
2015-07-25  0:50         ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).