diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-04-13 12:25:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-13 12:25:29 +0200 |
commit | 09588e93bbe486ce782de9fba604f5cd184ec446 (patch) | |
tree | 3d53506c44082f40aa43325260f6b363498f9613 /clang/lib/AST/ByteCode/Compiler.cpp | |
parent | beac727e48346efb84558696fb080b1bbd07e234 (diff) | |
download | llvm-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.cpp | 48 |
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> |