Skip to content

Commit ed0a9ef

Browse files
Attribute cleanup actions at the end of a function body to its closing brace [GH edgcpp#309]
1 parent 5bfce0a commit ed0a9ef

7 files changed

Lines changed: 70 additions & 6 deletions

File tree

‎src/Changes‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
Version 7.1
22

3+
10/15/26 [GH #309]
4+
Position of (lowered) cleanups at the end of a function body
5+
6+
The cleanup actions (e.g., destructor calls) performed when control reaches
7+
the end of a function body were attributed to the source position of the
8+
preceding statement instead of to that of the closing brace of the function
9+
body. That is now fixed. For example:
10+
11+
int v = 0;
12+
struct D { ~D() { v = v + 1; } };
13+
void f() {
14+
D d;
15+
v = 2;
16+
} // The call of d's destructor is now positioned on this line.
17+
// Previously it was positioned on the line with "v = 2;" above.
18+
19+
320
10/16/26 [GH #302]
421
Incorrect order of base-class initializers in class template
522

‎src/lower_il.c‎

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19288,12 +19288,27 @@ Lower an stmk_return statement.
1928819288
} /* if */
1928919289
if (any_cleanup_on_return) {
1929019290
/* Generate any cleanup actions required on exit from the routine. */
19291-
if (make_block) {
19292-
/* Turn the return into a block so that code can be inserted
19293-
in front of the return. */
19294-
turn_branch_into_block(statement, &insert_location, &return_statement);
19295-
} /* if */
19296-
gen_cleanup_actions(innermost_function_scope->lifetime, &insert_location);
19291+
{ Value_saver<a_source_position> saved_code_pos(&code_pos_for_lowering);
19292+
Value_saver<a_source_position> saved_error_position(&error_position);
19293+
19294+
if (statement->compiler_generated && statement->position.seq == 0) {
19295+
a_statement_ptr assoc_block = innermost_function_scope->assoc_block;
19296+
if (assoc_block != NULL &&
19297+
assoc_block->kind == stmk_block &&
19298+
assoc_block->variant.block.extra_info->final_position.seq != 0) {
19299+
code_pos_for_lowering = assoc_block->variant.block.extra_info
19300+
->final_position;
19301+
error_position = code_pos_for_lowering;
19302+
} /* if */
19303+
} /* if */
19304+
if (make_block) {
19305+
/* Turn the return into a block so that code can be inserted
19306+
in front of the return. */
19307+
turn_branch_into_block(statement, &insert_location, &return_statement);
19308+
} /* if */
19309+
gen_cleanup_actions(innermost_function_scope->lifetime,
19310+
&insert_location);
19311+
}
1929719312
reset_cleanup_state_at_transfer_of_control(return_statement, statement);
1929819313
} /* if */
1929919314
/* Maintain a list of all returns in the routine so that epilogue code
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
gh-309.sft.cpp:fp:-DTEST_NUMBER=1 --g++:REQUIREMENTS NOT MET:
2+
gh-309.sft.cpp:fp:-DTEST_NUMBER=2 --g++ --no_exceptions:REQUIREMENTS NOT MET:
13
immediate-pragma-lost.sft.cpp:cppbe:-DTEST_NUMBER=1:PASS:
24
pragma-il-class-no-lowering.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:
35
pragma-il-class.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
gh-309.sft.cpp:fp:-DTEST_NUMBER=1 --g++:REQUIREMENTS NOT MET:
2+
gh-309.sft.cpp:fp:-DTEST_NUMBER=2 --g++ --no_exceptions:REQUIREMENTS NOT MET:
13
immediate-pragma-lost.sft.cpp:cppbe:-DTEST_NUMBER=1:PASS:
24
pragma-il-class-no-lowering.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:
35
pragma-il-class.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fe_only -DTEST_NUMBER=1 --g++ Test_name.c
2+
destructor call on line 14
3+
destructor call on line 18
4+
destructor call on line 20
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fe_only -DTEST_NUMBER=2 --g++ --no_exceptions Test_name.c
2+
destructor call on line 14
3+
destructor call on line 18
4+
destructor call on line 20
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//type:fp
2+
//options:--g++:--g++ --no_exceptions
3+
//require:BACK_END_IS_C_GEN_BE 1
4+
//filter:awk '/^#(line)? [0-9]+/ { line = $2; next } /_ZN1DD1Ev\(\(/ { print "destructor call on line " line } { line++ }' Test_name.int.c
5+
int sink;
6+
7+
struct D {
8+
~D();
9+
};
10+
11+
void f() {
12+
D d;
13+
sink = 1;
14+
} // The destructor call was previously attributed to the line above.
15+
16+
void g(bool b) {
17+
D d;
18+
if (b) return;
19+
sink = 2;
20+
} // The destructor call was previously attributed to the line above.

0 commit comments

Comments
 (0)