[tree-ssa] fix middle-end/13325

Richard Henderson rth@redhat.com
Wed Feb 4 02:30:00 GMT 2004


The Problem here is that we fold the builtin so early that at the
place we check for the warning (still in the front-end mind!), we
have already lost track of the fact that it was originally a call.

I'd have just removed that so-early fold, except that it breaks
test cases that use __builtin_inf/nan in initializers.  Perhaps
there's a better way to solve that...

But in the meantime, expanding the meaning of the existing 
TREE_NO_UNUSED_WARNING bit seemed a good idea.


r~


        PR middle-end/13325
        * builtins.c (fold_builtin_1): Rename from fold_builtin.
        (fold_builtin): New.
        * c-simplify.c (gimplify_expr_stmt): Check TREE_NO_WARNING.
        * stmt.c (expand_expr_stmt_value): Likewise.
        * tree.h (struct tree_common): Add nowarning_flag.
        (TREE_NO_WARNING): New.
        (TREE_NO_UNUSED_WARNING): Remove.
        * c-typeck.c (build_unary_op): Use TREE_NO_WARNING instead.
        * stmt.c (warn_if_unused_value): Likewise.
cp/
        * call.c, cvt.c, init.c, typeck.c: Use TREE_NO_WARNING instead
        of TREE_NO_UNUSED_WARNING.
        * cvt.c (convert_to_void): Also use it for "has no effect" warning.
testsuite/
        * g++.dg/warn/noeffect5.C: New.
        * gcc.dg/20040202-1.c: New.

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.152.2.47
diff -c -p -d -u -r1.152.2.47 builtins.c
--- builtins.c	30 Jan 2004 13:13:29 -0000	1.152.2.47
+++ builtins.c	4 Feb 2004 02:11:28 -0000
@@ -6608,8 +6608,8 @@ fold_builtin_strncmp (tree exp)
 /* Used by constant folding to eliminate some builtin calls early.  EXP is
    the CALL_EXPR of a call to a builtin function.  */
 
-tree
-fold_builtin (tree exp)
+static tree
+fold_builtin_1 (tree exp)
 {
   tree fndecl = get_callee_fndecl (exp);
   tree arglist = TREE_OPERAND (exp, 1);
@@ -7031,6 +7031,24 @@ fold_builtin (tree exp)
     }
 
   return 0;
+}
+
+/* A wrapper function for builtin folding that prevents warnings for
+   "statement without effect" and the like, caused by removing the 
+   call node earlier than the warning is generated.  */
+
+tree
+fold_builtin (tree exp)
+{
+  exp = fold_builtin_1 (exp);
+  if (exp)
+    {
+      /* ??? Don't clobber shared nodes such as integer_zero_node.  */
+      if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
+	exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
+      TREE_NO_WARNING (exp) = 1;
+    }
+  return exp;
 }
 
 /* Conveniently construct a function call expression.  */
