re PR c/64279 (Warning missing for "(cond) ? A : A" / if(cond) expr1; else expr1; // same expression in if and else branch)

PR c/64279
	* c-common.h (do_warn_duplicated_branches_r): Declare.
	* c-gimplify.c (c_genericize): Walk the function tree calling
	do_warn_duplicated_branches_r.
	* c-warn.c (expr_from_macro_expansion_r): New.
	(do_warn_duplicated_branches): New.
	(do_warn_duplicated_branches_r): New.
	* c.opt (Wduplicated-branches): New option.

	* c-typeck.c (build_conditional_expr): Warn about duplicated branches.

	* call.c (build_conditional_expr_1): Warn about duplicated branches.
	* semantics.c (finish_expr_stmt): Build statement using the proper
	location.

	* doc/invoke.texi: Document -Wduplicated-branches.
	* fold-const.c (operand_equal_p): Handle MODIFY_EXPR, INIT_EXPR,
	COMPOUND_EXPR, PREDECREMENT_EXPR, PREINCREMENT_EXPR,
	POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, CLEANUP_POINT_EXPR, EXPR_STMT,
	STATEMENT_LIST, and RETURN_EXPR.  For non-pure non-const functions
	return 0 only when not OEP_LEXICOGRAPHIC.
	(fold_build_cleanup_point_expr): Use the expression
	location when building CLEANUP_POINT_EXPR.
	* tree-core.h (enum operand_equal_flag): Add OEP_LEXICOGRAPHIC.
	* tree.c (add_expr): Handle error_mark_node.

	* c-c++-common/Wduplicated-branches-1.c: New test.
	* c-c++-common/Wduplicated-branches-10.c: New test.
	* c-c++-common/Wduplicated-branches-11.c: New test.
	* c-c++-common/Wduplicated-branches-12.c: New test.
	* c-c++-common/Wduplicated-branches-2.c: New test.
	* c-c++-common/Wduplicated-branches-3.c: New test.
	* c-c++-common/Wduplicated-branches-4.c: New test.
	* c-c++-common/Wduplicated-branches-5.c: New test.
	* c-c++-common/Wduplicated-branches-6.c: New test.
	* c-c++-common/Wduplicated-branches-7.c: New test.
	* c-c++-common/Wduplicated-branches-8.c: New test.
	* c-c++-common/Wduplicated-branches-9.c: New test.
	* c-c++-common/Wimplicit-fallthrough-7.c: Coalesce dg-warning.
	* g++.dg/cpp0x/lambda/lambda-switch.C: Move dg-warning.
	* g++.dg/ext/builtin-object-size3.C: Likewise.
	* g++.dg/gomp/loop-1.C: Likewise.
	* g++.dg/warn/Wduplicated-branches1.C: New test.
	* g++.dg/warn/Wduplicated-branches2.C: New test.

From-SVN: r244705
This commit is contained in:
Marek Polacek 2017-01-20 12:02:50 +00:00 committed by Marek Polacek
parent 6e9e35e127
commit 2ebd93e1d7
34 changed files with 925 additions and 17 deletions

View file

@ -1,3 +1,17 @@
2017-01-20 Marek Polacek <polacek@redhat.com>
PR c/64279
* doc/invoke.texi: Document -Wduplicated-branches.
* fold-const.c (operand_equal_p): Handle MODIFY_EXPR, INIT_EXPR,
COMPOUND_EXPR, PREDECREMENT_EXPR, PREINCREMENT_EXPR,
POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, CLEANUP_POINT_EXPR, EXPR_STMT,
STATEMENT_LIST, and RETURN_EXPR. For non-pure non-const functions
return 0 only when not OEP_LEXICOGRAPHIC.
(fold_build_cleanup_point_expr): Use the expression
location when building CLEANUP_POINT_EXPR.
* tree-core.h (enum operand_equal_flag): Add OEP_LEXICOGRAPHIC.
* tree.c (add_expr): Handle error_mark_node.
2017-01-20 Martin Liska <mliska@suse.cz>
PR lto/69188

View file

@ -1,3 +1,14 @@
2017-01-20 Marek Polacek <polacek@redhat.com>
PR c/64279
* c-common.h (do_warn_duplicated_branches_r): Declare.
* c-gimplify.c (c_genericize): Walk the function tree calling
do_warn_duplicated_branches_r.
* c-warn.c (expr_from_macro_expansion_r): New.
(do_warn_duplicated_branches): New.
(do_warn_duplicated_branches_r): New.
* c.opt (Wduplicated-branches): New option.
2017-01-17 David Malcolm <dmalcolm@redhat.com>
PR c++/71497

View file

@ -1537,6 +1537,7 @@ extern void maybe_warn_bool_compare (location_t, enum tree_code, tree, tree);
extern bool maybe_warn_shift_overflow (location_t, tree, tree);
extern void warn_duplicated_cond_add_or_warn (location_t, tree, vec<tree> **);
extern bool diagnose_mismatched_attributes (tree, tree);
extern tree do_warn_duplicated_branches_r (tree *, int *, void *);
/* In c-attribs.c. */
extern bool attribute_takes_identifier_p (const_tree);

View file

@ -125,6 +125,10 @@ c_genericize (tree fndecl)
&pset);
}
if (warn_duplicated_branches)
walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
do_warn_duplicated_branches_r, NULL);
/* Dump the C-specific tree IR. */
dump_orig = get_dump_info (TDI_original, &local_dump_flags);
if (dump_orig)

View file

@ -2217,3 +2217,73 @@ warn_for_restrict (unsigned param_pos, vec<tree, va_gc> *args)
free (arg_positions);
}
/* Callback function to determine whether an expression TP or one of its
subexpressions comes from macro expansion. Used to suppress bogus
warnings. */
static tree
expr_from_macro_expansion_r (tree *tp, int *, void *)
{
if (CAN_HAVE_LOCATION_P (*tp)
&& from_macro_expansion_at (EXPR_LOCATION (*tp)))
return integer_zero_node;
return NULL_TREE;
}
/* Possibly warn when an if-else has identical branches. */
static void
do_warn_duplicated_branches (tree expr)
{
tree thenb = COND_EXPR_THEN (expr);
tree elseb = COND_EXPR_ELSE (expr);
/* Don't bother if there's no else branch. */
if (elseb == NULL_TREE)
return;
/* And don't warn for empty statements. */
if (TREE_CODE (thenb) == NOP_EXPR
&& TREE_TYPE (thenb) == void_type_node
&& TREE_OPERAND (thenb, 0) == size_zero_node)
return;
/* ... or empty branches. */
if (TREE_CODE (thenb) == STATEMENT_LIST
&& STATEMENT_LIST_HEAD (thenb) == NULL)
return;
/* Compute the hash of the then branch. */
inchash::hash hstate0 (0);
inchash::add_expr (thenb, hstate0);
hashval_t h0 = hstate0.end ();
/* Compute the hash of the else branch. */
inchash::hash hstate1 (0);
inchash::add_expr (elseb, hstate1);
hashval_t h1 = hstate1.end ();
/* Compare the hashes. */
if (h0 == h1
&& operand_equal_p (thenb, elseb, OEP_LEXICOGRAPHIC)
/* Don't warn if any of the branches or their subexpressions comes
from a macro. */
&& !walk_tree_without_duplicates (&thenb, expr_from_macro_expansion_r,
NULL)
&& !walk_tree_without_duplicates (&elseb, expr_from_macro_expansion_r,
NULL))
warning_at (EXPR_LOCATION (expr), OPT_Wduplicated_branches,
"this condition has identical branches");
}
/* Callback for c_genericize to implement -Wduplicated-branches. */
tree
do_warn_duplicated_branches_r (tree *tp, int *, void *)
{
if (TREE_CODE (*tp) == COND_EXPR)
do_warn_duplicated_branches (*tp);
return NULL_TREE;
}

View file

@ -468,6 +468,10 @@ Wdiv-by-zero
C ObjC C++ ObjC++ Var(warn_div_by_zero) Init(1) Warning
Warn about compile-time integer division by zero.
Wduplicated-branches
C ObjC C++ ObjC++ Var(warn_duplicated_branches) Init(0) Warning
Warn about duplicated branches in if-else statements.
Wduplicated-cond
C ObjC C++ ObjC++ Var(warn_duplicated_cond) Init(0) Warning
Warn about duplicated conditions in an if-else-if chain.

View file

@ -1,3 +1,8 @@
2017-01-20 Marek Polacek <polacek@redhat.com>
PR c/64279
* c-typeck.c (build_conditional_expr): Warn about duplicated branches.
2017-01-13 Richard Biener <rguenther@suse.de>
* gimple-parser.c (c_parser_gimple_compound_statement): Handle

View file

@ -5193,6 +5193,15 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret);
protected_set_expr_location (ret, colon_loc);
/* If the OP1 and OP2 are the same and don't have side-effects,
warn here, because the COND_EXPR will be turned into OP1. */
if (warn_duplicated_branches
&& TREE_CODE (ret) == COND_EXPR
&& (op1 == op2 || operand_equal_p (op1, op2, 0)))
warning_at (EXPR_LOCATION (ret), OPT_Wduplicated_branches,
"this condition has identical branches");
return ret;
}

View file

@ -1,3 +1,10 @@
2017-01-20 Marek Polacek <polacek@redhat.com>
PR c/64279
* call.c (build_conditional_expr_1): Warn about duplicated branches.
* semantics.c (finish_expr_stmt): Build statement using the proper
location.
2017-01-19 Jason Merrill <jason@redhat.com>
US 20 - forwarding references and class template argument deduction

View file

@ -5302,6 +5302,13 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
valid_operands:
result = build3_loc (loc, COND_EXPR, result_type, arg1, arg2, arg3);
/* If the ARG2 and ARG3 are the same and don't have side-effects,
warn here, because the COND_EXPR will be turned into ARG2. */
if (warn_duplicated_branches
&& (arg2 == arg3 || operand_equal_p (arg2, arg3, 0)))
warning_at (EXPR_LOCATION (result), OPT_Wduplicated_branches,
"this condition has identical branches");
/* We can't use result_type below, as fold might have returned a
throw_expr. */

View file

