https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79119
Bug ID: 79119 Summary: absolute value of a pointer difference can be assumed to be less than or equal to PTRDIFF_MAX Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- C and C++ guarantee that the difference between two pointers into the same array must be representable in ptrdiff_t. In addition, the absolute value of the difference must be less than or equal to PTRDIFF_MAX / sizeof (T) where T is the type of the array element. The test case below shows that GCC doesn't make use of the guarantee. If it did, it should be able to determine that the condition guarding the abort() statement in each of the functions below can never evaluate to true. $ cat t.c && gcc -O2 -S -fdump-tree-optimized=/dev/stdout t.c void f (int *a, __SIZE_TYPE__ i, __SIZE_TYPE__ j) { int *p = a + i; int *q = a + j; __SIZE_TYPE__ n = p < q ? q - p : p - q; if (n > __PTRDIFF_MAX__ / sizeof (int)) __builtin_abort (); } void g (int *a, __SIZE_TYPE__ i, __SIZE_TYPE__ j) { int *p = a + i; int *q = a + j; __SIZE_TYPE__ n = p < q ? q - p : p - q; if (n > __PTRDIFF_MAX__) __builtin_abort (); } ;; Function f (f, funcdef_no=0, decl_uid=1445, cgraph_uid=0, symbol_order=0) f (int * a, long unsigned int i, long unsigned int j) { int * q; int * p; long unsigned int _1; long unsigned int _2; long int _3; long int _4; long int _5; long int _6; long unsigned int iftmp.0_7; long unsigned int iftmp.0_13; long unsigned int iftmp.0_14; long int _21; long int _22; <bb 2> [100.00%]: _1 = i_8(D) * 4; p_10 = a_9(D) + _1; _2 = j_11(D) * 4; q_12 = a_9(D) + _2; _21 = (long int) _1; _22 = (long int) _2; if (p_10 < q_12) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [50.00%]: _3 = _22 - _21; _4 = _3 /[ex] 4; iftmp.0_14 = (long unsigned int) _4; goto <bb 5>; [100.00%] <bb 4> [50.00%]: _5 = _21 - _22; _6 = _5 /[ex] 4; iftmp.0_13 = (long unsigned int) _6; <bb 5> [100.00%]: # iftmp.0_7 = PHI <iftmp.0_14(3), iftmp.0_13(4)> if (iftmp.0_7 > 536870911) goto <bb 6>; [0.04%] else goto <bb 7>; [99.96%] <bb 6> [0.04%]: __builtin_abort (); <bb 7> [99.96%]: return; } ;; Function g (g, funcdef_no=1, decl_uid=1453, cgraph_uid=1, symbol_order=1) g (int * a, long unsigned int i, long unsigned int j) { int * q; int * p; long unsigned int _1; long unsigned int _2; long int _3; long int _4; long int _5; long int _6; signed int n.10_7; long unsigned int iftmp.5_8; long unsigned int iftmp.5_14; long unsigned int iftmp.5_15; long int _22; long int _23; <bb 2> [100.00%]: _1 = i_9(D) * 4; p_11 = a_10(D) + _1; _2 = j_12(D) * 4; q_13 = a_10(D) + _2; _22 = (long int) _1; _23 = (long int) _2; if (p_11 < q_13) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [50.00%]: _3 = _23 - _22; _4 = _3 /[ex] 4; iftmp.5_15 = (long unsigned int) _4; goto <bb 5>; [100.00%] <bb 4> [50.00%]: _5 = _22 - _23; _6 = _5 /[ex] 4; iftmp.5_14 = (long unsigned int) _6; <bb 5> [100.00%]: # iftmp.5_8 = PHI <iftmp.5_15(3), iftmp.5_14(4)> n.10_7 = (signed int) iftmp.5_8; if (n.10_7 < 0) goto <bb 6>; [0.04%] else goto <bb 7>; [99.96%] <bb 6> [0.04%]: __builtin_abort (); <bb 7> [99.96%]: return; }