c-common.c (c_common_truthvalue_conversion): When warning about using an assignment as a truth value, set TREE_NO_WARNING.

./:	* c-common.c (c_common_truthvalue_conversion): When warning about
	using an assignment as a truth value, set TREE_NO_WARNING.
cp/:
	* semantics.c (maybe_convert_cond): Optionally warn when using an
	assignment as a condition.
	* typeck.c (convert_for_assignment): Optionally warn about
	assigning the result of an assignment to a bool.
testsuite/:
	* g++.dg/warn/Wparentheses-22.C: New test.
	* g++.dg/warn/Wparentheses-23.C: New test.

From-SVN: r120348
This commit is contained in:
Ian Lance Taylor 2007-01-02 17:49:07 +00:00 committed by Ian Lance Taylor
parent b1ed4cb43c
commit fbc8d2d30e
8 changed files with 281 additions and 6 deletions

View file

@ -1,3 +1,8 @@
2006-01-02 Ian Lance Taylor <iant@google.com>
* c-common.c (c_common_truthvalue_conversion): When warning about
using an assignment as a truth value, set TREE_NO_WARNING.
2007-01-02 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR middle-end/7651

View file

@ -1,6 +1,6 @@
/* Subroutines shared by all languages that are variants of C.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
@ -2726,9 +2726,13 @@ c_common_truthvalue_conversion (tree expr)
break;
case MODIFY_EXPR:
if (!TREE_NO_WARNING (expr))
warning (OPT_Wparentheses,
"suggest parentheses around assignment used as truth value");
if (!TREE_NO_WARNING (expr)
&& warn_parentheses)
{
warning (OPT_Wparentheses,
"suggest parentheses around assignment used as truth value");
TREE_NO_WARNING (expr) = 1;
}
break;
default:

View file

@ -1,3 +1,10 @@
2006-01-02 Ian Lance Taylor <iant@google.com>
* semantics.c (maybe_convert_cond): Optionally warn when using an
assignment as a condition.
* typeck.c (convert_for_assignment): Optionally warn about
assigning the result of an assignment to a bool.
2007-01-02 Douglas Gregor <doug.gregor@gmail.com>
* pt.c (canonical_template_parms): Correct typo in comment.

View file

@ -3,7 +3,7 @@
building RTL. These routines are used both during actual parsing
and during the instantiation of template functions.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Written by Mark Mitchell (mmitchell@usa.net) based on code found
formerly in parse.y and pt.c.
@ -587,6 +587,16 @@ maybe_convert_cond (tree cond)
/* Do the conversion. */
cond = convert_from_reference (cond);
if (TREE_CODE (cond) == MODIFY_EXPR
&& !TREE_NO_WARNING (cond)
&& warn_parentheses)
{
warning (OPT_Wparentheses,
"suggest parentheses around assignment used as truth value");
TREE_NO_WARNING (cond) = 1;
}
return condition_conversion (cond);
}

View file

@ -1,6 +1,7 @@
/* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
@ -6365,6 +6366,17 @@ convert_for_assignment (tree type, tree rhs,
errtype);
}
/* If -Wparentheses, warn about a = b = c when a has type bool. */
if (warn_parentheses
&& type == boolean_type_node
&& TREE_CODE (rhs) == MODIFY_EXPR
&& !TREE_NO_WARNING (rhs))
{
warning (OPT_Wparentheses,
"suggest parentheses around assignment used as truth value");
TREE_NO_WARNING (rhs) = 1;
}
return perform_implicit_conversion (strip_top_quals (type), rhs);
}

View file

@ -1,3 +1,8 @@
2006-01-02 Ian Lance Taylor <iant@google.com>
* g++.dg/warn/Wparentheses-22.C: New test.
* g++.dg/warn/Wparentheses-23.C: New test.
2007-01-02 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR middle-end/7651

View file