@ -670,6 +670,7 @@ tree
finish_expr_stmt (tree expr)
{
tree r = NULL_TREE;
location_t loc = EXPR_LOCATION (expr);
if (expr != NULL_TREE)
{
@ -694,7 +695,7 @@ finish_expr_stmt (tree expr)
if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
{
if (TREE_CODE (expr) != EXPR_STMT)
expr = build_stmt (input_location, EXPR_STMT, expr);
expr = build_stmt (loc, EXPR_STMT, expr);
expr = maybe_cleanup_point_expr_void (expr);
}

View file

@ -3734,7 +3734,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
-Warray-bounds=1 @r{(only with} @option{-O2}@r{)} @gol
-Wbool-compare @gol
-Wbool-operation @gol
-Wc++11-compat -Wc++14-compat@gol
-Wc++11-compat -Wc++14-compat @gol
-Wchar-subscripts @gol
-Wcomment @gol
-Wduplicate-decl-specifier @r{(C and Objective-C only)} @gol
@ -5263,6 +5263,22 @@ Incrementing a boolean is invalid in C++1z, and deprecated otherwise.)
This warning is enabled by @option{-Wall}.
@item -Wduplicated-branches
@opindex Wno-duplicated-branches
@opindex Wduplicated-branches
Warn when an if-else has identical branches. This warning detects cases like
@smallexample
if (p != NULL)
return 0;
else
return 0;
@end smallexample
It doesn't warn when both branches contain just a null statement. This warning
also warn for conditional operators:
@smallexample
int i = x ? *p : *p;
@end smallexample
@item -Wduplicated-cond
@opindex Wno-duplicated-cond
@opindex Wduplicated-cond

View file

@ -2722,6 +2722,9 @@ combine_comparisons (location_t loc,
If OEP_ADDRESS_OF is set, we are actually comparing addresses of objects,
not values of expressions.
If OEP_LEXICOGRAPHIC is set, then also handle expressions with side-effects
such as MODIFY_EXPR, RETURN_EXPR, as well as STATEMENT_LISTs.
Unless OEP_MATCH_SIDE_EFFECTS is set, the function returns false on
any operand with side effect. This is unnecesarily conservative in the
case we know that arg0 and arg1 are in disjoint code paths (such as in
@ -3154,6 +3157,23 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case BIT_INSERT_EXPR:
return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
case MODIFY_EXPR:
case INIT_EXPR:
case COMPOUND_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
if (flags & OEP_LEXICOGRAPHIC)
return OP_SAME (0) && OP_SAME (1);
return 0;
case CLEANUP_POINT_EXPR:
case EXPR_STMT:
if (flags & OEP_LEXICOGRAPHIC)
return OP_SAME (0);
return 0;
default:
return 0;
}
@ -3190,7 +3210,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
cef &= ECF_CONST | ECF_PURE;
else
cef &= ECF_CONST;
if (!cef)
if (!cef && !(flags & OEP_LEXICOGRAPHIC))
return 0;
}
@ -3269,8 +3289,39 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
}
return 1;
}
else if (TREE_CODE (arg0) == STATEMENT_LIST
&& (flags & OEP_LEXICOGRAPHIC))
{
/* Compare the STATEMENT_LISTs. */
tree_stmt_iterator tsi1, tsi2;
tree body1 = CONST_CAST_TREE (arg0);
tree body2 = CONST_CAST_TREE (arg1);
for (tsi1 = tsi_start (body1), tsi2 = tsi_start (body2); ;
tsi_next (&tsi1), tsi_next (&tsi2))
{
/* The lists don't have the same number of statements. */
if (tsi_end_p (tsi1) ^ tsi_end_p (tsi2))
return 0;
if (tsi_end_p (tsi1) && tsi_end_p (tsi2))
return 1;
if (!operand_equal_p (tsi_stmt (tsi1), tsi_stmt (tsi2),
OEP_LEXICOGRAPHIC))
return 0;
}
}
return 0;
case tcc_statement:
switch (TREE_CODE (arg0))
{
case RETURN_EXPR:
if (flags & OEP_LEXICOGRAPHIC)
return OP_SAME_WITH_NULL (0);
return 0;
default:
return 0;
}
default:
return 0;
}
@ -13897,7 +13948,7 @@ fold_build_cleanup_point_expr (tree type, tree expr)
return expr;
}
return build1 (CLEANUP_POINT_EXPR, type, expr);
return build1_loc (EXPR_LOCATION (expr), CLEANUP_POINT_EXPR, type, expr);
}
/* Given a pointer value OP0 and a type TYPE, return a simplified version

View file

@ -1,3 +1,25 @@
2017-01-20 Marek Polacek <polacek@redhat.com>
PR c/64279
* c-c++-common/Wduplicated-branches-1.c: New test.
* c-c++-common/Wduplicated-branches-10.c: New test.
* c-c++-common/Wduplicated-branches-11.c: New test.
* c-c++-common/Wduplicated-branches-12.c: New test.
* c-c++-common/Wduplicated-branches-2.c: New test.
* c-c++-common/Wduplicated-branches-3.c: New test.
* c-c++-common/Wduplicated-branches-4.c: New test.
* c-c++-common/Wduplicated-branches-5.c: New test.
* c-c++-common/Wduplicated-branches-6.c: New test.
* c-c++-common/Wduplicated-branches-7.c: New test.
* c-c++-common/Wduplicated-branches-8.c: New test.
* c-c++-common/Wduplicated-branches-9.c: New test.
* c-c++-common/Wimplicit-fallthrough-7.c: Coalesce dg-warning.
* g++.dg/cpp0x/lambda/lambda-switch.C: Move dg-warning.
* g++.dg/ext/builtin-object-size3.C: Likewise.
* g++.dg/gomp/loop-1.C: Likewise.
* g++.dg/warn/Wduplicated-branches1.C: New test.
* g++.dg/warn/Wduplicated-branches2.C: New test.
2017-01-20 Martin Liska <mliska@suse.cz>
PR lto/69188

View file

@ -0,0 +1,187 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches -O2" } */
extern void foo (int);
extern int g;
extern int a[10];
int
f (int i, int *p)
{
const int j = 0;
if (j == 0)
{
if (i > 10) /* { dg-warning "this condition has identical branches" } */
/* Optimizers can figure out that this is 1. */
*p = j * 2 + 1;
else
*p = 1;
}
if (i)
;
else
;
if (i == 0) /* { dg-warning "this condition has identical branches" } */
return 0;
else
return 0;
if (i == 1) /* { dg-warning "this condition has identical branches" } */
{
g = 10;
}
else
{
g = 10;
}
const char *s;
if (i == 2) /* { dg-warning "this condition has identical branches" } */
s = "foo";
else
s = "foo";
if (i == 3) /* { dg-warning "this condition has identical branches" } */
g = a[i];
else
g = a[i];
if (i == 4) /* { dg-warning "this condition has identical branches" } */
return i ? 1 : g;
else
return i ? 1 : g;
if (i == 5) /* { dg-warning "this condition has identical branches" } */
{
{
{
{
g++;
}
}
}
}
else
{
{
{
{
g++;
}
}
}
}
if (i == 6) /* { dg-warning "this condition has identical branches" } */
g = i * 6;
else
g = i * 6;
/* Don't warn. */
if (i == 7)
g = i / 6;
else
g = 6 / i;
if (i == 8) /* { dg-warning "this condition has identical branches" } */
return i * 8 * i * 8;
else
return 8 * i * 8 * i;
if (i == 9) /* { dg-warning "this condition has identical branches" } */
{
p++;
return *p;
}
else
{
p++;
return *p;
}
/* Don't warn. */
if (i == 10)
return *++p;
else
return ++*p;
if (i == 11) /* { dg-warning "this condition has identical branches" } */
{
foo (6);
}
else
{
foo (6);
}
if (i == 12) /* { dg-warning "this condition has identical branches" } */
{
foo (6 + i), foo (2);
}
else
{
foo (6 + i), foo (2);
}
if (i == 13) /* { dg-warning "this condition has identical branches" } */
p += (g + 1);
else
p += (g + 1);
if (i == 14) /* { dg-warning "this condition has identical branches" } */
{
foo (7);
*p = 0;
foo (9);
}
else
{
foo (7);
*p = 0;
foo (9);
}
if (i == 15) /* { dg-warning "this condition has identical branches" } */
p += (g + (1 + 2));
else
p += (g + (1 + 1 + 1));
if (i == 16) /* { dg-warning "this condition has identical branches" } */
foo (10 + g);
else
foo (g + 10);
if (i == 17) /* { dg-warning "this condition has identical branches" } */
({ foo (i); });
else
({ foo (i); });
if (i == 18)
{
if (i == 19)
{
if (i == 20) /* { dg-warning "this condition has identical branches" } */
foo (++i);
else
foo (++i);
}
}
/* Don't warn. */
if (i == 21)
{
foo (1);
foo (2);
}
else
{
foo (2);
foo (1);
}
return 0;
}

