]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix ICE for invalid const capacity expression handling
authorPhilip Herron <herron.philip@googlemail.com>
Wed, 17 Sep 2025 13:24:38 +0000 (14:24 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 20:30:51 +0000 (21:30 +0100)
When we have an invalid capacity expression we can't try to then also
const fold it as GCC will assert on invalid conversions.

Fixes Rust-GCC#4168

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): check for invalid capacity

gcc/testsuite/ChangeLog:

* rust/compile/issue-4168.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/typecheck/rust-hir-type-check-type.cc
gcc/testsuite/rust/compile/issue-4168.rs [new file with mode: 0644]

index dfefae8bef3e0c4ea41359b05fd0277780b84e38..833ad92db59845893fb9ba2bb790592fec8a68ca 100644 (file)
@@ -720,19 +720,32 @@ TypeCheckType::visit (HIR::ArrayType &type)
   else
     {
       HirId size_id = type.get_size_expr ().get_mappings ().get_hirid ();
-      unify_site (size_id, TyTy::TyWithLocation (expected_ty),
-                 TyTy::TyWithLocation (capacity_type,
-                                       type.get_size_expr ().get_locus ()),
-                 type.get_size_expr ().get_locus ());
+      TyTy::BaseType *result
+       = unify_site (size_id, TyTy::TyWithLocation (expected_ty),
+                     TyTy::TyWithLocation (capacity_type,
+                                           type.get_size_expr ().get_locus ()),
+                     type.get_size_expr ().get_locus ());
 
-      auto ctx = Compile::Context::get ();
-      tree capacity_expr = Compile::HIRCompileBase::query_compile_const_expr (
-       ctx, capacity_type, type.get_size_expr ());
-
-      const_type = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
-                                       expected_ty, capacity_expr, {},
-                                       type.get_size_expr ().get_locus (),
-                                       size_id, size_id);
+      if (result->is<TyTy::ErrorType> ())
+       {
+         const_type
+           = new TyTy::ConstType (TyTy::ConstType::ConstKind::Error, "",
+                                  expected_ty, error_mark_node, {},
+                                  type.get_size_expr ().get_locus (), size_id,
+                                  size_id);
+       }
+      else
+       {
+         auto ctx = Compile::Context::get ();
+         tree capacity_expr
+           = Compile::HIRCompileBase::query_compile_const_expr (
+             ctx, capacity_type, type.get_size_expr ());
+
+         const_type = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
+                                           "", expected_ty, capacity_expr, {},
+                                           type.get_size_expr ().get_locus (),
+                                           size_id, size_id);
+       }
     }
 
   translated
diff --git a/gcc/testsuite/rust/compile/issue-4168.rs b/gcc/testsuite/rust/compile/issue-4168.rs
new file mode 100644 (file)
index 0000000..abb1190
--- /dev/null
@@ -0,0 +1,7 @@
+const fn add(x: usize, y: usize) -> i32 {
+    add + y
+    // { dg-error "cannot apply operator .+. to types fn .x usize,y usize,. -> i32 and usize" "" { target *-*-* } .-1 }
+}
+const ARR: [i32; add(1, 2)] = [5, 6, 1];
+// { dg-error "mismatched types, expected .usize. but got .i32. .E0308." "" { target *-*-* } .-1 }
+// { dg-error "mismatched types" "" { target *-*-* } .-2 }