@ -0,0 +1,111 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Warnings for assignments used as truth-values when using classes.
// Like Wparentheses-1.C, but with a class.
int foo (int);
class C
{
public:
C()
: b(0)
{ }
// Use default assignment constructor.
// Provide conversion to bool so that an instance of this class will
// work as a condition.
operator bool() const
{ return b != 0; }
private:
int b;
};
C a, b, c;
bool d;
void
bar (void)
{
if (a = b) // { dg-warning "assignment" "correct warning" }
foo (0);
if ((a = b))
foo (1);
if (a = a) // { dg-warning "assignment" "correct warning" }
foo (2);
if ((a = a))
foo (3);
if (b = c) // { dg-warning "assignment" "correct warning" }
foo (4);
else
foo (5);
if ((b = c))
foo (6);
else
foo (7);
if (b = b) // { dg-warning "assignment" "correct warning" }
foo (8);
else
foo (9);
if ((b = b))
foo (10);
else
foo (11);
while (c = b) // { dg-warning "assignment" "correct warning" }
foo (12);
while ((c = b))
foo (13);
while (c = c) // { dg-warning "assignment" "correct warning" }
foo (14);
while ((c = c))
foo (15);
do foo (16); while (a = b); // { dg-warning "assignment" "correct warning" }
do foo (17); while ((a = b));
do foo (18); while (a = a); // { dg-warning "assignment" "correct warning" }
do foo (19); while ((a = a));
for (;c = b;) // { dg-warning "assignment" "correct warning" }
foo (20);
for (;(c = b);)
foo (21);
for (;c = c;) // { dg-warning "assignment" "correct warning" }
foo (22);
for (;(c = c);)
foo (23);
d = a = b; // { dg-warning "assignment" "correct warning" }
foo (24);
d = (a = b);
foo (25);
d = a = a; // { dg-warning "assignment" "correct warning" }
foo (26);
d = (a = a);
foo (27);
if (C(a))
foo (28);
}
bool
bar1 (void)
{
return a = b; // { dg-warning "assignment" "correct warning" }
}
bool
bar2 (void)
{
return (a = b);
}
bool
bar3 (void)
{
return a = a; // { dg-warning "assignment" "correct warning" }
}
bool
bar4 (void)
{
return (a = a);
}

View file

@ -0,0 +1,121 @@
// { dg-do compile }
// { dg-options "-Wparentheses" }
// Template version of Wparentheses-22.C.
int foo (int);
class C
{
public:
C()
: b(0)
{ }
// Use default assignment constructor.
// Provide conversion to bool so that an instance of this class will
// work as a condition.
operator bool() const
{ return b != 0; }
private:
int b;
};
C a, b, c;
bool d;
template<class T>
void
bar (T)
{
if (a = b) // { dg-warning "assignment" "correct warning" }
foo (0);
if ((a = b))
foo (1);
if (a = a) // { dg-warning "assignment" "correct warning" }
foo (2);
if ((a = a))
foo (3);
if (b = c) // { dg-warning "assignment" "correct warning" }
foo (4);
else
foo (5);
if ((b = c))
foo (6);
else
foo (7);
if (b = b) // { dg-warning "assignment" "correct warning" }
foo (8);
else
foo (9);
if ((b = b))
foo (10);
else
foo (11);
while (c = b) // { dg-warning "assignment" "correct warning" }
foo (12);
while ((c = b))
foo (13);
while (c = c) // { dg-warning "assignment" "correct warning" }
foo (14);
while ((c = c))
foo (15);
do foo (16); while (a = b); // { dg-warning "assignment" "correct warning" }
do foo (17); while ((a = b));
do foo (18); while (a = a); // { dg-warning "assignment" "correct warning" }
do foo (19); while ((a = a));
for (;c = b;) // { dg-warning "assignment" "correct warning" }
foo (20);
for (;(c = b);)
foo (21);
for (;c = c;) // { dg-warning "assignment" "correct warning" }
foo (22);
for (;(c = c);)
foo (23);
d = a = b; // { dg-warning "assignment" "correct warning" }
foo (24);
d = (a = b);
foo (25);
d = a = a; // { dg-warning "assignment" "correct warning" }
foo (26);
d = (a = a);
foo (27);
if (C(a))
foo (28);
}
template<class T>
bool
bar1 (T)
{
return a = b; // { dg-warning "assignment" "correct warning" }
}
template<class T>
bool
bar2 (T)
{
return (a = b);
}
template<class T>
bool
bar3 (T)
{
return a = a; // { dg-warning "assignment" "correct warning" }
}
template<class T>
bool
bar4 (T)
{
return (a = a);
}
template void bar<int> (int); // { dg-warning "instantiated" }
template bool bar1<int> (int); // { dg-warning "instantiated" }
template bool bar2<int> (int);
template bool bar3<int> (int); // { dg-warning "instantiated" }
template bool bar4<int> (int);