View file

@ -0,0 +1,18 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
#define DEBUG(msg) ;
void
f (int i)
{
if (i > 9)
{
DEBUG ("foo");
}
else
{
DEBUG ("bar");
}
}

View file

@ -0,0 +1,75 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
int
f (int p)
{
if (p == 0)
{
p += 1, ++p;
}
else
{
p -= 1, ++p;
}
if (p == 1)
{
}
else
p++;
if (p == 2)
p++;
else
{
}
if (p == 3)
{
}
else
{
}
if (p == 4)
{
++p;
return p;
}
else
{
p++;
return p;
}
if (p == 5)
++p;
else
p++;
if (p == 6)
{
++p;
++p;
return p;
}
else
{
++p;
return p;
}
if (p == 7)
{
++p;
return p;
}
else
{
++p;
++p;
return p;
}
}

View file

@ -0,0 +1,16 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
void
f (int i)
{
if (i) /* { dg-warning "this condition has identical branches" } */
return 0;
/* { dg-warning ".return. with a value" "" { target c } .-1 } */
/* { dg-error "return-statement with a value" "" { target c++ } .-2 } */
else
return 0;
/* { dg-warning ".return. with a value" "" { target c } .-1 } */
/* { dg-error "return-statement with a value" "" { target c++ } .-2 } */
}

