fortrangoingonforty/armfortas / b9065ea

Browse files

Honor descriptor-arg mask in proc-pointer component call dispatch

Authored by espadonne
Committed by mfwolffe
SHA
b9065ea1962d466ebf459f05f30a4b54606d4d5d
Parents
afd4318
Tree
8d45d6c

1 changed file

StatusFile+-
M src/ir/lower/expr.rs 42 11
src/ir/lower/expr.rsmodified
@@ -2024,23 +2024,54 @@ pub(crate) fn lower_expr_full(
20242024
                                         |k| callee_return_ir_type(st, k),
20252025
                                     )
20262026
                                     .unwrap_or(IrType::Int(IntWidth::I32));
2027
+                                    // Honor the abstract-interface descriptor
2028
+                                    // mask when forwarding actuals.  Without
2029
+                                    // this, an assumed-shape dummy
2030
+                                    // (`real(8), intent(in) :: x(:)`) received
2031
+                                    // only a base data pointer in place of
2032
+                                    // the descriptor — the callee then read
2033
+                                    // dims/rank out of the array elements'
2034
+                                    // bytes and segfaulted (stdlib's iterative
2035
+                                    // solvers all dispatch dot_product through
2036
+                                    // a procedure-pointer field this way).
2037
+                                    let callee_descriptor_args =
2038
+                                        first_procedure_lookup(&abi_lookup_keys, |k| {
2039
+                                            descriptor_params
2040
+                                                .and_then(|m| cached_param_mask_for_lookup(st, m, k))
2041
+                                        });
20272042
                                     let mut arg_vals: Vec<ValueId> =
20282043
                                         Vec::with_capacity(args.len());
2029
-                                    for arg in args {
2044
+                                    for (i, arg) in args.iter().enumerate() {
20302045
                                         if let crate::ast::expr::SectionSubscript::Element(
20312046
                                             e,
20322047
                                         ) = &arg.value
20332048
                                         {
2034
-                                            arg_vals.push(lower_arg_by_ref_full(
2035
-                                                b,
2036
-                                                locals,
2037
-                                                e,
2038
-                                                st,
2039
-                                                type_layouts,
2040
-                                                internal_funcs,
2041
-                                                contained_host_refs,
2042
-                                                descriptor_params,
2043
-                                            ));
2049
+                                            let wants_descriptor = callee_descriptor_args
2050
+                                                .as_ref()
2051
+                                                .map(|mask| mask.get(i).copied().unwrap_or(false))
2052
+                                                .unwrap_or(false);
2053
+                                            let v = if wants_descriptor {
2054
+                                                lower_arg_descriptor(
2055
+                                                    b,
2056
+                                                    locals,
2057
+                                                    e,
2058
+                                                    st,
2059
+                                                    type_layouts,
2060
+                                                    false,
2061
+                                                )
2062
+                                            } else {
2063
+                                                lower_arg_by_ref_full(
2064
+                                                    b,
2065
+                                                    locals,
2066
+                                                    e,
2067
+                                                    st,
2068
+                                                    type_layouts,
2069
+                                                    internal_funcs,
2070
+                                                    contained_host_refs,
2071
+                                                    descriptor_params,
2072
+                                                )
2073
+                                            };
2074
+                                            arg_vals.push(v);
20442075
                                         }
20452076
                                     }
20462077
                                     return b.call(