Hello,

This patch fixes fixes an erroneous -Wnonnull warning when calling a
constructor declared with __attribute__ ((nonnull (1))).  The issue is
that a NULL pointer is used as the placeholder object for the "this"
parameter of the constructor method call until a target object is
determined and substituted for the placeholder object during
gimplification.  Meanwhile, check_function_arguments is called in
build_over_call which notices that there is a NULL pointer argument for
a parameter that's been marked nonnull, thus issuing the -Wnonnull
warning.

This patch modifies the C++ frontend to use build_dummy_object() instead
of a NULL pointer as the placeholder object to a constructor method
call.  This suppresses the warning issued by check_function_arguments
because the object returned by build_dummy_object() is not determined to
be a NULL pointer.

I bootstrapped and regtested this patch on x86_64-unknown-linux-gnu.

        PR c++/60764
        * call.c (build_user_type_coversion): Use build_dummy_object
        to create the placeholder object for a constructor method call.
        (build_special_member_call): Likewise.
        (build_over_call): Check for the placeholder object with
        is_dummy_object.
        (build_new_method_call_1): Likewise.  Don't attempt to resolve
        a dummy object for a constructor method call.
---
 gcc/cp/call.c                        | 14 +++++---------
 gcc/testsuite/g++.dg/warn/nonnull2.C | 10 ++++++++++
 2 files changed, 15 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/nonnull2.C

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ae0d4ff..ff5c834 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3519,8 +3519,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int 
flags,
     {
       int ctorflags = flags;
 
-      first_arg = build_int_cst (build_pointer_type (totype), 0);
-      first_arg = build_fold_indirect_ref (first_arg);
+      first_arg = build_dummy_object (totype);
 
       /* We should never try to call the abstract or base constructor
         from here.  */
@@ -7096,7 +7095,7 @@ build_over_call (struct z_candidate *cand, int flags, 
tsubst_flags_t complain)
         ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
         temp or an INIT_EXPR otherwise.  */
       fa = argarray[0];
-      if (integer_zerop (fa))
+      if (is_dummy_object (fa))
        {
          if (TREE_CODE (arg) == TARGET_EXPR)
            return arg;
@@ -7434,10 +7433,7 @@ build_special_member_call (tree instance, tree name, 
vec<tree, va_gc> **args,
 
   /* Handle the special case where INSTANCE is NULL_TREE.  */
   if (name == complete_ctor_identifier && !instance)
-    {
-      instance = build_int_cst (build_pointer_type (class_type), 0);
-      instance = build1 (INDIRECT_REF, class_type, instance);
-    }
+    instance = build_dummy_object (class_type);
   else
     {
       if (name == complete_dtor_identifier
@@ -7747,8 +7743,7 @@ build_new_method_call_1 (tree instance, tree fns, 
vec<tree, va_gc> **args,
 
       if (init)
        {
-         if (INDIRECT_REF_P (instance)
-             && integer_zerop (TREE_OPERAND (instance, 0)))
+         if (is_dummy_object (instance))
            return get_target_expr_sfinae (init, complain);
          init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
          TREE_SIDE_EFFECTS (init) = true;
@@ -7847,6 +7842,7 @@ build_new_method_call_1 (tree instance, tree fns, 
vec<tree, va_gc> **args,
            }
 
          if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
+             && !DECL_CONSTRUCTOR_P (fn)
              && is_dummy_object (instance))
            {
              instance = maybe_resolve_dummy (instance);
diff --git a/gcc/testsuite/g++.dg/warn/nonnull2.C 
b/gcc/testsuite/g++.dg/warn/nonnull2.C
new file mode 100644
index 0000000..10515a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/nonnull2.C
@@ -0,0 +1,10 @@
+// PR c++/60764
+// { dg-options "-Wall" }
+
+struct foo
+{
+  foo () __attribute__ ((nonnull (1)));
+};
+
+const foo &x = foo (); // { dg-bogus "null argument" }
+foo y = foo (); // { dg-bogus "null argument" }
-- 
1.9.1

Reply via email to