aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cvt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/cvt.c')
-rw-r--r--gcc/cp/cvt.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 2d73ab8..64db100 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -909,9 +909,43 @@ convert_to_void (tree expr, const char *implicit)
if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
{
- if (implicit && warn_unused_value
- && !TREE_SIDE_EFFECTS (expr) && !TREE_NO_WARNING (expr))
- warning ("%s has no effect", implicit);
+ if (implicit && warn_unused_value && !TREE_NO_WARNING (expr))
+ {
+ /* The middle end does not warn about expressions that have
+ been explicitly cast to void, so we must do so here. */
+ if (!TREE_SIDE_EFFECTS (expr))
+ warning ("%s has no effect", implicit);
+ else
+ {
+ tree e;
+ enum tree_code code;
+ enum tree_code_class class;
+
+ e = expr;
+ /* We might like to warn about (say) "(int) f()", as the
+ cast has no effect, but the compiler itself will
+ generate implicit conversions under some
+ circmstances. (For example a block copy will be
+ turned into a call to "__builtin_memcpy", with a
+ conversion of the return value to an appropriate
+ type.) So, to avoid false positives, we strip
+ conversions. */
+ STRIP_NOPS (e);
+
+ code = TREE_CODE (e);
+ class = TREE_CODE_CLASS (code);
+ if (class == tcc_comparison
+ || class == tcc_unary
+ || (class == tcc_binary
+ && !(code == MODIFY_EXPR
+ || code == INIT_EXPR
+ || code == PREDECREMENT_EXPR
+ || code == PREINCREMENT_EXPR
+ || code == POSTDECREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)))
+ warning ("value computed is not used");
+ }
+ }
expr = build1 (CONVERT_EXPR, void_type_node, expr);
}
return expr;