public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Add overflow checking on LiteralExpression
@ 2022-06-08 11:58 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:58 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:507dbac06d845af87e488dcb1f66390b4ca12de3

commit 507dbac06d845af87e488dcb1f66390b4ca12de3
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Wed Jan 5 18:31:03 2022 +0000

    Add overflow checking on LiteralExpression
    
    This checks that the literal value is within the bounds of their respective
    types. I have ommited code fixing the other issue in the bug report that
    overflow/max_val integers should be saturated to infinity when cast to
    REAL_TYPE's this seems like something we really should have documentation
    to reference in the code as to why this is the correct Rust behaviour.
    
    Addresses #635

Diff:
---
 gcc/rust/backend/rust-compile-expr.cc         | 207 ++++++++++++++++++++++++++
 gcc/rust/backend/rust-compile-expr.h          | 166 ++++++---------------
 gcc/rust/hir/tree/rust-hir-expr.h             |   3 +-
 gcc/rust/typecheck/rust-hir-const-fold.h      |   6 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.h |  10 +-
 gcc/rust/typecheck/rust-tycheck-dump.h        |   2 +-
 gcc/rust/typecheck/rust-tyty-cast.h           |   2 +-
 gcc/testsuite/rust/compile/issue-635-1.rs     |   5 +
 gcc/testsuite/rust/compile/issue-635-2.rs     |   5 +
 9 files changed, 278 insertions(+), 128 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index b77a4d5d57c..0307b2145ae 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -27,6 +27,8 @@
 #include "rust-compile-pattern.h"
 
 #include "fold-const.h"
