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",
}
/* 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;
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;
}
--- /dev/null
+/* 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" }
+}
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)
--- /dev/null
+/* 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" }
+}
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",