aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-07-06 15:23:37 -0600
committerMartin Sebor <msebor@redhat.com>2020-07-06 15:23:37 -0600
commit67a493a0b9e7ce6caba4b8bedf1f3295e477ec00 (patch)
tree952e9ccb0ffa2e3f8c2e190f2cdc389a2085e2b8 /gcc
parent6e1c9715b3142bc09e313c0d4b196694ab7ae153 (diff)
downloadgcc-67a493a0b9e7ce6caba4b8bedf1f3295e477ec00.zip
gcc-67a493a0b9e7ce6caba4b8bedf1f3295e477ec00.tar.gz
gcc-67a493a0b9e7ce6caba4b8bedf1f3295e477ec00.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/c-common.c22
-rw-r--r--gcc/cp/call.c13
-rw-r--r--gcc/testsuite/g++.dg/warn/Wnonnull6.C37
3 files changed, 63 insertions, 9 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index aae1ddb..51ecde6 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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. */
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index d8923be..5341a57 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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)));
diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull6.C b/gcc/testsuite/g++.dg/warn/Wnonnull6.C
new file mode 100644
index 0000000..dae6dd2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wnonnull6.C
@@ -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" }
+}