+#include "realmpfr.h"
+#include "convert.h"
 
 namespace Rust {
 namespace Compile {
@@ -893,5 +895,210 @@ CompileExpr::resolve_operator_overload (
 					       nullptr, expr.get_locus ());
 }
 
+tree
+CompileExpr::compile_bool_literal (const HIR::LiteralExpr &expr,
+				   const TyTy::BaseType *tyty)
+{
+  rust_assert (expr.get_lit_type () == HIR::Literal::BOOL);
+
+  const auto literal_value = expr.get_literal ();
+  bool bval = literal_value.as_string ().compare ("true") == 0;
+  return ctx->get_backend ()->boolean_constant_expression (bval);
+}
+
+tree
+CompileExpr::compile_integer_literal (const HIR::LiteralExpr &expr,
+				      const TyTy::BaseType *tyty)
+{
+  rust_assert (expr.get_lit_type () == HIR::Literal::INT);
+  const auto literal_value = expr.get_literal ();
+
+  tree type = TyTyResolveCompile::compile (ctx, tyty);
+  rust_assert (TREE_CODE (type) == INTEGER_TYPE);
+
+  mpz_t ival;
+  if (mpz_init_set_str (ival, literal_value.as_string ().c_str (), 10) != 0)
+    {
+      rust_error_at (expr.get_locus (), "bad number in literal");
+      return error_mark_node;
+    }
+
+  mpz_t type_min;
+  mpz_t type_max;
+  mpz_init (type_min);
+  mpz_init (type_max);
+  get_type_static_bounds (type, type_min, type_max);
+
+  if (mpz_cmp (ival, type_min) < 0 || mpz_cmp (ival, type_max) > 0)
+    {
+      rust_error_at (expr.get_locus (),
+		     "integer overflows the respective type %<%s%>",
+		     tyty->get_name ().c_str ());
+      return error_mark_node;
+    }
+  return double_int_to_tree (type, mpz_get_double_int (type, ival, true));
+}
+
+tree
+CompileExpr::compile_float_literal (const HIR::LiteralExpr &expr,
+				    const TyTy::BaseType *tyty)
+{
+  rust_assert (expr.get_lit_type () == HIR::Literal::FLOAT);
+  const auto literal_value = expr.get_literal ();
+
+  mpfr_t fval;
+  if (mpfr_init_set_str (fval, literal_value.as_string ().c_str (), 10,
+			 MPFR_RNDN)
+      != 0)
+    {
+      rust_error_at (expr.get_locus (), "bad number in literal");
+      return error_mark_node;
+    }
+
+  tree type = TyTyResolveCompile::compile (ctx, tyty);
+
+  // taken from:
+  // see go/gofrontend/expressions.cc:check_float_type
+  mpfr_exp_t exp = mpfr_get_exp (fval);
+  bool real_value_overflow = exp > TYPE_PRECISION (type);
+
+  REAL_VALUE_TYPE r1;
+  real_from_mpfr (&r1, fval, type, GMP_RNDN);
+  REAL_VALUE_TYPE r2;
+  real_convert (&r2, TYPE_MODE (type), &r1);
+
+  tree real_value = build_real (type, r2);
+  if (TREE_OVERFLOW (real_value) || real_value_overflow)
+    {
+      rust_error_at (expr.get_locus (),
+		     "decimal overflows the respective type %<%s%>",
+		     tyty->get_name ().c_str ());
+      return error_mark_node;
+    }
+
+  return real_value;
+}
+
+tree
+CompileExpr::compile_char_literal (const HIR::LiteralExpr &expr,
+				   const TyTy::BaseType *tyty)
+{
+  rust_assert (expr.get_lit_type () == HIR::Literal::CHAR);
+  const auto literal_value = expr.get_literal ();
+
+  // FIXME needs wchar_t
+  char c = literal_value.as_string ().c_str ()[0];
+  return ctx->get_backend ()->wchar_constant_expression (c);
+}
+
+tree
+CompileExpr::compile_byte_literal (const HIR::LiteralExpr &expr,
+				   const TyTy::BaseType *tyty)
+{
+  rust_assert (expr.get_lit_type () == HIR::Literal::BYTE);
+  const auto literal_value = expr.get_literal ();
+
+  tree type = TyTyResolveCompile::compile (ctx, tyty);
+  char c = literal_value.as_string ().c_str ()[0];
+  return build_int_cst (type, c);
+}
+
+tree
+CompileExpr::compile_string_literal (const HIR::LiteralExpr &expr,
+				     const TyTy::BaseType *tyty)
+{
+  rust_assert (expr.get_lit_type () == HIR::Literal::STRING);
+  const auto literal_value = expr.get_literal ();
+
+  auto base = ctx->get_backend ()->string_constant_expression (
+    literal_value.as_string ());
+  return ctx->get_backend ()->address_expression (base, expr.get_locus ());
+}
+
+tree
+CompileExpr::compile_byte_string_literal (const HIR::LiteralExpr &expr,
+					  const TyTy::BaseType *tyty)
+{
+  rust_assert (expr.get_lit_type () == HIR::Literal::BYTE_STRING);
+
+  // the type here is &[ty; capacity]
+  rust_assert (tyty->get_kind () == TyTy::TypeKind::REF);
+  const auto ref_tyty = static_cast<const TyTy::ReferenceType *> (tyty);
+  auto base_tyty = ref_tyty->get_base ();
+  rust_assert (base_tyty->get_kind () == TyTy::TypeKind::ARRAY);
+  auto array_tyty = static_cast<TyTy::ArrayType *> (base_tyty);
+
+  std::string value_str = expr.get_literal ().as_string ();
+  std::vector<tree> vals;
+  std::vector<unsigned long> indexes;
+  for (size_t i = 0; i < value_str.size (); i++)
+    {
+      char b = value_str.at (i);
+      tree bb = ctx->get_backend ()->char_constant_expression (b);
+      vals.push_back (bb);
+      indexes.push_back (i);
+    }
+
+  tree array_type = TyTyResolveCompile::compile (ctx, array_tyty);
+  tree constructed
+    = ctx->get_backend ()->array_constructor_expression (array_type, indexes,
+							 vals,
+							 expr.get_locus ());
+
+  return ctx->get_backend ()->address_expression (constructed,
+						  expr.get_locus ());
+}
+
+tree
+CompileExpr::type_cast_expression (tree type_to_cast_to, tree expr_tree,
+				   Location location)
+{
+  if (type_to_cast_to == error_mark_node || expr_tree == error_mark_node
+      || TREE_TYPE (expr_tree) == error_mark_node)
+    return error_mark_node;
+
+  if (ctx->get_backend ()->type_size (type_to_cast_to) == 0
+      || TREE_TYPE (expr_tree) == void_type_node)
+    {
+      // Do not convert zero-sized types.
+      return expr_tree;
+    }
+  else if (TREE_CODE (type_to_cast_to) == INTEGER_TYPE)
+    {
+      tree cast = fold (convert_to_integer (type_to_cast_to, expr_tree));
+      // FIXME check for TREE_OVERFLOW?
+      return cast;
+    }
+  else if (TREE_CODE (type_to_cast_to) == REAL_TYPE)
+    {
+      tree cast = fold (convert_to_real (type_to_cast_to, expr_tree));
+      // FIXME
+      // We might need to check that the tree is MAX val and thusly saturate it
+      // to inf. we can get the bounds and check the value if its >= or <= to
+      // the min and max bounds
+      //
+      // https://github.com/Rust-GCC/gccrs/issues/635
+      return cast;
+    }
+  else if (TREE_CODE (type_to_cast_to) == COMPLEX_TYPE)
+    {
+      return fold (convert_to_complex (type_to_cast_to, expr_tree));
+    }
+  else if (TREE_CODE (type_to_cast_to) == POINTER_TYPE
+	   && TREE_CODE (TREE_TYPE (expr_tree)) == INTEGER_TYPE)
+    {
+      return fold (convert_to_pointer (type_to_cast_to, expr_tree));
+    }
+  else if (TREE_CODE (type_to_cast_to) == RECORD_TYPE
+	   || TREE_CODE (type_to_cast_to) == ARRAY_TYPE)
+    {
+      return fold_build1_loc (location.gcc_location (), VIEW_CONVERT_EXPR,
+			      type_to_cast_to, expr_tree);
+    }
+
+  return fold_convert_loc (location.gcc_location (), type_to_cast_to,
+			   expr_tree);
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index dc4f90937c2..2f446217683 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -234,132 +234,41 @@ public:
 
   void visit (HIR::LiteralExpr &expr) override
   {
-    auto literal_value = expr.get_literal ();
+    TyTy::BaseType *tyty = nullptr;
+    if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+					 &tyty))
+      return;
+
     switch (expr.get_lit_type ())
       {
-	case HIR::Literal::BOOL: {
-	  bool bval = literal_value->as_string ().compare ("true") == 0;
-	  translated = ctx->get_backend ()->boolean_constant_expression (bval);
-	}
+      case HIR::Literal::BOOL:
+	translated = compile_bool_literal (expr, tyty);
 	return;
 
-	case HIR::Literal::INT: {
-	  mpz_t ival;
-	  if (mpz_init_set_str (ival, literal_value->as_string ().c_str (), 10)
-	      != 0)
-	    {
-	      rust_fatal_error (expr.get_locus (), "bad number in literal");
-	      return;
-	    }
-
-	  TyTy::BaseType *tyty = nullptr;
-	  if (!ctx->get_tyctx ()->lookup_type (
-		expr.get_mappings ().get_hirid (), &tyty))
-	    {
-	      rust_fatal_error (
-		expr.get_locus (),
-		"did not resolve type for this literal expr (HirId %d)",
-		expr.get_mappings ().get_hirid ());
-	      return;
-	    }
-
-	  tree type = TyTyResolveCompile::compile (ctx, tyty);
-	  translated
-	    = ctx->get_backend ()->integer_constant_expression (type, ival);
-	}
+      case HIR::Literal::INT:
+	translated = compile_integer_literal (expr, tyty);
 	return;
 
-	case HIR::Literal::FLOAT: {
-	  mpfr_t fval;
-	  if (mpfr_init_set_str (fval, literal_value->as_string ().c_str (), 10,
-				 MPFR_RNDN)
-	      != 0)
-	    {
-	      rust_fatal_error (expr.get_locus (),
-				"bad floating-point number in literal");
-	      return;
-	    }
-
-	  TyTy::BaseType *tyty = nullptr;
-	  if (!ctx->get_tyctx ()->lookup_type (
-		expr.get_mappings ().get_hirid (), &tyty))
-	    {
-	      rust_fatal_error (expr.get_locus (),
-				"did not resolve type for this literal expr");
-	      return;
-	    }
-
-	  tree type = TyTyResolveCompile::compile (ctx, tyty);
-	  translated
-	    = ctx->get_backend ()->float_constant_expression (type, fval);
-	}
+      case HIR::Literal::FLOAT:
+	translated = compile_float_literal (expr, tyty);
 	return;
 
-	case HIR::Literal::CHAR: {
-	  // FIXME needs wchar_t
-	  char c = literal_value->as_string ().c_str ()[0];
-	  translated = ctx->get_backend ()->wchar_constant_expression (c);
-	}
+      case HIR::Literal::CHAR:
+	translated = compile_char_literal (expr, tyty);
 	return;
 
-	case HIR::Literal::BYTE: {
-	  char c = literal_value->as_string ().c_str ()[0];
-	  translated = ctx->get_backend ()->char_constant_expression (c);
-	}
+      case HIR::Literal::BYTE:
+	translated = compile_byte_literal (expr, tyty);
 	return;
 
-	case HIR::Literal::STRING: {
-	  auto base = ctx->get_backend ()->string_constant_expression (
-	    literal_value->as_string ());
-	  translated
-	    = ctx->get_backend ()->address_expression (base, expr.get_locus ());
-	}
+      case HIR::Literal::STRING:
+	translated = compile_string_literal (expr, tyty);
 	return;
 
-	case HIR::Literal::BYTE_STRING: {
-	  TyTy::BaseType *tyty = nullptr;
-	  if (!ctx->get_tyctx ()->lookup_type (
-		expr.get_mappings ().get_hirid (), &tyty))
-	    {
-	      rust_error_at (expr.get_locus (),
-			     "did not resolve type for this byte string");
-	      return;
-	    }
-
-	  // the type here is &[ty; capacity]
-	  rust_assert (tyty->get_kind () == TyTy::TypeKind::REF);
-	  auto ref_tyty = static_cast<TyTy::ReferenceType *> (tyty);
-	  auto base_tyty = ref_tyty->get_base ();
-	  rust_assert (base_tyty->get_kind () == TyTy::TypeKind::ARRAY);
-	  auto array_tyty = static_cast<TyTy::ArrayType *> (base_tyty);
-
-	  std::string value_str = expr.get_literal ()->as_string ();
-	  std::vector<tree> vals;
-	  std::vector<unsigned long> indexes;
-	  for (size_t i = 0; i < value_str.size (); i++)
-	    {
-	      char b = value_str.at (i);
-	      tree bb = ctx->get_backend ()->char_constant_expression (b);
-	      vals.push_back (bb);
-	      indexes.push_back (i);
-	    }
-
-	  tree array_type = TyTyResolveCompile::compile (ctx, array_tyty);
-	  tree constructed = ctx->get_backend ()->array_constructor_expression (
-	    array_type, indexes, vals, expr.get_locus ());
-
-	  translated
-	    = ctx->get_backend ()->address_expression (constructed,
-						       expr.get_locus ());
-	}
-	return;
-
-      default:
-	rust_fatal_error (expr.get_locus (), "unknown literal");
+      case HIR::Literal::BYTE_STRING:
+	translated = compile_byte_string_literal (expr, tyty);
 	return;
       }
-
-    gcc_unreachable ();
   }
 
   void visit (HIR::AssignmentExpr &expr) override
@@ -502,20 +411,19 @@ public:
 
   void visit (HIR::TypeCastExpr &expr) override
   {
-    TyTy::BaseType *tyty_to_cast_to = nullptr;
+    TyTy::BaseType *tyty = nullptr;
     if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
-					 &tyty_to_cast_to))
+					 &tyty))
       {
-	translated = ctx->get_backend ()->error_expression ();
+	translated = error_mark_node;
 	return;
       }
 
-    auto type_to_cast_to = TyTyResolveCompile::compile (ctx, tyty_to_cast_to);
+    auto type_to_cast_to = TyTyResolveCompile::compile (ctx, tyty);
     auto casted_expr
       = CompileExpr::Compile (expr.get_casted_expr ().get (), ctx);
     translated
-      = ctx->get_backend ()->convert_expression (type_to_cast_to, casted_expr,
-						 expr.get_locus ());
+      = type_cast_expression (type_to_cast_to, casted_expr, expr.get_locus ());
   }
 
   void visit (HIR::IfExpr &expr) override
@@ -1067,9 +975,33 @@ protected:
 			     HIR::OperatorExpr &expr, tree lhs, tree rhs,
 			     HIR::Expr *lhs_expr, HIR::Expr *rhs_expr);
 
+  tree compile_bool_literal (const HIR::LiteralExpr &expr,
+			     const TyTy::BaseType *tyty);
+
+  tree compile_integer_literal (const HIR::LiteralExpr &expr,
+				const TyTy::BaseType *tyty);
+
+  tree compile_float_literal (const HIR::LiteralExpr &expr,
+			      const TyTy::BaseType *tyty);
+
+  tree compile_char_literal (const HIR::LiteralExpr &expr,
+			     const TyTy::BaseType *tyty);
+
+  tree compile_byte_literal (const HIR::LiteralExpr &expr,
+			     const TyTy::BaseType *tyty);
+
+  tree compile_string_literal (const HIR::LiteralExpr &expr,
+			       const TyTy::BaseType *tyty);
+
+  tree compile_byte_string_literal (const HIR::LiteralExpr &expr,
+				    const TyTy::BaseType *tyty);
+
+  tree type_cast_expression (tree type_to_cast_to, tree expr, Location locus);
+
 private:
   CompileExpr (Context *ctx)
