Commit ca6c7225 by Jakub Jelinek

c++: Handle COMPOUND_EXPRs in get_narrower and warnings_for_convert_and_check [PR91993]

As the testcases shows, the -Wconversion warning behaves quite differently
when -fsanitize=undefined vs. when not sanitizing, but in the end it is
not something specific to sanitizing, if a user uses
  return static_cast<uc>(static_cast<uc>((d++, a) << 1U) | b) | c;
instead of
  return static_cast<uc>(static_cast<uc>(a << 1U) | b) | c;
and thus there is some COMPOUND_EXPR involved, cp_build_binary_op behaves
significantly different, e.g. shorten_binary_op will have different result
(uc for the case without COMPOUND_EXPR, int with it), but it isn't limited
to that.

> How about improving get_narrower to handle COMPOUND_EXPR?  I'd think that
> would do the trick without affecting evaluation order.

Not completely, had to change also warnings_for_convert_and_check, but with
that it works.  The float-cast-overflow* changes are needed because now with
-O1+ we emit lots of -Woverflow warnings on the testcase, but we do emit
those warnings on the testcase even when compiling just with -O1 and without
-fsanitize=float-cast-overflow, so it seems to me a change in the right
direction, having -fsanitize= or explicit comma expressions smaller effect
on the warnings that are emitted.

2020-03-23  Jakub Jelinek  <jakub@redhat.com>

	PR c++/91993
	* tree.c (get_narrower): Handle COMPOUND_EXPR by recursing on
	ultimate rhs and if returned something different, reconstructing
	the COMPOUND_EXPRs.

	* c-warn.c (warnings_for_convert_and_check): For expr and/or
	result being COMPOUND_EXPRs, skip to ultimate rhs.

	* g++.dg/warn/Wconversion-pr91993.C: New test.
	* g++.dg/ubsan/pr91993.C: New test.
	* c-c++-common/ubsan/float-cast-overflow-1.c: Add -Wno-overflow
	to dg-options.
	* c-c++-common/ubsan/float-cast-overflow-2.c: Likewise.
	* c-c++-common/ubsan/float-cast-overflow-4.c: Likewise.
parent 5db9e893
2020-03-23 Jakub Jelinek <jakub@redhat.com>
PR c++/91993
* tree.c (get_narrower): Handle COMPOUND_EXPR by recursing on
ultimate rhs and if returned something different, reconstructing
the COMPOUND_EXPRs.
2020-03-23 Lewis Hyatt <lhyatt@gmail.com>
* opts.c (print_filtered_help): Improve the help text for alias options.
......
2020-03-23 Jakub Jelinek <jakub@redhat.com>
PR c++/91993
* c-warn.c (warnings_for_convert_and_check): For expr and/or
result being COMPOUND_EXPRs, skip to ultimate rhs.
2020-03-20 Richard Sandiford <richard.sandiford@arm.com>
PR middle-end/94072
......
......@@ -1359,6 +1359,11 @@ warnings_for_convert_and_check (location_t loc, tree type, tree expr,
{
loc = expansion_point_location_if_in_system_header (loc);
while (TREE_CODE (expr) == COMPOUND_EXPR)
expr = TREE_OPERAND (expr, 1);
while (TREE_CODE (result) == COMPOUND_EXPR)
result = TREE_OPERAND (result, 1);
bool cst = TREE_CODE_CLASS (TREE_CODE (result)) == tcc_constant;
tree exprtype = TREE_TYPE (expr);
......
2020-03-23 Jakub Jelinek <jakub@redhat.com>
PR c++/91993
* g++.dg/warn/Wconversion-pr91993.C: New test.
* g++.dg/ubsan/pr91993.C: New test.
* c-c++-common/ubsan/float-cast-overflow-1.c: Add -Wno-overflow
to dg-options.
* c-c++-common/ubsan/float-cast-overflow-2.c: Likewise.
* c-c++-common/ubsan/float-cast-overflow-4.c: Likewise.
2020-03-23 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
Andre Vieira <andre.simoesdiasvieira@arm.com>
Mihail Ionescu <mihail.ionescu@arm.com>
......
/* { dg-do run { target { lp64 || ilp32 } } } */
/* { dg-options "-fsanitize=float-cast-overflow" } */
/* { dg-options "-fsanitize=float-cast-overflow -Wno-overflow" } */
/* { dg-additional-options "-ffloat-store" { target { ia32 } } } */
/* { dg-additional-options "-mieee" { target { { alpha*-*-* } || { sh*-*-* } } } } */
......
/* { dg-do run } */
/* { dg-require-effective-target int128 } */
/* { dg-options "-fsanitize=float-cast-overflow" } */
/* { dg-options "-fsanitize=float-cast-overflow -Wno-overflow" } */
#include "float-cast.h"
......
/* { dg-do run { target { lp64 } } } */
/* { dg-options "-fsanitize=float-cast-overflow" } */
/* { dg-options "-fsanitize=float-cast-overflow -Wno-overflow" } */
#include <limits.h>
#include "float-cast.h"
......
// PR c++/91993
// { dg-do compile }
// { dg-options "-Wconversion -fsanitize=undefined" }
typedef unsigned char uc;
int
foo (const uc &a, const uc &b, const uc &c)
{
return static_cast<uc>(static_cast<uc>(a << 1U) | b) | c; // { dg-bogus "conversion from 'int' to 'unsigned char' may change value" }
}
int
bar (const uc &a, const uc &b, const uc &c, int &d)
{
return static_cast<uc>(static_cast<uc>((d++, a) << 1U) | b) | c; // { dg-bogus "conversion from 'int' to 'unsigned char' may change value" }
}
// PR c++/91993
// { dg-do compile }
// { dg-options "-Wconversion" }
typedef unsigned char uc;
int
foo (const uc &a, const uc &b, const uc &c)
{
return static_cast<uc>(static_cast<uc>(a << 1U) | b) | c; // { dg-bogus "conversion from 'int' to 'unsigned char' may change value" }
}
int
bar (const uc &a, const uc &b, const uc &c, int &d)
{
return static_cast<uc>(static_cast<uc>((d++, a) << 1U) | b) | c; // { dg-bogus "conversion from 'int' to 'unsigned char' may change value" }
}
......@@ -8862,6 +8862,21 @@ get_narrower (tree op, int *unsignedp_ptr)
tree win = op;
bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
if (TREE_CODE (op) == COMPOUND_EXPR)
{
while (TREE_CODE (op) == COMPOUND_EXPR)
op = TREE_OPERAND (op, 1);
tree ret = get_narrower (op, unsignedp_ptr);
if (ret == op)
return win;
op = win;
for (tree *p = &win; TREE_CODE (op) == COMPOUND_EXPR;
op = TREE_OPERAND (op, 1), p = &TREE_OPERAND (*p, 1))
*p = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR,
TREE_TYPE (ret), TREE_OPERAND (op, 0),
ret);
return win;
}
while (TREE_CODE (op) == NOP_EXPR)
{
int bitschange
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment