Hi,
this one is a bit subtler. It's actually a regression due to the fix for
PR35602, which was about a bogus warning for:
struct c
{
~c();
c();
};
int
main()
{
c x[0UL][0UL] = // { dg-bogus "warning: conversion to .long unsigned
int. from .long int. may change the sign of the result" }
{
};
}
The way we did it, we added a check at the beginning of
c-common.c:conversion_warning:
/* If any operand is artificial, then this expression was generated
by the compiler and we do not warn. */
for (i = 0; i < expr_num_operands; i++)
{
tree op = TREE_OPERAND (expr, i);
if (op && DECL_P (op) && DECL_ARTIFICIAL (op))
return;
}
which catches the artificial (only) operand of the expr (expr is a
BIT_NOT_EXPR and the operand a VAR_DECL).
Now, however, for testcases like PR45385, where member functions are
involved, we easily fail to produce warnings, simply because the this
pointer is artificial! Thus I had the idea of restricting the above
check to the single operand case which matters for PR35602: for sure
it's a safe change, and passes the testsuite, but I cannot exclude that
more complex situations can occur for which the loop would avoid more
bogus warnings... What do you think, is the change good enough for now?
Thanks,
Paolo.
////////////////////
/c-family
2011-10-21 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/45385
* c-common.c (conversion_warning): Early return only if the
only operand is DECL_ARTIFICIAL.
testsuite/
2011-10-21 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/45385
* g++.dg/warn/Wconversion4.C: New.
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c (revision 180288)
+++ c-family/c-common.c (working copy)
@@ -2121,19 +2121,17 @@ unsafe_conversion_p (tree type, tree expr, bool pr
static void
conversion_warning (tree type, tree expr)
{
- int i;
- const int expr_num_operands = TREE_OPERAND_LENGTH (expr);
tree expr_type = TREE_TYPE (expr);
location_t loc = EXPR_LOC_OR_HERE (expr);
if (!warn_conversion && !warn_sign_conversion)
return;
- /* If any operand is artificial, then this expression was generated
- by the compiler and we do not warn. */
- for (i = 0; i < expr_num_operands; i++)
+ /* If the only operand is artificial, then the expression was generated
+ by the compiler and we do not warn. ???? */
+ if (TREE_OPERAND_LENGTH (expr) == 1)
{
- tree op = TREE_OPERAND (expr, i);
+ tree op = TREE_OPERAND (expr, 0);
if (op && DECL_P (op) && DECL_ARTIFICIAL (op))
return;
}
Index: testsuite/g++.dg/warn/Wconversion4.C
===================================================================
--- testsuite/g++.dg/warn/Wconversion4.C (revision 0)
+++ testsuite/g++.dg/warn/Wconversion4.C (revision 0)
@@ -0,0 +1,17 @@
+// PR c++/45385
+// { dg-options "-Wconversion" }
+
+void foo(unsigned char);
+
+class Test
+{
+ void eval()
+ {
+ foo(bar()); // { dg-warning "may alter its value" }
+ }
+
+ unsigned int bar() const
+ {
+ return __INT_MAX__ * 2U + 1;
+ }
+};