2248aed9e350 — Leonard Ritter a month ago
* fixed accidental double dropping of values; expression blocks whose result was noreturn still attempted to clean up the scope, which had already been cleaned up
2 files changed, 24 insertions(+), 6 deletions(-)

M src/prover.cpp
M testing/test_borrowing.sc
M src/prover.cpp +7 -6
@@ 751,12 751,13 @@ static SCOPES_RESULT(TypedValueRef) move
     int retdepth, TypedValueRef result, const char *by) {
     SCOPES_RESULT_TYPE(TypedValueRef);
     TypedValues values;
-    if (is_returning_value(result->get_type())
-        && split_return_values(values, result)) {
-        SCOPES_CHECK_RESULT(move_merge_values(ctx, result, retdepth, values, by));
-        result = ref(result.anchor(), ArgumentList::from(values));
-    } else {
-        SCOPES_CHECK_RESULT(move_merge_values(ctx, result, retdepth, values, by));
+    if (is_returning_value(result->get_type())) {
+        if (split_return_values(values, result)) {
+            SCOPES_CHECK_RESULT(move_merge_values(ctx, result, retdepth, values, by));
+            result = ref(result.anchor(), ArgumentList::from(values));
+        } else {
+            SCOPES_CHECK_RESULT(move_merge_values(ctx, result, retdepth, values, by));
+        }
     }
     return result;
 }

          
M testing/test_borrowing.sc +17 -0
@@ 559,4 559,21 @@ do
     parse (nullof M)
     parse2 (nullof M)
 
+# regression: return in a do-block or label causes double free
+     produces: assertion failed: (_refcount >= 0)
+fn testfunc ()
+    label ok
+        label ok2
+            merge ok (One 303)
+    fn testf ()
+        do
+
+            return (One 304)
+                do
+                    return (One 303)
+    testf;
+    ;
+testfunc;
+One.test-refcount-balanced;
+
 ;
  No newline at end of file