Bug 80800 - UBSAN: yet another false positive
Summary: UBSAN: yet another false positive
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: sanitizer (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Marek Polacek
URL:
Keywords:
Depends on:
Blocks: yarpgen
  Show dependency treegraph
 
Reported: 2017-05-17 07:53 UTC by Dmitry Babokin
Modified: 2021-11-01 23:07 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-05-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Babokin 2017-05-17 07:53:31 UTC
gcc rev248130, x86_64

> cat f.cpp
short var_29 = 26289;
unsigned short var_48 = 20359;
unsigned short var_80 = 21070;
int foo() {
  return 72 * (var_48 * 8531 * (var_80 / var_29));
}

int main () {
  foo();
  return 0;
}

> g++ -fsanitize=undefined f.cpp

> ./a.out
f.cpp:5:49: runtime error: signed integer overflow: 20359 * 614232 cannot be represented in type 'int'
Comment 1 Marek Polacek 2017-05-17 07:59:28 UTC
Confirmed.  I'll have a look.
Comment 2 Richard Biener 2017-05-17 08:10:16 UTC
This time it's extract_muldiv.

((int) var_48 * 8531) * ((int) var_80 / (int) var_29)
multiplied by 72 to
((int) var_48 * 614232) * ((int) var_80 / (int) var_29)
Comment 3 Marek Polacek 2017-05-17 08:14:28 UTC
Whoa.  Do we want to use TYPE_OVERFLOW_SANITIZED to prevent that from happening?  I know you don't like it...
Comment 4 rguenther@suse.de 2017-05-17 08:29:42 UTC
On Wed, 17 May 2017, mpolacek at gcc dot gnu.org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80800
> 
> --- Comment #3 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
> Whoa.  Do we want to use TYPE_OVERFLOW_SANITIZED to prevent that from
> happening?  I know you don't like it...

No, the bug is the folding itself, even when not sanitizing.
Comment 5 Marek Polacek 2017-05-17 10:26:17 UTC
Simplified testcase:

unsigned short n = 20000;
unsigned short z = 0;

int
main ()
{
  return 50 * (n * 10000 * z);
}
Comment 6 Marek Polacek 2017-05-17 10:29:19 UTC
Or rather

int n = 20000;
int z = 0;

int
main ()
{
  return 50 * (n * 10000 * z);
}
Comment 7 Marek Polacek 2017-05-19 15:31:26 UTC
Author: mpolacek
Date: Fri May 19 15:30:54 2017
New Revision: 248291

URL: https://gcc.gnu.org/viewcvs?rev=248291&root=gcc&view=rev
Log:
	PR sanitizer/80800
	* fold-const.c (extract_muldiv_1) <case TRUNC_DIV_EXPR>: Add
	TYPE_OVERFLOW_WRAPS checks.

	* c-c++-common/ubsan/pr80800.c: New test.
	* c-c++-common/Wduplicated-branches-1.c: Adjust an expression.

Added:
    trunk/gcc/testsuite/c-c++-common/ubsan/pr80800.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/c-c++-common/Wduplicated-branches-1.c
Comment 8 Marek Polacek 2017-05-19 15:32:53 UTC
Fixed.