aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-10-22 13:32:20 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-10-22 13:32:20 +0100
commite0b43ccd05b72f6c7402b87eeeb8e26d18bef92b (patch)
tree6c94e2aa77e6e23610963dc793c6e17ea7de23f9
parent8e6c5a32b6e2c1ade6f1a835be2c2a26788db544 (diff)
downloadgcc-e0b43ccd05b72f6c7402b87eeeb8e26d18bef92b.zip
gcc-e0b43ccd05b72f6c7402b87eeeb8e26d18bef92b.tar.gz
gcc-e0b43ccd05b72f6c7402b87eeeb8e26d18bef92b.tar.bz2
Add missing coercion site code to MethodCallExpr's
Arguments to methods are coercion sites and may have implicit conversions to be performed this adds this missing code for this case. Fixes #755
-rw-r--r--gcc/rust/backend/rust-compile.cc28
-rw-r--r--gcc/testsuite/rust/execute/torture/trait10.rs43
2 files changed, 65 insertions, 6 deletions
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index f97f701..40e2f86 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -451,8 +451,6 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
}
}
- std::vector<Bexpression *> args;
-
// lookup the autoderef mappings
std::vector<Resolver::Adjustment> *adjustments = nullptr;
ok = ctx->get_tyctx ()->lookup_autoderef_mappings (
@@ -478,13 +476,31 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
break;
}
}
- args.push_back (self);
+
+ std::vector<Bexpression *> args;
+ args.push_back (self); // adjusted self
// normal args
- for (auto &argument : expr.get_arguments ())
+ for (size_t i = 0; i < expr.get_arguments ().size (); i++)
{
- Bexpression *compiled_expr = CompileExpr::Compile (argument.get (), ctx);
- args.push_back (compiled_expr);
+ auto &argument = expr.get_arguments ().at (i);
+ auto rvalue = CompileExpr::Compile (argument.get (), ctx);
+
+ // assignments are coercion sites so lets convert the rvalue if
+ // necessary, offset from the already adjusted implicit self
+ bool ok;
+ TyTy::BaseType *expected = fntype->param_at (i + 1).second;
+
+ TyTy::BaseType *actual = nullptr;
+ ok = ctx->get_tyctx ()->lookup_type (
+ argument->get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ // coerce it if required
+ rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
+
+ // add it to the list
+ args.push_back (rvalue);
}
auto fncontext = ctx->peek_fn ();
diff --git a/gcc/testsuite/rust/execute/torture/trait10.rs b/gcc/testsuite/rust/execute/torture/trait10.rs
new file mode 100644
index 0000000..615df423
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/trait10.rs
@@ -0,0 +1,43 @@
+/* { dg-output "123\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+struct Foo(i32);
+trait Bar {
+ fn baz(&self);
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}
+
+impl Bar for Foo {
+ fn baz(&self) {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, self.0);
+ }
+ }
+}
+
+struct S;
+impl S {
+ fn dynamic_dispatch(self, t: &dyn Bar) {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ t.baz();
+ }
+}
+
+pub fn main() -> i32 {
+ let a;
+ a = &Foo(123);
+
+ let b;
+ b = S;
+
+ b.dynamic_dispatch(a);
+
+ 0
+}