diff options
author | Martin Sebor <msebor@redhat.com> | 2021-01-25 12:41:28 -0700 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2021-01-25 12:41:28 -0700 |
commit | d6f1cf644c45b76a27b6a6869dedaa030e3c7570 (patch) | |
tree | 099882d59ed8681df57417ddd194bc67af3039cf /gcc | |
parent | 7d54cccad332074d5fb81123796239f0f61b11a7 (diff) | |
download | gcc-d6f1cf644c45b76a27b6a6869dedaa030e3c7570.zip gcc-d6f1cf644c45b76a27b6a6869dedaa030e3c7570.tar.gz gcc-d6f1cf644c45b76a27b6a6869dedaa030e3c7570.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c-family/c-common.c | 2 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wnonnull10.C | 63 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wnonnull5.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wnonnull9.C | 117 | ||||
-rw-r--r-- | 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 2028e93..813212c 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 f94488b..e809f0e 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 0000000..a7e795c --- /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 78862d4..959cf18 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 0000000..b6135c4 --- /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 965f092..3bfd4a6 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", |