These are ported from the c-family code c-warn.cc and c/c-typchk.cc
Fixes Rust-GCC#2394
gcc/rust/ChangeLog:
* backend/rust-constexpr.cc (eval_store_expression): check for null
(eval_call_expression): remove bad warning
* rust-gcc.cc (arithmetic_or_logical_expression): add warnings
gcc/testsuite/ChangeLog:
* rust/compile/issue-2394.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
}
}
+ if (*non_constant_p)
+ return t;
+
/* Don't share a CONSTRUCTOR that might be changed later. */
init = unshare_constructor (init);
+ if (init == NULL_TREE)
+ return t;
if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
&& TREE_CODE (init) == CONSTRUCTOR)
result = *ctx->global->values.get (res);
if (result == NULL_TREE && !*non_constant_p)
{
- if (!ctx->quiet)
- error ("%<constexpr%> call flows off the end "
- "of the function");
*non_constant_p = true;
}
}
if (floating_point && extended_type != NULL_TREE)
ret = convert (original_type, ret);
+ if (op == ArithmeticOrLogicalOperator::DIVIDE
+ && (integer_zerop (right) || fixed_zerop (right)))
+ {
+ rust_error_at (location, "division by zero");
+ }
+ else if (op == ArithmeticOrLogicalOperator::LEFT_SHIFT
+ && (compare_tree_int (right, TYPE_PRECISION (TREE_TYPE (ret))) >= 0))
+ {
+ rust_error_at (location, "left shift count >= width of type");
+ }
+
return ret;
}
--- /dev/null
+const A: i32 = (1 / 0);
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+fn main() {
+ let a = 1 / 0;
+ // { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+ let b = 3;
+ let c = b / 0;
+ // { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+ let a = 1 << 500;
+ // { dg-error "left shift count >= width of type" "" { target *-*-* } .-1 }
+}