This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fwd: Fix an issue in unused value warning for C++ frontend (PR/39551)


Hi Jason,

Thanks a lot for the review. When I updated my source tree with the
latest mainline and re-ran the testsuite (in preparation for
submission), I saw a new failure in g++.dg/warn/Wunused-1.C, where the
compiler with my patch emitted an unexpected warning at line 13 (see
below).

  5 struct A {};
  6 struct B { char c; };
  7
  8 void foo ()
  9 {
 10   struct A a0, a1;
 11   struct B b0, b1 = { 25 };
 12
 13   a0 = a1;      // { dg-bogus "value computed is not used" }
 14   b0 = b1;
 15 }

It turns out that, with your patch that fixes PR c++/39480 (submitted
yesterday), the code emitted by the C++ FE for line 13 changes from

* (struct A *) __builtin_memcpy (&a0, (const struct A &) (const struct
A *) &a1, 0)

to

* (&a0 == (const struct A &) &a1 ? &a0 : (struct A *) __builtin_memcpy
(&a0, (const struct A &) &a1, 0))

And my original changes in convert_to_void failed to handle the new
code and therefore emitted a bogus warning.

I've modified my patch and changed 'is_builtin_func_call' to
'contains_builtin_func_call' so that we can correctly identify the
expression containing builtin function calls generated by the
front-end. Please take a look at the enclosed patch again. Thanks.

This new patch was bootstrapped and tested on x86_64-linux-gnu.

Le-chun


2009-04-14  Le-Chun Wu  <lcwu@google.com>

        PR c++/39551
       * gcc/cp/cvt.c (contains_builtin_func_call): New function.
       (convert_to_void): Emit warning when stripping off INDIRECT_REF.
       * gcc/testsuite/g++.dg/warn/Wunused-13.C: New test.


Index: gcc/testsuite/g++.dg/warn/Wunused-13.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wunused-13.C	(revision 0)
+++ gcc/testsuite/g++.dg/warn/Wunused-13.C	(revision 0)
@@ -0,0 +1,7 @@
+// Test whether -Wunused handles effectless indirect_ref operation ('*').
+// { dg-do compile }
+// { dg-options "-Wunused" }
+
+void Foo(int* x) {
+  *x++; // { dg-warning "value computed is not used" }
+}
Index: gcc/cp/cvt.c
===================================================================
--- gcc/cp/cvt.c	(revision 146055)
+++ gcc/cp/cvt.c	(working copy)
@@ -765,6 +765,44 @@ ocp_convert (tree type, tree expr, int c
   return error_mark_node;
 }

+/* Check if the given EXPR contains a built-in function call.  */
+
+static bool
+contains_builtin_func_call (tree expr)
+{
+  tree fndecl;
+
+  /* The compiler could generate implicit conversions under some
+     circumstances. We are not interested in these conversions.
+     Do not use STRIP_NOPs because it will not strip conversions
+     to "void", as that is not a mode-preserving conversion.  */
+  while (TREE_CODE (expr) == NOP_EXPR)
+    expr = TREE_OPERAND (expr, 0);
+
+  if (TREE_CODE (expr) != CALL_EXPR)
+    {
+      if (EXPR_P (expr))
+        {
+          int nops = TREE_OPERAND_LENGTH (expr);
+          int i;
+          for (i = 0; i < nops; i++)
+            {
+              tree op = TREE_OPERAND (expr, i);
+              if (contains_builtin_func_call (op))
+                return true;
+            }
+        }
+      return false;
+    }
+
+  fndecl = get_callee_fndecl (expr);
+
+  if (fndecl && DECL_BUILT_IN (fndecl))
+    return true;
+  else
+    return false;
+}
+
 /* When an expression is used in a void context, its value is discarded and
    no lvalue-rvalue and similar conversions happen [expr.static.cast/4,
    stmt.expr/1, expr.comma/1].  This permits dereferencing an incomplete type
@@ -870,7 +908,24 @@ convert_to_void (tree expr, const char *
                        implicit ? implicit : "void context");
           }
 	if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type))
-	  expr = TREE_OPERAND (expr, 0);
+          {
+            expr = TREE_OPERAND (expr, 0);
+            /* Emit a warning (if enabled) when the "effect-less" INDIRECT_REF
+               operation is stripped off. Note that we don't warn about
+               - automatic dereferencing of references, since the user cannot
+                 control it. (See also warn_if_unused_value() in stmt.c.)
+               - automatic dereferencing of an expression containing builtin
+                 function calls, since the compiler can do things like
+                 converting a struct copy to a __builtin_memcpy call (or to an
+                 expression containing __builtin_memcpy), which is then
+                 automatically dereferenced. (For an example, see
+                 build_over_call in call.c.)  */
+            if (warn_unused_value
+                && (complain & tf_warning)
+                && !is_reference
+                && !contains_builtin_func_call (expr))
+              warning (OPT_Wunused_value, "value computed is not used");
+          }

 	break;
       }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]