fortrangoingonforty/armfortas / 5537df7

Browse files

Test ALLOCATE STAT= integer(int64) writeback

Authored by espadonne
Committed by mfwolffe
SHA
5537df78d56510cc985237e752ec08ae9d7cf629
Parents
006f299
Tree
d040833

1 changed file

StatusFile+-
M tests/cli_driver.rs 37 0
tests/cli_driver.rsmodified
@@ -28623,6 +28623,43 @@ fn cmplx_whole_array_with_kind_keyword_returns_correct_kind_descriptor() {
2862328623
     let _ = std::fs::remove_file(&src);
2862428624
 }
2862528625
 
28626
+#[test]
28627
+fn allocate_stat_int64_writes_back_to_user_variable() {
28628
+    // F2018 §9.7.1.3: STAT= variable receives the allocate status.
28629
+    // Runtime writes an i32; when the user's variable is a wider
28630
+    // integer kind (e.g. integer(int64), as in stdlib_sorting where
28631
+    // int_index = int64), the i32 result must be sign-extended back
28632
+    // into the user's slot. Without the writeback the upper 4 bytes
28633
+    // were stack garbage, so `if (stat /= 0)` read non-zero on
28634
+    // success and triggered "Allocation of array buffer failed."
28635
+    // in stdlib_sorting_sort_adjoint at line 121 (matched stdlib
28636
+    // sort_index + sort_adjoint examples).
28637
+    let src = write_program(
28638
+        "program p\n  implicit none\n  integer, parameter :: i64 = selected_int_kind(18)\n  integer(i64) :: stat\n  integer, allocatable :: buf(:)\n  allocate(buf(0:6), stat=stat)\n  if (stat /= 0_i64) error stop 1\n  deallocate(buf, stat=stat)\n  if (stat /= 0_i64) error stop 2\n  print *, 'ok'\nend program\n",
28639
+        "f90",
28640
+    );
28641
+    let out = unique_path("alloc_stat_int64", "bin");
28642
+    let compile = Command::new(compiler("armfortas"))
28643
+        .args([src.to_str().unwrap(), "-o", out.to_str().unwrap()])
28644
+        .output()
28645
+        .expect("alloc-stat-int64 compile failed to spawn");
28646
+    assert!(
28647
+        compile.status.success(),
28648
+        "alloc-stat-int64 compile failed: {}",
28649
+        String::from_utf8_lossy(&compile.stderr)
28650
+    );
28651
+    let run = Command::new(&out).output().expect("alloc-stat-int64 run failed");
28652
+    assert!(
28653
+        run.status.success() && String::from_utf8_lossy(&run.stdout).contains("ok"),
28654
+        "alloc-stat-int64 run failed: status={:?} stdout={} stderr={}",
28655
+        run.status,
28656
+        String::from_utf8_lossy(&run.stdout),
28657
+        String::from_utf8_lossy(&run.stderr)
28658
+    );
28659
+    let _ = std::fs::remove_file(&out);
28660
+    let _ = std::fs::remove_file(&src);
28661
+}
28662
+
2862628663
 #[test]
2862728664
 fn rank2_section_with_vector_subscript_gathers_into_fresh_descriptor() {
2862828665
     // F2018 §9.5.3.3: a section like `A(:, pivots)` where one subscript