Exclude calls to variadic lambda stubs from -Wnonnull checking (PR c++/95984).
Resolves: PR c++/95984 - Internal compiler error: Error reporting routines re-entered in -Wnonnull on a variadic lamnda PR c++/96021 - missing -Wnonnull passing nullptr to a nonnull variadic lambda gcc/c-family/ChangeLog: PR c++/95984 * c-common.c (check_function_nonnull): Avoid checking syntesized calls to stub lambda objects with null this pointer. (check_nonnull_arg): Handle C++ nullptr. gcc/cp/ChangeLog: PR c++/95984 * call.c (build_over_call): Check calls only when tf_warning is set. gcc/testsuite/ChangeLog: PR c++/95984 * g++.dg/warn/Wnonnull6.C: New test.
This commit is contained in:
parent
6e1c9715b3
commit
67a493a0b9
3 changed files with 63 additions and 9 deletions
|
@ -5308,12 +5308,26 @@ check_function_nonnull (nonnull_arg_ctx &ctx, int nargs, tree *argarray)
|
|||
int firstarg = 0;
|
||||
if (TREE_CODE (ctx.fntype) == METHOD_TYPE)
|
||||
{
|
||||
bool closure = false;
|
||||
if (ctx.fndecl)
|
||||
{
|
||||
/* For certain lambda expressions the C++ front end emits calls
|
||||
that pass a null this pointer as an argument named __closure
|
||||
to the member operator() of empty function. Detect those
|
||||
and avoid checking them, but proceed to check the remaining
|
||||
arguments. */
|
||||
tree arg0 = DECL_ARGUMENTS (ctx.fndecl);
|
||||
if (tree arg0name = DECL_NAME (arg0))
|
||||
closure = id_equal (arg0name, "__closure");
|
||||
}
|
||||
|
||||
/* In calls to C++ non-static member functions check the this
|
||||
pointer regardless of whether the function is declared with
|
||||
attribute nonnull. */
|
||||
firstarg = 1;
|
||||
check_function_arguments_recurse (check_nonnull_arg, &ctx, argarray[0],
|
||||
firstarg);
|
||||
if (!closure)
|
||||
check_function_arguments_recurse (check_nonnull_arg, &ctx, argarray[0],
|
||||
firstarg);
|
||||
}
|
||||
|
||||
tree attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (ctx.fntype));
|
||||
|
@ -5503,7 +5517,9 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num)
|
|||
happen if the "nonnull" attribute was given without an operand
|
||||
list (which means to check every pointer argument). */
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (param)) != POINTER_TYPE)
|
||||
tree paramtype = TREE_TYPE (param);
|
||||
if (TREE_CODE (paramtype) != POINTER_TYPE
|
||||
&& TREE_CODE (paramtype) != NULLPTR_TYPE)
|
||||
return;
|
||||
|
||||
/* Diagnose the simple cases of null arguments. */
|
||||
|
|
|
@ -8842,15 +8842,16 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
|||
gcc_assert (j <= nargs);
|
||||
nargs = j;
|
||||
|
||||
/* Avoid to do argument-transformation, if warnings for format, and for
|
||||
nonnull are disabled. Just in case that at least one of them is active
|
||||
/* Avoid performing argument transformation if warnings are disabled.
|
||||
When tf_warning is set and at least one of the warnings is active
|
||||
the check_function_arguments function might warn about something. */
|
||||
|
||||
bool warned_p = false;
|
||||
if (warn_nonnull
|
||||
|| warn_format
|
||||
|| warn_suggest_attribute_format
|
||||
|| warn_restrict)
|
||||
if ((complain & tf_warning)
|
||||
&& (warn_nonnull
|
||||
|| warn_format
|
||||
|| warn_suggest_attribute_format
|
||||
|| warn_restrict))
|
||||
{
|
||||
tree *fargs = (!nargs ? argarray
|
||||
: (tree *) alloca (nargs * sizeof (tree)));
|
||||
|
|
37
gcc/testsuite/g++.dg/warn/Wnonnull6.C
Normal file
37
gcc/testsuite/g++.dg/warn/Wnonnull6.C
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* PR c++/95984 - Internal compiler error: Error reporting routines re-entered
|
||||
in -Wnonnull on a variadic lamnda
|
||||
PR c++/missing -Wnonnull passing nullptr to a nonnull variadic lambda
|
||||
{ dg-do compile { target c++11 } }
|
||||
{ dg-options "-Wall" } */
|
||||
|
||||
typedef int F (int);
|
||||
|
||||
F* pr95984 ()
|
||||
{
|
||||
// This also triggered the ICE.
|
||||
return [](auto...) { return 0; }; // { dg-bogus "\\\[-Wnonnull" }
|
||||
}
|
||||
|
||||
|
||||
__attribute__ ((nonnull)) void f (int, ...);
|
||||
void ff ()
|
||||
{
|
||||
f (1, nullptr); // { dg-warning "\\\[-Wnonnull" }
|
||||
}
|
||||
|
||||
template <class T> void g (T t)
|
||||
{
|
||||
t (1, nullptr); // { dg-warning "\\\[-Wnonnull" }
|
||||
}
|
||||
|
||||
void gg (void)
|
||||
{
|
||||
g ([](int, auto...) __attribute__ ((nonnull)) { });
|
||||
}
|
||||
|
||||
template <class T> __attribute__ ((nonnull)) void h (T);
|
||||
|
||||
void hh ()
|
||||
{
|
||||
h (nullptr); // { dg-warning "\\\[-Wnonnull" }
|
||||
}
|
Loading…
Add table
Reference in a new issue