-
Notifications
You must be signed in to change notification settings - Fork 161
Open
Description
If I create an object that requires cleanup in the condition of a for-loop, the cleanup is created in the wrong scope.
#include <iostream>
struct Struk {
Struk(int i) : i(i) { std::cout << "Struk(" << i << ")\n"; }
~Struk() { std::cout << "~Struk()\n"; }
operator bool() { return i < 10; }
private:
int i;
};
int main() {
for (int i = 0; Struk a{i}; ++i) {
}
}
When compiled with -fno-exceptions
is represented as:
cir.func dso_local @main() -> !s32i {
%0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
cir.scope {
%2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["i", init] {alignment = 4 : i64}
%3 = cir.alloca !rec_Struk, !cir.ptr<!rec_Struk>, ["a", init] {alignment = 4 : i64}
%4 = cir.const #cir.int<0> : !s32i
cir.store align(4) %4, %2 : !s32i, !cir.ptr<!s32i>
cir.for : cond {
%5 = cir.load align(4) %2 : !cir.ptr<!s32i>, !s32i
cir.call @_ZN5StrukC2Ei(%3, %5) : (!cir.ptr<!rec_Struk>, !s32i) -> ()
%6 = cir.call @_ZN5StrukcvbEv(%3) : (!cir.ptr<!rec_Struk>) -> !cir.bool
cir.condition(%6)
} body {
cir.yield
} step {
%5 = cir.load align(4) %2 : !cir.ptr<!s32i>, !s32i
%6 = cir.unary(inc, %5) nsw : !s32i, !s32i
cir.store align(4) %6, %2 : !s32i, !cir.ptr<!s32i>
cir.yield
}
cir.call @_ZN5StrukD2Ev(%3) : (!cir.ptr<!rec_Struk>) -> ()
}
%1 = cir.load %0 : !cir.ptr<!s32i>, !s32i
cir.return %1 : !s32i
}
The Struk
constructor is correctly called each time the condition is evaluated, but the destructor is only called once, at the end of the loop.
https://godbolt.org/z/sbW7hEjGa
An equivalent problem also occurs for a variable declared in the condition of a while loop.
bcardosolopes
Metadata
Metadata
Assignees
Labels
No labels