@@ -78,7 +78,19 @@ along with GCC; see the file COPYING3. If not see
(simplify
(mult @0 integer_zerop@1)
- @1)
+ /* Make sure to preserve divisions by zero. */
+ (with { enum tree_code code = TREE_CODE (@0); }
+ (if ((code != TRUNC_DIV_EXPR
+ && code != EXACT_DIV_EXPR
+ && code != ROUND_DIV_EXPR
+ && code != FLOOR_DIV_EXPR
+ && code != CEIL_DIV_EXPR
+ && code != TRUNC_MOD_EXPR
+ && code != CEIL_MOD_EXPR
+ && code != FLOOR_MOD_EXPR
+ && code != ROUND_MOD_EXPR)
+ || !integer_zerop (TREE_OPERAND (@0, 1)))
+ @1)))
/* Maybe fold x * 0 to 0. The expressions aren't the same
when x is NaN, since x * 0 is also NaN. Nor are they the
@@ -17,7 +17,7 @@ enum e {
/* But as in DR#031, the 1/0 in an evaluated subexpression means the
whole expression violates the constraints. */
E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */
- /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */
+ /* { dg-error "enumerator value for 'E4' is not an integer constant|not a constant.expression" "enum error" { target *-*-* } 19 } */
E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */
/* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 21 } */
/* Again, overflow in evaluated subexpression. */
@@ -30,8 +30,9 @@ enum e {
struct s {
int a;
int : 0 * (1 / 0); /* { dg-warning "division by zero" } */
+ /* { dg-error "not an integer constant|not a constant.expression" "bit-field error" { target *-*-* } 32 } */
int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
- /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 33 } */
+ /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 34 } */
};
void
@@ -45,7 +46,6 @@ f (void)
/* This expression is neither required to be constant. */
static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */
-
// Test for overflow in null pointer constant.
void *n = 0;
/* The first two of these involve overflow, so are not null pointer
@@ -54,7 +54,7 @@ void *n = 0;
void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
/* { dg-warning "invalid conversion from 'int' to 'void" "null" { target *-*-* } 54 } */
void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */
-/* { dg-error "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 56 } */
+/* { dg-warning "invalid conversion from 'int' to 'void\\*'" "null" { target *-*-* } 56 } */
void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } } */
void
@@ -63,9 +63,10 @@ g (int i)
switch (i)
{
case 0 * (1/0): /* { dg-warning "division by zero" } */
+ /* { dg-error "not a constant.expression" "case error" { target *-*-* } 65 } */
;
case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */
- /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 67 } */
+ /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 68 } */
;
}
}
@@ -17,7 +17,7 @@ enum e {
/* But as in DR#031, the 1/0 in an evaluated subexpression means the
whole expression violates the constraints. */
E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */
- /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */
+ /* { dg-error "enumerator value for 'E4' is not an integer constant|not a constant.expression" "enum error" { target *-*-* } 19 } */
E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */
/* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 21 } */
/* Again, overflow in evaluated subexpression. */
@@ -30,8 +30,9 @@ enum e {
struct s {
int a;
int : 0 * (1 / 0); /* { dg-warning "division by zero" } */
+ /* { dg-error "not an integer constant|not a constant.expression" "bit-field error" { target *-*-* } 32 } */
int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
- /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 33 } */
+ /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 34 } */
};
void
@@ -40,7 +41,6 @@ f (void)
/* This expression is not required to be a constant expression, so
it should just involve undefined behavior at runtime. */
int c = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */
-
}
/* This expression is neither required to be constant. */
@@ -56,7 +56,7 @@ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" }
/* { dg-warning "invalid conversion from 'int' to 'void" "null" { target *-*-* } 55 } */
void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */
-/* { dg-warning "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 58 } */
+/* { dg-warning "invalid conversion from 'int' to 'void\\*'" "null" { target *-*-* } 58 } */
void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } } */
void
@@ -65,9 +65,10 @@ g (int i)
switch (i)
{
case 0 * (1/0): /* { dg-warning "division by zero" } */
+ /* { dg-error "not a constant.expression" "case error" { target *-*-* } 67 } */
;
case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */
- /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 69 } */
+ /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } 70 } */
;
}
}
@@ -17,7 +17,7 @@ enum e {
/* But as in DR#031, the 1/0 in an evaluated subexpression means the
whole expression violates the constraints. */
E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */
- /* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { xfail *-*-* } 19 } */
+ /* { dg-error "enumerator value for 'E4' is not an integer constant|not a constant.expression" "enum error" { target *-*-* } 19 } */
E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */
/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 21 } */
/* { dg-error "enumerator value for 'E5' is not an integer constant" "enum error" { target *-*-* } 21 } */
@@ -32,9 +32,10 @@ enum e {
struct s {
int a;
int : 0 * (1 / 0); /* { dg-warning "division by zero" } */
+ /* { dg-error "not an integer constant|not a constant.expression" "bit-field error" { target *-*-* } 34 } */
int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 35 } */
- /* { dg-error "bit-field .* width not an integer constant" "" { target *-*-* } 35 } */
+ /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 36 } */
+ /* { dg-error "bit-field .* width not an integer constant" "" { target *-*-* } 36 } */
};
void
@@ -43,7 +44,6 @@ f (void)
/* This expression is not required to be a constant expression, so
it should just involve undefined behavior at runtime. */
int c = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */
-
}
/* This expression is neither required to be constant. */
@@ -59,7 +59,7 @@ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" }
/* { dg-error "invalid conversion from 'int' to 'void" "null" { target *-*-* } 58 } */
void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */
-/* { dg-error "invalid conversion from 'int' to 'void*'" "null" { xfail *-*-* } 61 } */
+/* { dg-error "invalid conversion from 'int' to 'void\\*'" "null" { target *-*-* } 61 } */
void *r = (1 ? 0 : INT_MAX+1); /* { dg-bogus "integer overflow in expression" "" { xfail *-*-* } } */
void
@@ -68,9 +68,10 @@ g (int i)
switch (i)
{
case 0 * (1/0): /* { dg-warning "division by zero" } */
+ /* { dg-error "not a constant.expression" "case error" { target *-*-* } 70 } */
;
case 1 + 0 * (INT_MAX + 1): /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 72 } */
+ /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 73 } */
;
}
}
@@ -1,14 +1,10 @@
/* { dg-do compile } */
/* { dg-options "-fsanitize=integer-divide-by-zero" } */
-/* TODO: We expect an error on the invalid case here, because that
- must be a constant-expression. This will be fixed when we have
- proper delayed folding. */
-
void
foo (int i)
{
switch (i)
case 0 * (1 / 0): /* { dg-warning "division by zero" } */
- ; /* { dg-error "division by zero" "" { xfail *-*-* } 10 } */
+ ; /* { dg-error "not a constant.expression" "" { target *-*-* } 8 } */
}