fortrangoingonforty/armfortas / 50df16a

Browse files

Test complex scalar/array/field assignment from int promotes via buffer

Authored by espadonne
Committed by mfwolffe
SHA
50df16a87ce6a48d68c84f3fe251631decdaa3fc
Parents
7e968c9
Tree
8d39f81

1 changed file

StatusFile+-
M tests/cli_driver.rs 43 0
tests/cli_driver.rsmodified
@@ -13853,6 +13853,49 @@ fn inline_array_intrinsic_in_print_walks_descriptor_elements() {
1385313853
     let _ = std::fs::remove_file(&src);
1385413854
 }
1385513855
 
13856
+#[test]
13857
+fn complex_scalar_assigned_from_integer_promotes_via_buffer_not_pointer_cast() {
13858
+    // F2018 §10.2.1.3: complex variables can be assigned a scalar of
13859
+    // numeric type — the right-hand side is promoted to complex with
13860
+    // imag=0. Our complex-assign lowering used to memcpy the 8/16
13861
+    // bytes from the RHS treating its register-resident value as if
13862
+    // it were a pointer to a [fN x 2] buffer; for an integer/real RHS
13863
+    // that meant memcpy(c, value_as_ptr, 8) and faulted on the bogus
13864
+    // address. LAPACK CGEEV's `work(1) = maxwrk` (complex(sp) = i32)
13865
+    // SEGV'd on this exact path, taking out every example_eig*,
13866
+    // example_pseudoinverse, example_solve_{cg,bicgstab,pcg}, etc.
13867
+    // The fix materializes a fresh [fN x 2] buffer when the RHS isn't
13868
+    // already complex — covers scalar `c = i`, array element `a(k)=i`,
13869
+    // and derived-type field `dt%c = i`.
13870
+    let src = write_program(
13871
+        "program t\n  implicit none\n  complex(4) :: c, a(5)\n  type :: tt\n    complex(4) :: f\n  end type\n  type(tt) :: dt\n  integer :: i\n  i = 42\n  c = i\n  a(3) = i\n  dt%f = i\n  if (abs(real(c) - 42.0) > 1.0e-5) error stop 1\n  if (abs(aimag(c)) > 1.0e-5) error stop 2\n  if (abs(real(a(3)) - 42.0) > 1.0e-5) error stop 3\n  if (abs(aimag(a(3))) > 1.0e-5) error stop 4\n  if (abs(real(dt%f) - 42.0) > 1.0e-5) error stop 5\n  if (abs(aimag(dt%f)) > 1.0e-5) error stop 6\n  print *, 'ok'\nend program\n",
13872
+        "f90",
13873
+    );
13874
+    let out = unique_path("cmplx_int_assign", "bin");
13875
+    let compile = Command::new(compiler("armfortas"))
13876
+        .args([src.to_str().unwrap(), "-o", out.to_str().unwrap()])
13877
+        .output()
13878
+        .expect("complex<-int compile failed");
13879
+    assert!(
13880
+        compile.status.success(),
13881
+        "complex<-int should compile: {}",
13882
+        String::from_utf8_lossy(&compile.stderr)
13883
+    );
13884
+    let run = Command::new(&out).output().expect("complex<-int run failed");
13885
+    assert!(
13886
+        run.status.success(),
13887
+        "complex<-int should pass: status={:?} stdout={} stderr={}",
13888
+        run.status,
13889
+        String::from_utf8_lossy(&run.stdout),
13890
+        String::from_utf8_lossy(&run.stderr)
13891
+    );
13892
+    let stdout = String::from_utf8_lossy(&run.stdout);
13893
+    assert!(stdout.contains("ok"), "expected ok, got: {}", stdout);
13894
+
13895
+    let _ = std::fs::remove_file(&out);
13896
+    let _ = std::fs::remove_file(&src);
13897
+}
13898
+
1385613899
 #[test]
1385713900
 fn complex_dp_array_constructor_preserves_imaginary_lane_in_assignment() {
1385813901
     // F2018 §7.8: array-constructor element values for complex(dp)