Commit a410e9e4 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[torque] Emit labels only if they are used.

This CL changes the generated C++ code for LabeledStatementBlocks to
only emit labels if they are used.

Prior to this CL, when a label was only used on one path of an
if constexpr expression, and not at all anywhere else,
the try/label construct would BIND a label that was not used,
causing a CSA verification error.

R=tebbi@chromium.org

Change-Id: Ia81a0cd081b84528c95bbdbdb98b9ab51928e13f
Reviewed-on: https://chromium-review.googlesource.com/1057247Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Commit-Queue: Simon Zünd <szuend@google.com>
Cr-Commit-Position: refs/heads/master@{#53173}
parent 632ceb4d
......@@ -1244,6 +1244,7 @@ class CodeAssemblerLabel {
~CodeAssemblerLabel();
inline bool is_bound() const { return bound_; }
inline bool is_used() const { return merge_count_ != 0; }
private:
friend class CodeAssembler;
......
......@@ -1408,6 +1408,11 @@ bool ImplementationVisitor::GenerateLabeledStatementBlocks(
bool live = false;
auto label_iterator = statement_labels.begin();
for (Statement* block : blocks) {
GenerateIndent();
source_out() << "if (" << (*label_iterator)->generated() << "->is_used())"
<< std::endl;
ScopedIndent indent(this);
GenerateLabelBind(*label_iterator++);
if (!Visit(block)->IsNever()) {
GenerateLabelGoto(merge_label);
......
......@@ -92,6 +92,15 @@ TEST(TestGotoLabelWithTwoParameters) {
ft.CheckCall(ft.true_value());
}
TEST(TestPartiallyUnusedLabel) {
Isolate* isolate(CcTest::InitIsolateOnce());
CodeAssemblerTester asm_tester(isolate, 0);
TestBuiltinsFromDSLAssembler m(asm_tester.state());
{ m.Return(m.TestPartiallyUnusedLabel()); }
FunctionTester ft(asm_tester.GenerateCode(), 0);
ft.CheckCall(ft.true_value());
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -82,4 +82,29 @@ macro TestGotoLabelWithTwoParameters(): Boolean {
}
}
macro LabelTestHelper4(flag: constexpr bool): never labels Label4, Label5 {
if constexpr (flag) goto Label4;
else goto Label5;
}
macro CallLabelTestHelper4(flag: constexpr bool): bool {
try {
LabelTestHelper4(flag) otherwise Label4, Label5;
}
label Label4 {
return true;
}
label Label5 {
return false;
}
}
macro TestPartiallyUnusedLabel(): Boolean {
let r1: bool = CallLabelTestHelper4(true);
let r2: bool = CallLabelTestHelper4(false);
if (r1 && !r2) return True;
else return False;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment