Bug 80932 - UBSAN: false positive as a result of distribution: c1*(c2*v1-c3*v2)=>c1*c2*v1-c1*c3*v2
Summary: UBSAN: false positive as a result of distribution: c1*(c2*v1-c3*v2)=>c1*c2*v1...
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: wrong-code
Depends on:
Blocks: yarpgen
  Show dependency treegraph
 
Reported: 2017-05-31 21:00 UTC by Dmitry Babokin
Modified: 2021-11-01 23:07 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-06-01 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-31 21:00:22 UTC
gcc trunk rev248580, x86_64.

Transformation causing troubles: const1 * (const2 * var1 - const3 * var2) => const1*const2*var1 - const3*var2;

> cat f.cpp

#include <iostream>
signed char var_10 = 77;
long long int var_13 = 1547580415367384384LL;

long foo() {
  long a = -6 *
            // 0xbf8a6c24aa342bc0 = -4644781160949077056
           (long(16636733186465668563ULL * var_13 ) -
            // 0xd4cdd0f8c2df13cf = -3112602000603278385
            long(678280911954875019ULL * var_10));
  return a;
}

int main () {
    long a = foo ();
    std::cout << a << std::endl;
    return 0;
}

> g++ -fsanitize=undefined -O0 f.cpp; ./a.out

f.cpp:6:8: runtime error: signed integer overflow: -9024801181724640896 - 228867929910118694 cannot be represented in type 'long int'
9193074962074792026
Comment 1 Marek Polacek 2017-06-01 09:59:25 UTC
Confirmed.  I'll take a look.
Comment 2 Marek Polacek 2017-06-05 13:37:09 UTC
Better testcase (C and C++):

int x = 1;

long int
foo (void)
{
  return ((long) (13801962912760474560ULL * x) - (long) (15334142073106273231ULL * x)) * -6;
}

int
main ()
{
  foo ();
  return 0;
}
Comment 3 Marek Polacek 2017-06-05 13:37:35 UTC
Should've been in ASSIGNED.
Comment 4 Marek Polacek 2017-06-07 11:20:12 UTC
Author: mpolacek
Date: Wed Jun  7 11:19:40 2017
New Revision: 248961

URL: https://gcc.gnu.org/viewcvs?rev=248961&root=gcc&view=rev
Log:
	PR sanitizer/80932
	* fold-const.c (extract_muldiv_1) <case MINUS_EXPR>: Add
	TYPE_OVERFLOW_WRAPS check. 

	* c-c++-common/ubsan/pr80932.c: New test.

Added:
    trunk/gcc/testsuite/c-c++-common/ubsan/pr80932.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Marek Polacek 2017-06-07 11:34:29 UTC
Fixed.
Comment 6 Markus Trippelsdorf 2017-06-08 07:21:43 UTC
New failures:
FAIL: c-c++-common/ubsan/pr80932.c   -O0  execution test
FAIL: c-c++-common/ubsan/pr80932.c   -O0  execution test
Comment 7 Marek Polacek 2017-06-08 10:46:36 UTC
Can't reproduce.  What arch, is that gcc or g++, ...
Comment 9 Markus Trippelsdorf 2017-06-08 10:59:22 UTC
trunk (checking=release):

trippels@gcc67 gcc % gcc -O0 -fsanitize=undefined ./gcc/testsuite/c-c++-common/ubsan/pr80932.c
trippels@gcc67 gcc % ./a.out
gcc/testsuite/c-c++-common/ubsan/pr80932.c:10:88: runtime error: signed integer overflow: -9024801181724640896 - 228867929910118694 cannot be represented in type 'long int'
Comment 10 Marek Polacek 2017-06-08 11:29:28 UTC
Reproduced with -m32 on x86_64.  Silly me.  Will fix.

pr80932.c:10:88: runtime error: signed integer overflow: -413853711 * -6 cannot be represented in type 'long int'
Comment 11 Marek Polacek 2017-06-08 12:38:59 UTC
Author: mpolacek
Date: Thu Jun  8 12:38:27 2017
New Revision: 249010

URL: https://gcc.gnu.org/viewcvs?rev=249010&root=gcc&view=rev
Log:
	PR sanitize/80932
	* c-c++-common/ubsan/pr80932.c: Test with ints, not with long ints.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/c-c++-common/ubsan/pr80932.c
Comment 12 Richard Biener 2017-08-28 12:50:28 UTC
Author: rguenth
Date: Mon Aug 28 12:49:55 2017
New Revision: 251381

URL: https://gcc.gnu.org/viewcvs?rev=251381&root=gcc&view=rev
Log:
2017-08-28  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2017-06-14  Richard Biener  <rguenther@suse.de>

	PR middle-end/81088
	* fold-const.c (split_tree): Drop TREE_OVERFLOW flag from
	literal constants.
	(fold_binary_loc): When associating do not treat pre-existing
	TREE_OVERFLOW on literal constants as a reason to allow
	TREE_OVERFLOW on associated literal constants.

	* c-c++-common/ubsan/pr81088.c: New testcase.

	2017-06-13  Richard Biener  <rguenther@suse.de>

	PR middle-end/81065
	* fold-const.c (extract_muldiv_1): Remove bogus distribution
	case of C * (x * C2 + C3).
	(fold_addr_of_array_ref_difference): Properly fold index difference.

	* c-c++-common/ubsan/pr81065.c: New testcase.

	2017-06-08  Marek Polacek  <polacek@redhat.com>

	PR sanitize/80932
	* c-c++-common/ubsan/pr80932.c: Test with ints, not with long ints.

	2017-06-07  Marek Polacek  <polacek@redhat.com>

	PR sanitizer/80932
	* fold-const.c (extract_muldiv_1) <case MINUS_EXPR>: Add
	TYPE_OVERFLOW_WRAPS check. 

	* c-c++-common/ubsan/pr80932.c: New test.

Added:
    branches/gcc-7-branch/gcc/testsuite/c-c++-common/ubsan/pr80932.c
    branches/gcc-7-branch/gcc/testsuite/c-c++-common/ubsan/pr81065.c
    branches/gcc-7-branch/gcc/testsuite/c-c++-common/ubsan/pr81088.c
Modified:
    branches/gcc-7-branch/gcc/ChangeLog
    branches/gcc-7-branch/gcc/fold-const.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog