From 60a0513e1edb1f19485faf0a68810f49bf7f3d2b Mon Sep 17 00:00:00 2001 From: ian Date: Tue, 2 Jan 2007 17:49:07 +0000 Subject: [PATCH] ./: * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120348 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 ++ gcc/c-common.c | 12 ++- gcc/cp/ChangeLog | 7 ++ gcc/cp/semantics.c | 12 ++- gcc/cp/typeck.c | 14 +++- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/warn/Wparentheses-22.C | 111 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/warn/Wparentheses-23.C | 121 ++++++++++++++++++++++++++++ 8 files changed, 281 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wparentheses-22.C create mode 100644 gcc/testsuite/g++.dg/warn/Wparentheses-23.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78b8ce8..30e9a20 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2006-01-02 Ian Lance Taylor + + * 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 PR middle-end/7651 diff --git a/gcc/c-common.c b/gcc/c-common.c index 0658141..cca1490 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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: diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 16da3ee..abc7a71 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2006-01-02 Ian Lance Taylor + + * 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 * pt.c (canonical_template_parms): Correct typo in comment. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 41d2be9..5b8906e 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7e8b785b..6c05b9f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e2e3d3d..5f17a94 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-01-02 Ian Lance Taylor + + * g++.dg/warn/Wparentheses-22.C: New test. + * g++.dg/warn/Wparentheses-23.C: New test. + 2007-01-02 Manuel Lopez-Ibanez PR middle-end/7651 diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-22.C b/gcc/testsuite/g++.dg/warn/Wparentheses-22.C new file mode 100644 index 0000000..395953d --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-22.C @@ -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); +} diff --git a/gcc/testsuite/g++.dg/warn/Wparentheses-23.C b/gcc/testsuite/g++.dg/warn/Wparentheses-23.C new file mode 100644 index 0000000..755c574 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wparentheses-23.C @@ -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 +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 +bool +bar1 (T) +{ + return a = b; // { dg-warning "assignment" "correct warning" } +} + +template +bool +bar2 (T) +{ + return (a = b); +} + +template +bool +bar3 (T) +{ + return a = a; // { dg-warning "assignment" "correct warning" } +} + +template +bool +bar4 (T) +{ + return (a = a); +} + +template void bar (int); // { dg-warning "instantiated" } +template bool bar1 (int); // { dg-warning "instantiated" } +template bool bar2 (int); +template bool bar3 (int); // { dg-warning "instantiated" } +template bool bar4 (int); -- 2.7.4