Index: c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.4.90
diff -c -p -d -u -r1.1.4.90 c-simplify.c
--- c-simplify.c	30 Jan 2004 04:34:41 -0000	1.1.4.90
+++ c-simplify.c	4 Feb 2004 02:11:28 -0000
@@ -515,7 +515,9 @@ gimplify_expr_stmt (tree *stmt_p)
     {
       if (!TREE_SIDE_EFFECTS (stmt))
 	{
-	  if (!IS_EMPTY_STMT (stmt) && !VOID_TYPE_P (TREE_TYPE (stmt)))
+	  if (!IS_EMPTY_STMT (stmt)
+	      && !VOID_TYPE_P (TREE_TYPE (stmt))
+	      && !TREE_NO_WARNING (stmt))
 	    warning ("statement with no effect");
 	}
       else if (warn_unused_value)
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.196.2.37
diff -c -p -d -u -r1.196.2.37 c-typeck.c
--- c-typeck.c	30 Jan 2004 13:13:36 -0000	1.196.2.37
+++ c-typeck.c	4 Feb 2004 02:11:28 -0000
@@ -2363,7 +2363,7 @@ build_unary_op (enum tree_code code, tre
 	TREE_SIDE_EFFECTS (val) = 1;
 	val = convert (result_type, val);
 	if (TREE_CODE (val) != code)
-	  TREE_NO_UNUSED_WARNING (val) = 1;
+	  TREE_NO_WARNING (val) = 1;
 	return val;
       }
 
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.267.2.45
diff -c -p -d -u -r1.267.2.45 stmt.c
--- stmt.c	30 Jan 2004 13:14:16 -0000	1.267.2.45
+++ stmt.c	4 Feb 2004 02:11:29 -0000
@@ -2228,7 +2228,7 @@ expand_expr_stmt_value (tree exp, int wa
     {
       if (TREE_SIDE_EFFECTS (exp))
 	warn_if_unused_value (exp);
-      else if (!VOID_TYPE_P (TREE_TYPE (exp)))
+      else if (!VOID_TYPE_P (TREE_TYPE (exp)) && !TREE_NO_WARNING (exp))
 	warning ("%Hstatement with no effect", &emit_locus);
     }
 
@@ -2328,7 +2328,7 @@ warn_if_unused_value (tree exp)
       return warn_if_unused_value (TREE_OPERAND (exp, 1));
 
     case COMPOUND_EXPR:
-      if (TREE_NO_UNUSED_WARNING (exp))
+      if (TREE_NO_WARNING (exp))
 	return 0;
       if (warn_if_unused_value (TREE_OPERAND (exp, 0)))
 	return 1;
@@ -2341,7 +2341,7 @@ warn_if_unused_value (tree exp)
     case CONVERT_EXPR:
     case NON_LVALUE_EXPR:
       /* Don't warn about conversions not explicit in the user's program.  */
-      if (TREE_NO_UNUSED_WARNING (exp))
+      if (TREE_NO_WARNING (exp))
 	return 0;
       /* Assignment to a cast usually results in a cast of a modify.
 	 Don't complain about that.  There can be an arbitrary number of
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.165
diff -c -p -d -u -r1.342.2.165 tree.h
--- tree.h	30 Jan 2004 13:14:19 -0000	1.342.2.165
+++ tree.h	4 Feb 2004 02:11:29 -0000
@@ -142,7 +142,7 @@ struct tree_common GTY(())
   unsigned readonly_flag : 1;
   unsigned unsigned_flag : 1;
   unsigned asm_written_flag: 1;
-  unsigned : 1;
+  unsigned nowarning_flag : 1;
 
   unsigned used_flag : 1;
   unsigned nothrow_flag : 1;
@@ -180,8 +180,6 @@ struct tree_common GTY(())
 
        TREE_STATIC in
            VAR_DECL, FUNCTION_DECL, CONSTRUCTOR, ADDR_EXPR
-       TREE_NO_UNUSED_WARNING in
-           CONVERT_EXPR, NOP_EXPR, COMPOUND_EXPR
        TREE_VIA_VIRTUAL in
            TREE_LIST or TREE_VEC
        TREE_CONSTANT_OVERFLOW in
@@ -291,6 +289,10 @@ struct tree_common GTY(())
 	TREE_INVARIANT in
 	    all expressions.
 
+   nowarning_flag:
+
+       TREE_NO_WARNING in
+           ... any expr node
 */
 
 /* Define accessors for the fields that all tree nodes have
@@ -603,9 +605,9 @@ extern void tree_operand_check_failed (i
    executed if an exception is thrown, not on normal exit of its scope.  */
 #define CLEANUP_EH_ONLY(NODE) ((NODE)->common.static_flag)
 
-/* In a CONVERT_EXPR, NOP_EXPR or COMPOUND_EXPR, this means the node was
-   made implicitly and should not lead to an "unused value" warning.  */
-#define TREE_NO_UNUSED_WARNING(NODE) ((NODE)->common.static_flag)
+/* In an expr node (usually a conversion) this means the node was made
+   implicitly and should not lead to any sort of warning.  */
+#define TREE_NO_WARNING(NODE) ((NODE)->common.nowarning_flag)
 
 /* Nonzero for a TREE_LIST or TREE_VEC node means that the derivation
    chain is via a `virtual' declaration.  */
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.320.2.41
diff -c -p -d -u -r1.320.2.41 call.c
--- cp/call.c	30 Jan 2004 13:16:12 -0000	1.320.2.41
+++ cp/call.c	4 Feb 2004 02:11:29 -0000
@@ -4561,7 +4561,7 @@ build_over_call (struct z_candidate *can
 	  val = build (MODIFY_EXPR, as_base, to_as_base, arg_as_base);
 	  val = convert_to_void (val, NULL);
 	  val = build (COMPOUND_EXPR, type, val, save_to);
-	  TREE_NO_UNUSED_WARNING (val) = 1;
+	  TREE_NO_WARNING (val) = 1;
 	}
       
       return val;
Index: cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.118.2.20
diff -c -p -d -u -r1.118.2.20 cvt.c
--- cp/cvt.c	3 Jan 2004 23:03:08 -0000	1.118.2.20
+++ cp/cvt.c	4 Feb 2004 02:11:29 -0000
@@ -817,7 +817,7 @@ convert_to_void (tree expr, const char *
         /* The second part of a compound expr contains the value.  */
         tree op1 = TREE_OPERAND (expr,1);
         tree new_op1 = convert_to_void
-	  (op1, (implicit && !TREE_NO_UNUSED_WARNING (expr)
+	  (op1, (implicit && !TREE_NO_WARNING (expr)
 		 ? "right-hand operand of comma" : NULL));
         
         if (new_op1 != op1)
@@ -894,7 +894,8 @@ convert_to_void (tree expr, const char *
   
   if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
     {
-      if (implicit && !TREE_SIDE_EFFECTS (expr) && warn_unused_value)
+      if (implicit && warn_unused_value
+	  && !TREE_SIDE_EFFECTS (expr) && !TREE_NO_WARNING (expr))
 	warning ("%s has no effect", implicit);
       expr = build1 (CONVERT_EXPR, void_type_node, expr);
     }
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.281.2.35
diff -c -p -d -u -r1.281.2.35 init.c
--- cp/init.c	30 Jan 2004 13:16:22 -0000	1.281.2.35
+++ cp/init.c	4 Feb 2004 02:11:30 -0000
@@ -1829,7 +1829,7 @@ build_new (tree placement, tree decl, tr
 
   /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain.  */
   rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
-  TREE_NO_UNUSED_WARNING (rval) = 1;
+  TREE_NO_WARNING (rval) = 1;
 
   return rval;
 }
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.408.2.39
diff -c -p -d -u -r1.408.2.39 typeck.c
--- cp/typeck.c	30 Jan 2004 13:16:31 -0000	1.408.2.39
+++ cp/typeck.c	4 Feb 2004 02:11:30 -0000
@@ -3838,7 +3838,7 @@ build_unary_op (enum tree_code code, tre
 	      compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value);
 
 	      /* Eliminate warning about unused result of + or -.  */
-	      TREE_NO_UNUSED_WARNING (compound) = 1;
+	      TREE_NO_WARNING (compound) = 1;
 	      return compound;
 	    }
 
@@ -4126,7 +4126,7 @@ unary_complex_lvalue (enum tree_code cod
     {
       tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0);
       arg = build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result);
-      TREE_NO_UNUSED_WARNING (arg) = 1;
+      TREE_NO_WARNING (arg) = 1;
       return arg;
     }
 
@@ -5235,7 +5235,7 @@ build_modify_expr (tree lhs, enum tree_c
   if (olhs)
     {
       result = build (COMPOUND_EXPR, olhstype, result, olhs);
-      TREE_NO_UNUSED_WARNING (result) = 1;
+      TREE_NO_WARNING (result) = 1;
       return result;
     }
   return convert_for_assignment (olhstype, result, "assignment",
Index: testsuite/g++.dg/warn/noeffect5.C
===================================================================
RCS file: testsuite/g++.dg/warn/noeffect5.C
diff -N testsuite/g++.dg/warn/noeffect5.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/warn/noeffect5.C	4 Feb 2004 02:11:30 -0000
@@ -0,0 +1,8 @@
+/* PR middle-end/13325 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);
+void f (void *dest, const void *src) {
+    memcpy (dest, src, 0);
+}
Index: testsuite/gcc.dg/20040202-1.c
===================================================================
RCS file: testsuite/gcc.dg/20040202-1.c
diff -N testsuite/gcc.dg/20040202-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/20040202-1.c	4 Feb 2004 02:11:31 -0000
@@ -0,0 +1,8 @@
+/* PR middle-end/13325 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);
+void f (void *dest, const void *src) {
+    memcpy (dest, src, 0);
+}



More information about the Gcc-patches mailing list