Skip to content

Commit 56453c3

Browse files
committed
LLVMCodeAnalyzer: Fix previous else branch
1 parent 149f832 commit 56453c3

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

src/engine/internal/llvm/llvmcodeanalyzer.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,21 @@ void LLVMCodeAnalyzer::analyzeScript(const LLVMInstructionList &script) const
3838
branch->listTypes = currentBranch->listTypes;
3939
currentBranch = branch.get();
4040
branches.push_back(std::move(branch));
41+
42+
assert(!currentBranch->isAtElse);
4143
} else if (isElse(ins)) {
4244
assert(!currentBranch->elseBranch);
4345

4446
// Enter else branch with type information from the previous branch
4547
Branch *previousBranch = branches[branches.size() - 2].get();
48+
49+
if (previousBranch->isAtElse) {
50+
previousBranch = previousBranch->elseBranch.get();
51+
assert(previousBranch);
52+
}
53+
4654
currentBranch->elseBranch = std::make_unique<Branch>();
55+
currentBranch->isAtElse = true;
4756
currentBranch = currentBranch->elseBranch.get();
4857
currentBranch->start = ins;
4958
currentBranch->variableTypes = previousBranch->variableTypes;
@@ -57,9 +66,13 @@ void LLVMCodeAnalyzer::analyzeScript(const LLVMInstructionList &script) const
5766
// Merge/override types
5867
Branch *previousBranch = branches[branches.size() - 2].get();
5968
Branch *primaryBranch = branches.back().get();
60-
6169
assert(primaryBranch);
6270

71+
if (previousBranch->isAtElse) {
72+
previousBranch = previousBranch->elseBranch.get();
73+
assert(previousBranch);
74+
}
75+
6376
if (primaryBranch && primaryBranch->elseBranch) {
6477
// The previous variable types can be ignored in if/else statements
6578
overrideVariableTypes(primaryBranch, previousBranch);

src/engine/internal/llvm/llvmcodeanalyzer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class LLVMCodeAnalyzer
2929
std::unordered_map<List *, Compiler::StaticType> listTypes;
3030

3131
std::unique_ptr<Branch> elseBranch;
32+
bool isAtElse = false; // whether we're currently processing the else branch
3233
};
3334

3435
void updateVariableType(Branch *branch, LLVMInstruction *ins, std::unordered_set<LLVMInstruction *> &typeAssignedInstructions, bool isWrite) const;

test/llvm/code_analyzer/variable_type_analysis.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,47 @@ TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, WriteInLoop)
896896
ASSERT_EQ(setVar->targetType, Compiler::StaticType::Unknown);
897897
}
898898

899+
TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, NestedIfStatements)
900+
{
901+
LLVMInstructionList list;
902+
Variable var("", "");
903+
904+
auto outerIf = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginIf, false);
905+
list.addInstruction(outerIf);
906+
907+
auto setVar1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, false);
908+
LLVMConstantRegister value1(Compiler::StaticType::Number, 1);
909+
setVar1->targetVariable = &var;
910+
setVar1->args.push_back({ Compiler::StaticType::Unknown, &value1 });
911+
list.addInstruction(setVar1);
912+
913+
auto outerElse = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginElse, false);
914+
list.addInstruction(outerElse);
915+
916+
auto innerIf = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginIf, false);
917+
list.addInstruction(innerIf);
918+
919+
auto innerElse = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginElse, false);
920+
list.addInstruction(innerElse);
921+
922+
auto innerIfEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndIf, false);
923+
list.addInstruction(innerIfEnd);
924+
925+
auto setVar2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, false);
926+
LLVMConstantRegister value2(Compiler::StaticType::String, "test");
927+
setVar2->targetVariable = &var;
928+
setVar2->args.push_back({ Compiler::StaticType::Unknown, &value2 });
929+
list.addInstruction(setVar2);
930+
931+
auto outerIfEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndIf, false);
932+
list.addInstruction(outerIfEnd);
933+
934+
m_analyzer->analyzeScript(list);
935+
936+
ASSERT_EQ(setVar1->targetType, Compiler::StaticType::Unknown);
937+
ASSERT_EQ(setVar2->targetType, Compiler::StaticType::Unknown);
938+
}
939+
899940
TEST_F(LLVMCodeAnalyzer_VariableTypeAnalysis, ComplexNestedControlFlow)
900941
{
901942
LLVMInstructionList list;

0 commit comments

Comments
 (0)