-    : HIRCompileBase (ctx), translated (nullptr), capacity_expr (nullptr)
+    : HIRCompileBase (ctx), translated (error_mark_node),
+      capacity_expr (nullptr)
   {}
 
   tree translated;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 678455051cf..c1495d4a501 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -95,7 +95,8 @@ public:
 
   void accept_vis (HIRFullVisitor &vis) override;
 
-  Literal *get_literal () { return &literal; }
+  Literal &get_literal () { return literal; }
+  const Literal &get_literal () const { return literal; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h
index d1f71277754..19078165862 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold.h
@@ -354,7 +354,7 @@ public:
       {
 	case HIR::Literal::INT: {
 	  mpz_t ival;
-	  if (mpz_init_set_str (ival, literal_value->as_string ().c_str (), 10)
+	  if (mpz_init_set_str (ival, literal_value.as_string ().c_str (), 10)
 	      != 0)
 	    {
 	      rust_fatal_error (expr.get_locus (), "bad number in literal");
@@ -376,14 +376,14 @@ public:
 	return;
 
 	case HIR::Literal::BOOL: {
-	  bool bval = literal_value->as_string ().compare ("true") == 0;
+	  bool bval = literal_value.as_string ().compare ("true") == 0;
 	  folded = ctx->get_backend ()->boolean_constant_expression (bval);
 	}
 	return;
 
 	case HIR::Literal::FLOAT: {
 	  mpfr_t fval;
-	  if (mpfr_init_set_str (fval, literal_value->as_string ().c_str (), 10,
+	  if (mpfr_init_set_str (fval, literal_value.as_string ().c_str (), 10,
 				 MPFR_RNDN)
 	      != 0)
 	    {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 8de736db542..cb3aa6a5237 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -604,7 +604,7 @@ public:
 	case HIR::Literal::LitType::INT: {
 	  bool ok = false;
 
-	  switch (expr.get_literal ()->get_type_hint ())
+	  switch (expr.get_literal ().get_type_hint ())
 	    {
 	    case CORETYPE_I8:
 	      ok = context->lookup_builtin ("i8", &infered);
@@ -639,11 +639,11 @@ public:
 	      break;
 
 	    case CORETYPE_F32:
-	      expr.get_literal ()->set_lit_type (HIR::Literal::LitType::FLOAT);
+	      expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
 	      ok = context->lookup_builtin ("f32", &infered);
 	      break;
 	    case CORETYPE_F64:
-	      expr.get_literal ()->set_lit_type (HIR::Literal::LitType::FLOAT);
+	      expr.get_literal ().set_lit_type (HIR::Literal::LitType::FLOAT);
 	      ok = context->lookup_builtin ("f64", &infered);
 	      break;
 
@@ -661,7 +661,7 @@ public:
 	case HIR::Literal::LitType::FLOAT: {
 	  bool ok = false;
 
-	  switch (expr.get_literal ()->get_type_hint ())
+	  switch (expr.get_literal ().get_type_hint ())
 	    {
 	    case CORETYPE_F32:
 	      ok = context->lookup_builtin ("f32", &infered);
@@ -727,7 +727,7 @@ public:
 	  /* Capacity is the size of the string (number of chars).
 	     It is a constant, but for fold it to get a tree.  */
 	  std::string capacity_str
-	    = std::to_string (expr.get_literal ()->as_string ().size ());
+	    = std::to_string (expr.get_literal ().as_string ().size ());
 	  HIR::LiteralExpr literal_capacity (capacity_mapping, capacity_str,
 					     HIR::Literal::LitType::INT,
 					     PrimitiveCoreType::CORETYPE_USIZE,
diff --git a/gcc/rust/typecheck/rust-tycheck-dump.h b/gcc/rust/typecheck/rust-tycheck-dump.h
index c7219cd31d5..33a4b11539f 100644
--- a/gcc/rust/typecheck/rust-tycheck-dump.h
+++ b/gcc/rust/typecheck/rust-tycheck-dump.h
@@ -141,7 +141,7 @@ public:
 
   void visit (HIR::LiteralExpr &expr) override
   {
-    dump += expr.get_literal ()->as_string () + ":"
+    dump += expr.get_literal ().as_string () + ":"
 	    + type_string (expr.get_mappings ());
   }
 
diff --git a/gcc/rust/typecheck/rust-tyty-cast.h b/gcc/rust/typecheck/rust-tyty-cast.h
index aaa589beda3..07fedd0f878 100644
--- a/gcc/rust/typecheck/rust-tyty-cast.h
+++ b/gcc/rust/typecheck/rust-tyty-cast.h
@@ -444,7 +444,7 @@ public:
   void visit (FloatType &type) override
   {
     bool is_valid
-      = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL)
+      = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::INTEGRAL)
 	|| (base->get_infer_kind () == TyTy::InferType::InferTypeKind::FLOAT);
     if (is_valid)
       {
diff --git a/gcc/testsuite/rust/compile/issue-635-1.rs b/gcc/testsuite/rust/compile/issue-635-1.rs
new file mode 100644
index 00000000000..dc6a4c2eece
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-635-1.rs
@@ -0,0 +1,5 @@
+// { dg-additional-options "-w" }
+fn test() -> i32 {
+    return 10000000000000000000000000000000000000000000;
+    // { dg-error "integer overflows the respective type .i32." "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/issue-635-2.rs b/gcc/testsuite/rust/compile/issue-635-2.rs
new file mode 100644
index 00000000000..335218aa52c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-635-2.rs
@@ -0,0 +1,5 @@
+// { dg-additional-options "-w" }
+fn test() -> f32 {
+    return 10000000000000000000000000000000000000000000.0f32;
+    // { dg-error "decimal overflows the respective type .f32." "" { target *-*-* } .-1 }
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 11:58 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:58 [gcc/devel/rust/master] Add overflow checking on LiteralExpression Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).