public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-6900] PR c++/98646 - spurious -Wnonnull calling a member on the result of static_cast
@ 2021-01-25 19:43 Martin Sebor
  0 siblings, 0 replies; only message in thread
From: Martin Sebor @ 2021-01-25 19:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:d6f1cf644c45b76a27b6a6869dedaa030e3c7570

commit r11-6900-gd6f1cf644c45b76a27b6a6869dedaa030e3c7570
Author: Martin Sebor <msebor@redhat.com>
Date:   Mon Jan 25 12:41:28 2021 -0700

    PR c++/98646 - spurious -Wnonnull calling a member on the result of static_cast
    
    gcc/c-family/ChangeLog:
    
            PR c++/98646
            * c-common.c (check_nonnull_arg): Adjust warning text.
    
    gcc/cp/ChangeLog:
    
            PR c++/98646
            * cvt.c (cp_fold_convert): Propagate TREE_NO_WARNING.
    
    gcc/ChangeLog:
    
            PR c++/98646
            * tree-ssa-ccp.c (pass_post_ipa_warn::execute): Adjust warning text.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/98646
            * g++.dg/warn/Wnonnull5.C: Adjust text of an expected warning.
            * g++.dg/warn/Wnonnull10.C: New test.
            * g++.dg/warn/Wnonnull9.C: New test.

Diff:
---
 gcc/c-family/c-common.c                |   2 +-
 gcc/cp/cvt.c                           |   9 ++-
 gcc/testsuite/g++.dg/warn/Wnonnull10.C |  63 ++++++++++++++++++
 gcc/testsuite/g++.dg/warn/Wnonnull5.C  |  10 +--
 gcc/testsuite/g++.dg/warn/Wnonnull9.C  | 117 +++++++++++++++++++++++++++++++++
 gcc/tree-ssa-ccp.c                     |   2 +-
 6 files changed, 195 insertions(+), 8 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 2028e93b4d7..813212cc21d 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5595,7 +5595,7 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num)
   if (param_num == 0)
     {
       warned = warning_at (loc, OPT_Wnonnull,
-			   "%qs pointer null", "this");
+			   "%qs pointer is null", "this");
       if (warned && pctx->fndecl)
 	inform (DECL_SOURCE_LOCATION (pctx->fndecl),
 		"in a call to non-static member function %qD",
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index f94488b1114..e809f0e4068 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -599,11 +599,14 @@ ignore_overflows (tree expr, tree orig)
 }
 
 /* Fold away simple conversions, but make sure TREE_OVERFLOW is set
-   properly.  */
+   properly and propagate TREE_NO_WARNING if folding EXPR results
+   in the same expression code.  */
 
 tree
 cp_fold_convert (tree type, tree expr)
 {
+  bool nowarn = TREE_NO_WARNING (expr);
+
   tree conv;
   if (TREE_TYPE (expr) == type)
     conv = expr;
@@ -626,6 +629,10 @@ cp_fold_convert (tree type, tree expr)
       conv = fold_convert (type, expr);
       conv = ignore_overflows (conv, expr);
     }
