Bug 36227 - [4.3 Regression] POINTER_PLUS folding introduces undefined overflow
Summary: [4.3 Regression] POINTER_PLUS folding introduces undefined overflow
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.4.0
Assignee: Richard Biener
URL:
Keywords: wrong-code
: 38835 (view as bug list)
Depends on:
Blocks: 38835
  Show dependency treegraph
 
Reported: 2008-05-13 12:42 UTC by Richard Biener
Modified: 2009-06-17 12:35 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.2.4 4.4.0
Known to fail: 4.3.2 4.3.3 4.3.4
Last reconfirmed: 2009-01-16 13:35:48


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2008-05-13 12:42:26 UTC
unsigned long * sat_add(unsigned long *ptr, unsigned long i, unsigned long *end)
{
  if ((unsigned long)ptr + i * sizeof(*ptr) > (unsigned long)ptr)
    return ptr + i;
  else
    return end;
}

is folded to

  if (ptr + (long unsigned int) (i * 8) > ptr)
    {
      return ptr + (long unsigned int) (i * 8);
    }
  else
    {
      return end;
    }
Comment 1 Richard Biener 2008-05-13 12:43:36 UTC
Err - only with volatiles ... !?

volatile unsigned long * sat_add(volatile unsigned long *ptr, unsigned long i, volatile unsigned long *end)
{
  if ((unsigned long)ptr + i * sizeof(*ptr) > (unsigned long)ptr)
    return ptr + i;
  else
    return end;
}
Comment 2 Richard Biener 2008-05-13 12:54:21 UTC
Part of the fix is