View file

@ -0,0 +1,114 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches -O2" } */
void
f (int *p)
{
if (*p > 0)
{
if (x == 0) /* { dg-error "undeclared|not declared" } */
*p = 5;
else
*p = 6;
}
}
void
f2 (int *p)
{
if (*p > 0)
{
if (*p > 2)
*p = x; /* { dg-error "undeclared|not declared" } */
else
*p = 6;
}
}
void
f3 (int *p)
{
if (*p > 0)
{
if (*p > 2)
*p = 8;
else
*p = x; /* { dg-error "undeclared|not declared" } */
}
}
void
f4 (int *p)
{
if (*p > 0)
{
if (x == 0) /* { dg-error "undeclared|not declared" } */
*p = 5;
else
*p = 6;
}
else
{
if (x == 0) /* { dg-error "not declared" "" { target c++ } } */
*p = 7;
else
*p = 6;
}
}
void
f5 (int *p)
{
if (*p > 0)
{
if (*p > 2)
*p = x; /* { dg-error "undeclared|not declared" } */
else
*p = 6;
}
else
{
if (x == 0) /* { dg-error "not declared" "" { target c++ } } */
*p = 5;
else
*p = 6;
}
}
void
f6 (int *p)
{
if (*p > 0)
{
if (*p > 2)
*p = 8;
else
*p = x; /* { dg-error "undeclared|not declared" } */
}
else
{
if (x == 0) /* { dg-error "not declared" "" { target c++ } } */
*p = 5;
else
*p = 6;
}
}
void
f7 (int i)
{
if (i > 5)
({ x++; }); /* { dg-error "undeclared|not declared" } */
else
({ i++; });
}
void
f8 (int i)
{
if (i > 5)
({ i++; });
else
({ x++; }); /* { dg-error "undeclared|not declared" } */
}

View file

@ -0,0 +1,19 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
extern int *g;
void
f (short int i)
{
if (i == 0) /* { dg-warning "this condition has identical branches" } */
*g = (int) i;
else
*g = (int) i;
if (i == 1)
*g = (unsigned char) i;
else
*g = (signed char) i;
}

View file

@ -0,0 +1,35 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
extern int *g;
extern const int *q;
void
f (int i)
{
int j;
if (i == 0)
for (j = 0; j < 10; j++)
++*g;
else
for (j = 0; j < 10; j++)
++*g;
if (i == 1)
{
int i = 10;
*g = i;
}
else
{
int i = 10;
*g = i;
}
if (i == 3)
q = (const int []){1};
else
q = (const int []){1};
}

View file

@ -0,0 +1,24 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
extern int g;
extern void foo ();
#define A g = i
#define B g = i
#define DOIT() foo()
#define DOIT2() foo()
void
f (int i)
{
if (i == 0)
A;
else
B;
if (i == 1)
DOIT();
else
DOIT2();
}

View file

@ -0,0 +1,12 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
void
f (int i)
{
if (i == 0)
;
else if (i == 1)
;
}

View file

@ -0,0 +1,36 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
struct S
{
int x;
} s;
int a[10];
#define XMEM(R) ((R).x)
#define XSTR(R) ((R).x)
void
f (int i)
{
if (i)
XMEM(s) = 1;
else
XSTR(s) = 1;
if (i) /* { dg-warning "this condition has identical branches" } */
s.x = 1;
else
s.x = 1;
if (i)
XMEM(s) = 1;
else
s.x = 1;
if (i)
s.x = 1;
else
XMEM(s) = 1;
}

View file

@ -0,0 +1,73 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
#define A 5
#define B 5
#define I i
extern int a[10];
extern int g;
int
f (int i)
{
if (i == 1) /* { dg-warning "this condition has identical branches" } */
return a[5];
else
return a[5];
if (i == 2) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
return a[A];
else
return a[5];
if (i == 3) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
return a[5];
else
return a[A];
if (i == 4) /* { dg-warning "this condition has identical branches" } */
return a[A];
else
return a[A];
if (i == 5) /* { dg-warning "this condition has identical branches" } */
return a[i];
else
return a[i];
if (i == 6) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
return a[I];
else
return a[i];
if (i == 7) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
return a[i];
else
return a[I];
if (i == 8) /* { dg-warning "this condition has identical branches" } */
return a[I];
else
return a[I];
if (i == 10) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
g += A;
else
g += B;
if (i == 11) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
g += B;
else
g += A;
if (i == 12) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
g += A;
else
g += 5;
if (i == 12) /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
g += 5;
else
g += A;
}

View file

@ -0,0 +1,46 @@
/* PR c/64279 */
/* { dg-do compile } */
/* { dg-options "-Wduplicated-branches" } */
extern int *p, foo (void), a[10];
#define N 5
#define M 5
#define I i
void
f (int i)
{
*p += i ? 1 : 1; /* { dg-warning "this condition has identical branches" } */
*p += i ? N : M; /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
*p += i ? M : N; /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
*p += i ? i : i; /* { dg-warning "this condition has identical branches" } */
*p += i ? i++ : i++; /* { dg-warning "this condition has identical branches" } */
*p += i ? foo () : foo (); /* { dg-warning "this condition has identical branches" } */
*p += i ? ({ i++; }) : ({ i++; }); /* { dg-warning "this condition has identical branches" } */
*p += i ? a[i] : a[i]; /* { dg-warning "this condition has identical branches" } */
*p += i ? a[5] : a[5]; /* { dg-warning "this condition has identical branches" } */
*p += i ? a[N] : a[M]; /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
*p += i ? a[5] : a[M]; /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
*p += i ? a[M] : a[5]; /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
*p += i ? a[I] : a[I]; /* { dg-warning "this condition has identical branches" } */
*p += i ? a[i] : a[I]; /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
*p += i ? a[I] : a[i]; /* { dg-bogus "this condition has identical branches" "" { xfail *-*-* } } */
*p += i ?: 1;
*p += i ?: M;
*p += i ?: N;
*p += i ?: i; /* { dg-warning "this condition has identical branches" "" { target c++ } } */
*p += i ?: i++;
*p += i ?: foo ();
*p += i ?: ({ i++; });
*p += i ?: a[i];
*p += i ?: a[5];
*p += i ?: a[M];
*p += i ?: a[M];
*p += i ?: a[5];
*p += i ?: a[I];
*p += i ?: a[I];
*p += i ?: a[i];
*p += (i > 5 ? (i > 10 ? i : i) : i); /* { dg-warning "this condition has identical branches" } */
}

View file

@ -39,9 +39,9 @@ f (int i)
switch (i)
{
case 1:
do /* { dg-warning "statement may fall through" "" { target c++ } 42 } */
do
bar (2);
while (--i); /* { dg-warning "statement may fall through" "" { target c } 44 } */
while (--i); /* { dg-warning "statement may fall through" } */
case 2:
bar (99);
}

View file

@ -16,11 +16,11 @@ main ()
break; // { dg-error "break" }
}
};
l = []()
l = []() // { dg-warning "statement will never be executed" }
{
case 3: // { dg-error "case" }
break; // { dg-error "break" }
}; // { dg-warning "statement will never be executed" }
};
}
}
}

View file

@ -3,7 +3,7 @@
void baz (int *, int *);
#define MEMCPY(d,s,l) __builtin___memcpy_chk (d, s, l, __builtin_object_size (d, 0))
#define MEMCPY(d,s,l) __builtin___memcpy_chk (d, s, l, __builtin_object_size (d, 0)) // { dg-warning "writing" }
int
foo ()
@ -20,7 +20,7 @@ bar ()
{
int *p = new int;
int *q = new int[4];
MEMCPY (p, "abcdefghijklmnopqrstuvwxyz", sizeof (int) + 1); // { dg-warning "writing" }
MEMCPY (q, "abcdefghijklmnopqrstuvwxyz", 4 * sizeof (int) + 1); // { dg-warning "writing" }
MEMCPY (p, "abcdefghijklmnopqrstuvwxyz", sizeof (int) + 1); // { dg-message "in expansion of macro" }
MEMCPY (q, "abcdefghijklmnopqrstuvwxyz", 4 * sizeof (int) + 1); // { dg-message "in expansion of macro" }
baz (p, q);
}

View file

@ -82,8 +82,8 @@ f1 (int x)
for (j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
;
#pragma omp for collapse(2)
for (i = 0; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */
for (j = baz (&i); j < 16; j += 2)
for (i = 0; i < 16; i++)
for (j = baz (&i); j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
;
#pragma omp for collapse(2)
for (i = 0; i < 16; i++)
@ -215,8 +215,8 @@ f2 (int x)
for (int j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
;
#pragma omp for collapse(2)
for (int i = 0; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */
for (int j = baz (&i); j < 16; j += 2)
for (int i = 0; i < 16; i++)
for (int j = baz (&i); j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
;
#pragma omp for collapse(2)
for (int i = 0; i < 16; i++)

View file

@ -0,0 +1,21 @@
// PR c/64279
// { dg-do compile }
// { dg-options "-Wduplicated-branches" }
template <typename T>
void
f (char i, int *p)
{
if (i)
*p = (signed short) i;
else
*p = (unsigned short) i;
if (i) // { dg-warning "this condition has identical branches" }
*p = (T) i;
else
*p = (unsigned short) i;
}
template void f<unsigned short>(char, int *); // { dg-message "required from here" }
template void f<signed short>(char, int *);

View file

@ -0,0 +1,8 @@
// PR c/6427
// { dg-do compile { target c++11 } }
// { dg-options "-Wduplicated-branches" }
template<typename _ITp>
struct S {
static constexpr int i = sizeof(_ITp) > alignof(_ITp) ? sizeof(_ITp) : alignof(_ITp);
};

View file

@ -814,7 +814,9 @@ enum operand_equal_flag {
/* Internal within operand_equal_p: */
OEP_NO_HASH_CHECK = 16,
/* Internal within inchash::add_expr: */
OEP_HASH_CHECK = 32
OEP_HASH_CHECK = 32,
/* Makes operand_equal_p handle more expressions: */
OEP_LEXICOGRAPHIC = 64
};
/* Enum and arrays used for tree allocation stats.

View file

@ -7776,7 +7776,7 @@ add_expr (const_tree t, inchash::hash &hstate, unsigned int flags)
enum tree_code code;
enum tree_code_class tclass;
if (t == NULL_TREE)
if (t == NULL_TREE || t == error_mark_node)
{
hstate.merge_hash (0);
return;