This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] fix middle-end/13325
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 3 Feb 2004 18:30:37 -0800
- Subject: [tree-ssa] fix middle-end/13325
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);
+}