aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Compiler.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-04-13 12:25:29 +0200
committerGitHub <noreply@github.com>2025-04-13 12:25:29 +0200
commit09588e93bbe486ce782de9fba604f5cd184ec446 (patch)
tree3d53506c44082f40aa43325260f6b363498f9613 /clang/lib/AST/ByteCode/Compiler.cpp
parentbeac727e48346efb84558696fb080b1bbd07e234 (diff)
downloadllvm-09588e93bbe486ce782de9fba604f5cd184ec446.zip
llvm-09588e93bbe486ce782de9fba604f5cd184ec446.tar.gz
llvm-09588e93bbe486ce782de9fba604f5cd184ec446.tar.bz2
[clang][bytecode] Fix an inconsistency with loop condition jumps (#135530)
When emitting the jump for e.g. a for loop condition, we used to jump out of the CondScope, leaving the scope initialized, because we skipped the corresponding Destroy opcode. If that loop was in a loop itself, that outer loop could then iterate once more, leading to us initializing a scope that was still initialized. Fix this by also destroying the scope after the EndLabel.
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp48
1 files changed, 24 insertions, 24 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 86b4358..2e22c85 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5431,39 +5431,39 @@ bool Compiler<Emitter>::visitForStmt(const ForStmt *S) {
this->fallthrough(CondLabel);
this->emitLabel(CondLabel);
- {
- LocalScope<Emitter> CondScope(this);
- if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
- if (!visitDeclStmt(CondDecl))
- return false;
-
- if (Cond) {
- if (!this->visitBool(Cond))
- return false;
- if (!this->jumpFalse(EndLabel))
- return false;
- }
-
- if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
- return false;
-
- if (Body && !this->visitStmt(Body))
+ // Start of loop body.
+ LocalScope<Emitter> CondScope(this);
+ if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
+ if (!visitDeclStmt(CondDecl))
return false;
- this->fallthrough(IncLabel);
- this->emitLabel(IncLabel);
- if (Inc && !this->discard(Inc))
+ if (Cond) {
+ if (!this->visitBool(Cond))
return false;
-
- if (!CondScope.destroyLocals())
+ if (!this->jumpFalse(EndLabel))
return false;
}
+ if (!this->maybeEmitDeferredVarInit(S->getConditionVariable()))
+ return false;
+
+ if (Body && !this->visitStmt(Body))
+ return false;
+
+ this->fallthrough(IncLabel);
+ this->emitLabel(IncLabel);
+ if (Inc && !this->discard(Inc))
+ return false;
+
+ if (!CondScope.destroyLocals())
+ return false;
if (!this->jump(CondLabel))
return false;
+ // End of loop body.
- this->fallthrough(EndLabel);
this->emitLabel(EndLabel);
- return true;
+ // If we jumped out of the loop above, we still need to clean up the condition
+ // scope.
+ return CondScope.destroyLocals();
}
template <class Emitter>