From deef71132774618d06d571e935d10753f92d8ad9 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 4 May 2016 16:00:33 +0000 Subject: [PATCH] c.opt (Wdangling-else): New option. * c.opt (Wdangling-else): New option. * c-parser.c (c_parser_if_statement): Replace OPT_Wparentheses with OPT_Wdangling_else. * parser.c (cp_parser_selection_statement): Replace OPT_Wparentheses with OPT_Wdangling_else. * doc/invoke.texi: Document -Wdangling-else. * c-c++-common/Wdangling-else-1.c: New test. * c-c++-common/Wdangling-else-2.c: New test. * c-c++-common/Wdangling-else-3.c: New test. From-SVN: r235885 --- gcc/ChangeLog | 4 + gcc/c-family/ChangeLog | 4 + gcc/c-family/c.opt | 4 + gcc/c/ChangeLog | 5 ++ gcc/c/c-parser.c | 2 +- gcc/cp/ChangeLog | 5 ++ gcc/cp/parser.c | 2 +- gcc/doc/invoke.texi | 88 ++++++++++--------- gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/c-c++-common/Wdangling-else-1.c | 13 +++ gcc/testsuite/c-c++-common/Wdangling-else-2.c | 13 +++ gcc/testsuite/c-c++-common/Wdangling-else-3.c | 13 +++ 12 files changed, 116 insertions(+), 43 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wdangling-else-1.c create mode 100644 gcc/testsuite/c-c++-common/Wdangling-else-2.c create mode 100644 gcc/testsuite/c-c++-common/Wdangling-else-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c99daeb457f..17390ab7471 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2016-05-04 Marek Polacek + + * doc/invoke.texi: Document -Wdangling-else. + 2016-05-04 Thomas Preud'homme * config.gcc: Error out when conflicting multilib is detected. Do not diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 09a72e39e86..e1ba43945c6 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2016-05-04 Marek Polacek + + * c.opt (Wdangling-else): New option. + 2016-05-03 Marek Polacek PR c/70859 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 05bfa7cbc6f..bdc6ee0f83b 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -370,6 +370,10 @@ Wctor-dtor-privacy C++ ObjC++ Var(warn_ctor_dtor_privacy) Warning Warn when all constructors and destructors are private. +Wdangling-else +C ObjC C++ ObjC++ Var(warn_dangling_else) Warning LangEnabledBy(C ObjC C++ ObjC++,Wparentheses) +Warn about dangling else. + Wdate-time C ObjC C++ ObjC++ CPP(warn_date_time) CppReason(CPP_W_DATE_TIME) Var(cpp_warn_date_time) Init(0) Warning Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage. diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 517a8c6c02e..1e77ef5e40f 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2016-05-04 Marek Polacek + + * c-parser.c (c_parser_if_statement): Replace OPT_Wparentheses with + OPT_Wdangling_else. + 2016-05-04 Marek Polacek PR c/48778 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 701ab45ff89..d275f8ef594 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -5542,7 +5542,7 @@ c_parser_if_statement (c_parser *parser, bool *if_p, vec *chain) /* Diagnose an ambiguous else if if-then-else is nested inside if-then. */ if (nested_if) - warning_at (loc, OPT_Wparentheses, + warning_at (loc, OPT_Wdangling_else, "suggest explicit braces to avoid ambiguous %"); if (warn_duplicated_cond) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b7375189214..74df11011fc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2016-05-04 Marek Polacek + + * parser.c (cp_parser_selection_statement): Replace OPT_Wparentheses + with OPT_Wdangling_else. + 2016-05-03 Martin Sebor PR c++/66561 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c4941a05996..da2ee3cf1dc 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10951,7 +10951,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p, statement which does have an else clause. We warn about the potential ambiguity. */ if (nested_if) - warning_at (EXPR_LOCATION (statement), OPT_Wparentheses, + warning_at (EXPR_LOCATION (statement), OPT_Wdangling_else, "suggest explicit braces to avoid ambiguous" " %"); if (warn_duplicated_cond) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 46729db7ac5..96df18e4c31 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -257,7 +257,8 @@ Objective-C and Objective-C++ Dialects}. -Wc90-c99-compat -Wc99-c11-compat @gol -Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol -Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol --Wconversion -Wcoverage-mismatch -Wno-cpp -Wdate-time -Wdelete-incomplete @gol +-Wconversion -Wcoverage-mismatch -Wno-cpp -Wdangling-else -Wdate-time @gol +-Wdelete-incomplete @gol -Wno-deprecated -Wno-deprecated-declarations -Wno-designated-init @gol -Wdisabled-optimization @gol -Wno-discarded-qualifiers -Wno-discarded-array-qualifiers @gol @@ -3976,46 +3977,6 @@ Also warn if a comparison like @code{x<=y<=z} appears; this is equivalent to @code{(x<=y ? 1 : 0) <= z}, which is a different interpretation from that of ordinary mathematical notation. -Also warn about constructions where there may be confusion to which -@code{if} statement an @code{else} branch belongs. Here is an example of -such a case: - -@smallexample -@group -@{ - if (a) - if (b) - foo (); - else - bar (); -@} -@end group -@end smallexample - -In C/C++, every @code{else} branch belongs to the innermost possible -@code{if} statement, which in this example is @code{if (b)}. This is -often not what the programmer expected, as illustrated in the above -example by indentation the programmer chose. When there is the -potential for this confusion, GCC issues a warning when this flag -is specified. To eliminate the warning, add explicit braces around -the innermost @code{if} statement so there is no way the @code{else} -can belong to the enclosing @code{if}. The resulting code -looks like this: - -@smallexample -@group -@{ - if (a) - @{ - if (b) - foo (); - else - bar (); - @} -@} -@end group -@end smallexample - Also warn for dangerous uses of the GNU extension to @code{?:} with omitted middle operand. When the condition in the @code{?}: operator is a boolean expression, the omitted value is @@ -5148,6 +5109,51 @@ compiler doesn't give this warning for types defined in the main .C file, as those are unlikely to have multiple definitions. @option{-Wsubobject-linkage} is enabled by default. +@item -Wdangling-else +@opindex Wdangling-else +@opindex Wno-dangling-else +Warn about constructions where there may be confusion to which +@code{if} statement an @code{else} branch belongs. Here is an example of +such a case: + +@smallexample +@group +@{ + if (a) + if (b) + foo (); + else + bar (); +@} +@end group +@end smallexample + +In C/C++, every @code{else} branch belongs to the innermost possible +@code{if} statement, which in this example is @code{if (b)}. This is +often not what the programmer expected, as illustrated in the above +example by indentation the programmer chose. When there is the +potential for this confusion, GCC issues a warning when this flag +is specified. To eliminate the warning, add explicit braces around +the innermost @code{if} statement so there is no way the @code{else} +can belong to the enclosing @code{if}. The resulting code +looks like this: + +@smallexample +@group +@{ + if (a) + @{ + if (b) + foo (); + else + bar (); + @} +@} +@end group +@end smallexample + +This warning is enabled by @option{-Wparentheses}. + @item -Wdate-time @opindex Wdate-time @opindex Wno-date-time diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 06a1f0766f7..fdf961d72ff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-05-04 Marek Polacek + + * c-c++-common/Wdangling-else-1.c: New test. + * c-c++-common/Wdangling-else-2.c: New test. + * c-c++-common/Wdangling-else-3.c: New test. + 2016-05-04 Kwok Cheung Yeung * gcc.target/mips/mips16-attributes.c: Skip if -mmicromips diff --git a/gcc/testsuite/c-c++-common/Wdangling-else-1.c b/gcc/testsuite/c-c++-common/Wdangling-else-1.c new file mode 100644 index 00000000000..28a5a8f53fb --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wdangling-else-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Wdangling-else" } */ + +void bar (int); +void +foo (int a, int b) +{ + if (a) /* { dg-warning "suggest explicit braces to avoid ambiguous" } */ + if (b) + bar (1); + else + bar (2); +} diff --git a/gcc/testsuite/c-c++-common/Wdangling-else-2.c b/gcc/testsuite/c-c++-common/Wdangling-else-2.c new file mode 100644 index 00000000000..87ea1ab5687 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wdangling-else-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Wparentheses" } */ + +void bar (int); +void +foo (int a, int b) +{ + if (a) /* { dg-warning "suggest explicit braces to avoid ambiguous" } */ + if (b) + bar (1); + else + bar (2); +} diff --git a/gcc/testsuite/c-c++-common/Wdangling-else-3.c b/gcc/testsuite/c-c++-common/Wdangling-else-3.c new file mode 100644 index 00000000000..0dae0d54ec8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wdangling-else-3.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Wparentheses -Wno-dangling-else" } */ + +void bar (int); +void +foo (int a, int b) +{ + if (a) /* { dg-bogus "suggest explicit braces to avoid ambiguous" } */ + if (b) + bar (1); + else + bar (2); +} -- 2.30.2