Index: fold-const.c
===================================================================
--- fold-const.c        (revision 135255)
+++ fold-const.c        (working copy)
@@ -6831,7 +6831,8 @@ fold_sign_changed_comparison (enum tree_
           && TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
     return NULL_TREE;
 
-  if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
+  if ((TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
+       || POINTER_TYPE_P (inner_type) != POINTER_TYPE_P (outer_type))
       && code != NE_EXPR
       && code != EQ_EXPR)
     return NULL_TREE;


but the question is if the folding to POINTER_PLUS is correct at all.
Comment 3 Richard Biener 2008-05-13 14:02:52 UTC
Subject: Bug 36227

Author: rguenth
Date: Tue May 13 14:01:53 2008
New Revision: 135260

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=135260
Log:
2008-05-13  Richard Guenther  <rguenther@suse.de>

	PR middle-end/36227
	* fold-const.c (fold_sign_changed_comparison): Do not allow
	changes in pointer-ness.

	* gcc.dg/pr36227.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/pr36227.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
    trunk/gcc/testsuite/ChangeLog

Comment 4 Richard Biener 2008-05-13 14:05:32 UTC
Subject: Bug 36227

Author: rguenth
Date: Tue May 13 14:04:40 2008
New Revision: 135261

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=135261
Log:
2008-05-13  Richard Guenther  <rguenther@suse.de>

	PR middle-end/36227
	* fold-const.c (fold_sign_changed_comparison): Do not allow
	changes in pointer-ness.

	* gcc.dg/pr36227.c: New testcase.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/pr36227.c
      - copied unchanged from r135260, trunk/gcc/testsuite/gcc.dg/pr36227.c
Modified:
    branches/gcc-4_3-branch/gcc/ChangeLog
    branches/gcc-4_3-branch/gcc/fold-const.c
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog

Comment 5 Richard Biener 2008-05-13 14:13:13 UTC
Only the theoretical problem remains.  We still fold

  (unsigned long)ptr + (unsigned long)i

to

  (unsigned long)(ptr + (unsigned long)i)

where the inner POINTER_PLUS_EXPR now may invoke undefined behavior on
overflow.

No testcase is known where that results in a wrong-code bug.
Comment 6 Richard Biener 2008-06-06 14:59:24 UTC
4.3.1 is being released, adjusting target milestone.
Comment 7 Joseph S. Myers 2008-08-27 22:04:03 UTC
4.3.2 is released, changing milestones to 4.3.3.
Comment 8 Richard Biener 2009-01-16 13:20:27 UTC
Now it does.  See PR38835.
Comment 9 Richard Biener 2009-01-16 13:35:48 UTC
Mine.
Comment 10 Richard Biener 2009-01-16 18:56:51 UTC
C testcase, fails with 4.3 and 4.4 with -O2 --param
max-fields-for-field-sensitive=0

#include <stdint.h>
extern void abort (void);
int main()
{
  int i = 1;
  int *p = &i;
  uintptr_t iptr;

  iptr = (uintptr_t)p - (uintptr_t)&iptr;
  p = (int *)((uintptr_t)&iptr + iptr);
  if (*p != 1)
    abort ();
  return 0;
}
Comment 11 Richard Biener 2009-01-16 18:57:07 UTC
*** Bug 38835 has been marked as a duplicate of this bug. ***
Comment 12 Richard Biener 2009-01-16 19:18:35 UTC
Subject: Bug 36227

Author: rguenth
Date: Fri Jan 16 19:18:18 2009
New Revision: 143442

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143442
Log:
2009-01-16  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/38835
	PR middle-end/36227
	* fold-const.c (fold_binary): Remove PTR + INT -> (INT)(PTR p+ INT)
	and INT + PTR -> (INT)(PTR p+ INT) folding.
	* tree-ssa-address.c (create_mem_ref): Properly use POINTER_PLUS_EXPR.

	java/
	* builtins.c (build_addr_sum): Use POINTER_PLUS_EXPR.

	* gcc.c-torture/execute/pr36227.c: New testcase.
	* gcc.dg/tree-ssa/foldaddr-1.c: XFAIL.
	* g++.dg/init/const7.C: Likewise.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/pr36227.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/fold-const.c
    trunk/gcc/java/ChangeLog
    trunk/gcc/java/builtins.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/init/const7.C
    trunk/gcc/testsuite/gcc.dg/tree-ssa/foldaddr-1.c
    trunk/gcc/tree-ssa-address.c

Comment 13 Richard Biener 2009-01-16 19:22:33 UTC
Fixed on the trunk.  Also fails with plain -O for 4.3.2.
Comment 14 John David Anglin 2009-01-19 16:14:29 UTC
New test fails on hpux:

Executing on host: /test/gnu/gcc/objdir/gcc/xgcc -B/test/gnu/gcc/objdir/gcc/ /te
st/gnu/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/pr36227.c  -w  -O0   -lm   -o
 /test/gnu/gcc/objdir/gcc/testsuite/gcc/pr36227.x0    (timeout = 300)
/test/gnu/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/pr36227.c:1:20: error: std
int.h: No such file or directory
Comment 15 rguenther@suse.de 2009-01-19 16:22:03 UTC
Subject: Re:  [4.3 Regression] POINTER_PLUS folding
 introduces undefined overflow

On Mon, 19 Jan 2009, danglin at gcc dot gnu dot org wrote:

> ------- Comment #14 from danglin at gcc dot gnu dot org  2009-01-19 16:14 -------
> New test fails on hpux:
> 
> Executing on host: /test/gnu/gcc/objdir/gcc/xgcc -B/test/gnu/gcc/objdir/gcc/
> /te
> st/gnu/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/pr36227.c  -w  -O0   -lm  
> -o
>  /test/gnu/gcc/objdir/gcc/testsuite/gcc/pr36227.x0    (timeout = 300)
> /test/gnu/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/pr36227.c:1:20: error:
> std
> int.h: No such file or directory

Ah, needs

{ target { stdint_types } }

Richard.
Comment 16 Richard Biener 2009-01-20 09:21:52 UTC
Should be fixed now.
Comment 17 Richard Biener 2009-01-24 10:20:23 UTC
GCC 4.3.3 is being released, adjusting target milestone.
Comment 18 Richard Biener 2009-01-24 23:34:22 UTC
Backporting requires revs 143442, 143455 and 143509 and then still regresses

gcc.target/i386/pr37101.c
gfortran.dg/array_constructor_12.f90

all pointer-plus ICEs.
Comment 19 Richard Biener 2009-06-17 12:35:56 UTC
WONTFIX for 4.3.