+
+  if (nowarn && TREE_CODE (expr) == TREE_CODE (conv))
+    TREE_NO_WARNING (conv) = nowarn;
+
   return conv;
 }
 
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull10.C b/gcc/testsuite/g++.dg/warn/Wnonnull10.C
new file mode 100644
index 00000000000..a7e795ceb8a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull10.C
@@ -0,0 +1,63 @@
+/* Very that -Wnonnull is issued for calls to inline member functions
+   with a null this pointer.
+   { dg-do compile }
+   { dg-options "-Wall" } */
+
+#if __cplusplus < 201103L
+# define nullptr 0
+#endif
+
+struct S
+{
+  void f () { }
+  static void g () { }
+  virtual void h () { }
+};
+
+void f0 ()
+{
+  static_cast<S*>(0)->f ();         // { dg-warning "-Wnonnull" }
+  static_cast<S*>(0)->g ();
+  static_cast<S*>(0)->h ();         // { dg-warning "-Wnonnull" }
+}
+
+void f1 ()
+{
+  static_cast<S*>(nullptr)->f ();   // { dg-warning "-Wnonnull" }
+  static_cast<S*>(nullptr)->g ();
+  static_cast<S*>(nullptr)->h ();   // { dg-warning "-Wnonnull" }
+}
+
+void f2 ()
+{
+  S* const p = 0;
+
+  p->f ();                          // { dg-warning "-Wnonnull" }
+  p->g ();
+  p->h ();                          // { dg-warning "-Wnonnull" }
+}
+
+
+#pragma GCC optimize "1"
+
+void f3 ()
+{
+  S *p = 0;
+
+  p->f ();                          // { dg-warning "-Wnonnull" }
+  p->g ();
+  p->h ();                          // { dg-warning "-Wnonnull" }
+}
+
+
+#pragma GCC optimize "2"
+
+void f4 (S *p)
+{
+  if (p)
+    return;
+
+  p->f ();                          // { dg-warning "-Wnonnull" }
+  p->g ();
+  p->h ();                          // { dg-warning "-Wnonnull" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull5.C b/gcc/testsuite/g++.dg/warn/Wnonnull5.C
index 78862d48993..959cf1840f8 100644
--- a/gcc/testsuite/g++.dg/warn/Wnonnull5.C
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull5.C
@@ -35,21 +35,21 @@ struct S
 
 void warn_nullptr_this ()
 {
-  ((S*)nullptr)->f0 ("");        // { dg-warning "3:'this' pointer null" "pr86568" { xfail *-*-* } }
-                                 // { dg-warning "this' pointer null" "pr86568 second variant" { target *-*-* } .-1 }
+  ((S*)nullptr)->f0 ("");        // { dg-warning "3:'this' pointer is null" "pr86568" { xfail *-*-* } }
+                                 // { dg-warning "this' pointer is null" "pr86568 second variant" { target *-*-* } .-1 }
 }
 
 void warn_null_this_cst ()
 {
   S* const null = 0;
-  null->f1 ("");                  // { dg-warning "3:'this' pointer null" }
+  null->f1 ("");                  // { dg-warning "3:'this' pointer is null" }
 }
 
 void warn_null_this_var ()
 {
   S* null = 0;
-  null->f2 (&null);               // { dg-warning "3:'this' pointer null" "pr86568" { xfail *-*-* } }
-                                  // { dg-warning "'this' pointer null" "pr86568 second variant" { target *-*-* } .-1 }
+  null->f2 (&null);               // { dg-warning "3:'this' pointer is null" "pr86568" { xfail *-*-* } }
+                                  // { dg-warning "'this' pointer is null" "pr86568 second variant" { target *-*-* } .-1 }
 }
 
 void warn_nullptr (S s)
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull9.C b/gcc/testsuite/g++.dg/warn/Wnonnull9.C
new file mode 100644
index 00000000000..b6135c4a624
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull9.C
@@ -0,0 +1,117 @@
+/* PR c++/98646 - spurious -Wnonnull calling a member on the result
+   of static_cast
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+struct A { virtual ~A (); };
+struct B
+{
+  virtual ~B ();
+  B* bptr ();
+  B& bref ();
+};
+
+struct C: A, B { virtual ~C (); void g () const; };
+
+
+void c_cast_C_ptr (B *p)
+{
+  ((C*)p->bptr ())->g ();
+}
+
+void c_cast_const_C_ptr (B *p)
+{
+  ((const C*)p->bptr ())->g ();
+}
+
+void static_cast_C_ptr (B *p)
+{
+  static_cast<C*>(p->bptr ())->g ();
+}
+
+void static_cast_const_C_ptr (B *p)
+{
+  /* The static_cast can't fail so verify that no warning is issued
+     here, even though GCC emits a null check for its argument.  */
+  static_cast<const C*>(p->bptr ())->g ();    // { dg-bogus "\\\[-Wnonnull" }
+}
+
+void dynamic_cast_C_ptr (B *p)
+{
+  // The dynamic_cast might fail so a warning is justified.
+  dynamic_cast<C*>(p->bptr ())->g ();         // { dg-warning "\\\[-Wnonnull" }
+}
+
+void dynamic_cast_const_C_ptr (B *p)
+{
+  dynamic_cast<const C*>(p->bptr ())->g ();   // { dg-warning "\\\[-Wnonnull" }
+}
+
+
+void c_cast_C_ref (B *p)
+{
+  ((C&)p->bref ()).g ();
+}
+
+void c_cast_const_C_ref (B *p)
+{
+  ((const C&)p->bref ()).g ();
+}
+
+void static_cast_C_ref (B *p)
+{
+  static_cast<C&>(p->bref ()).g ();
+}
+
+void static_cast_const_C_ref (B *p)
+{
+  static_cast<const C&>(p->bref ()).g ();
+}
+
+void dynamic_cast_C_ref (B *p)
+{
+  /* The dynamic_cast fails by throwing an exception so verify that
+     no warning is issued.  */
+  dynamic_cast<C&>(p->bref ()).g ();
+}
+
+void dynamic_cast_const_C_ref (B *p)
+{
+  dynamic_cast<const C&>(p->bref ()).g ();
+}
+
+
+struct D: B, A { virtual ~D (); void g () const; };
+
+void c_cast_D_ptr (B *p)
+{
+  ((D*)p->bptr ())->g ();
+}
+
+void c_cast_const_D_ptr (B *p)
+{
+  ((const D*)p->bptr ())->g ();
+}
+
+void static_cast_D_ptr (B *p)
+{
+  static_cast<D*>(p->bptr ())->g ();
+}
+
+void static_cast_const_D_ptr (B *p)
+{
+  /* The static_cast can't fail so verify that no warning is issued
+     here, even though GCC emits a null check for its argument.  */
+  static_cast<const D*>(p->bptr ())->g ();    // { dg-bogus "\\\[-Wnonnull" }
+}
+
+void dynamic_cast_D_ptr (B *p)
+{
+  // The dynamic_cast might fail so a warning is justified.
+  dynamic_cast<D*>(p->bptr ())->g ();         // { dg-warning "\\\[-Wnonnull" }
+}
+
+void dynamic_cast_const_D_ptr (B *p)
+{
+  dynamic_cast<const D*>(p->bptr ())->g ();   // { dg-warning "\\\[-Wnonnull" }
+}
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 965f092cccc..3bfd4a6265c 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -3564,7 +3564,7 @@ pass_post_ipa_warn::execute (function *fun)
 	      if (argno == 0)
 		{
 		  if (warning_at (loc, OPT_Wnonnull,
-				  "%G%qs pointer null", stmt, "this")
+				  "%G%qs pointer is null", stmt, "this")
 		      && fndecl)
 		    inform (DECL_SOURCE_LOCATION (fndecl),
 			    "in a call to non-static member function %qD",


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-01-25 19:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-25 19:43 [gcc r11-6900] PR c++/98646 - spurious -Wnonnull calling a member on the result of static_cast Martin Sebor

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).