@@ -1308,6 +1308,150 @@ TEST(LLVMTypeAnalyzer_VariableTypeAfterBranch, NestedLoopWithTypeChangeBeforeLoo
13081308 ASSERT_EQ (analyzer.variableTypeAfterBranch (&varPtr, outerLoop.get (), Compiler::StaticType::Number), Compiler::StaticType::Unknown);
13091309}
13101310
1311+ TEST (LLVMTypeAnalyzer_VariableTypeAfterBranch, IfStatementInLoopWithTypeChangeBeforeLoop_TypeChangeInIfBranch)
1312+ {
1313+ LLVMTypeAnalyzer analyzer;
1314+ LLVMInstructionList list;
1315+ LLVMVariablePtr varPtr;
1316+ Variable var (" " , " " );
1317+ varPtr.var = &var;
1318+
1319+ // Outer loop begin
1320+ auto outerLoop = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginRepeatUntilLoop, nullptr , false );
1321+ list.addInstruction (outerLoop);
1322+
1323+ // Variable write inside outer loop
1324+ auto setVar1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, nullptr , false );
1325+ LLVMConstantRegister value1 (Compiler::StaticType::String, " test" );
1326+ setVar1->workVariable = &var;
1327+ setVar1->args .push_back ({ Compiler::StaticType::Unknown, &value1 });
1328+ list.addInstruction (setVar1);
1329+
1330+ // Inner if statement begin
1331+ auto innerIf = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginIf, nullptr , false );
1332+ list.addInstruction (innerIf);
1333+
1334+ // Variable write inside inner if statement if branch
1335+ auto setVar2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, nullptr , false );
1336+ LLVMConstantRegister value2 (Compiler::StaticType::Number, 5 );
1337+ setVar2->workVariable = &var;
1338+ setVar2->args .push_back ({ Compiler::StaticType::Unknown, &value2 });
1339+ list.addInstruction (setVar2);
1340+
1341+ // Inner if statement else branch begin
1342+ auto innerElse = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginElse, nullptr , false );
1343+ list.addInstruction (innerElse);
1344+
1345+ // Inner if statement end
1346+ auto innerEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndIf, nullptr , false );
1347+ list.addInstruction (innerEnd);
1348+
1349+ // Outer loop end
1350+ auto outerEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndLoop, nullptr , false );
1351+ list.addInstruction (outerEnd);
1352+
1353+ // Returns unknown type because if statements can be skipped
1354+ ASSERT_EQ (analyzer.variableTypeAfterBranch (&varPtr, outerLoop.get (), Compiler::StaticType::Number), Compiler::StaticType::Unknown);
1355+ }
1356+
1357+ TEST (LLVMTypeAnalyzer_VariableTypeAfterBranch, IfStatementInLoopWithTypeChangeBeforeLoop_TypeChangeInElseBranch)
1358+ {
1359+ LLVMTypeAnalyzer analyzer;
1360+ LLVMInstructionList list;
1361+ LLVMVariablePtr varPtr;
1362+ Variable var (" " , " " );
1363+ varPtr.var = &var;
1364+
1365+ // Outer loop begin
1366+ auto outerLoop = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginRepeatUntilLoop, nullptr , false );
1367+ list.addInstruction (outerLoop);
1368+
1369+ // Variable write inside outer loop
1370+ auto setVar1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, nullptr , false );
1371+ LLVMConstantRegister value1 (Compiler::StaticType::String, " test" );
1372+ setVar1->workVariable = &var;
1373+ setVar1->args .push_back ({ Compiler::StaticType::Unknown, &value1 });
1374+ list.addInstruction (setVar1);
1375+
1376+ // Inner if statement begin
1377+ auto innerIf = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginIf, nullptr , false );
1378+ list.addInstruction (innerIf);
1379+
1380+ // Inner if statement else branch begin
1381+ auto innerElse = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginElse, nullptr , false );
1382+ list.addInstruction (innerElse);
1383+
1384+ // Variable write inside inner if statement else branch
1385+ auto setVar2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, nullptr , false );
1386+ LLVMConstantRegister value2 (Compiler::StaticType::Number, 5 );
1387+ setVar2->workVariable = &var;
1388+ setVar2->args .push_back ({ Compiler::StaticType::Unknown, &value2 });
1389+ list.addInstruction (setVar2);
1390+
1391+ // Inner if statement end
1392+ auto innerEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndIf, nullptr , false );
1393+ list.addInstruction (innerEnd);
1394+
1395+ // Outer loop end
1396+ auto outerEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndLoop, nullptr , false );
1397+ list.addInstruction (outerEnd);
1398+
1399+ // Returns unknown type because if statements can be skipped
1400+ ASSERT_EQ (analyzer.variableTypeAfterBranch (&varPtr, outerLoop.get (), Compiler::StaticType::Number), Compiler::StaticType::Unknown);
1401+ }
1402+
1403+ TEST (LLVMTypeAnalyzer_VariableTypeAfterBranch, IfStatementInLoopWithTypeChangeBeforeLoop_TypeChangeInBothBranches)
1404+ {
1405+ LLVMTypeAnalyzer analyzer;
1406+ LLVMInstructionList list;
1407+ LLVMVariablePtr varPtr;
1408+ Variable var (" " , " " );
1409+ varPtr.var = &var;
1410+
1411+ // Outer loop begin
1412+ auto outerLoop = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginRepeatUntilLoop, nullptr , false );
1413+ list.addInstruction (outerLoop);
1414+
1415+ // Variable write inside outer loop
1416+ auto setVar1 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, nullptr , false );
1417+ LLVMConstantRegister value1 (Compiler::StaticType::String, " test" );
1418+ setVar1->workVariable = &var;
1419+ setVar1->args .push_back ({ Compiler::StaticType::Unknown, &value1 });
1420+ list.addInstruction (setVar1);
1421+
1422+ // Inner if statement begin
1423+ auto innerIf = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginIf, nullptr , false );
1424+ list.addInstruction (innerIf);
1425+
1426+ auto setVar = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, nullptr , false );
1427+ LLVMConstantRegister value (Compiler::StaticType::Number, 5 );
1428+ setVar->workVariable = &var;
1429+ setVar->args .push_back ({ Compiler::StaticType::Unknown, &value });
1430+ list.addInstruction (setVar);
1431+
1432+ // Inner if statement else branch begin
1433+ auto innerElse = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::BeginElse, nullptr , false );
1434+ list.addInstruction (innerElse);
1435+
1436+ // Variable write inside inner if statement else branch
1437+ auto setVar2 = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::WriteVariable, nullptr , false );
1438+ LLVMConstantRegister value2 (Compiler::StaticType::Number, 5 );
1439+ setVar2->workVariable = &var;
1440+ setVar2->args .push_back ({ Compiler::StaticType::Unknown, &value2 });
1441+ list.addInstruction (setVar2);
1442+
1443+ // Inner if statement end
1444+ auto innerEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndIf, nullptr , false );
1445+ list.addInstruction (innerEnd);
1446+
1447+ // Outer loop end
1448+ auto outerEnd = std::make_shared<LLVMInstruction>(LLVMInstruction::Type::EndLoop, nullptr , false );
1449+ list.addInstruction (outerEnd);
1450+
1451+ // Returns number type because the type always changes to number
1452+ ASSERT_EQ (analyzer.variableTypeAfterBranch (&varPtr, outerLoop.get (), Compiler::StaticType::Number), Compiler::StaticType::Number);
1453+ }
1454+
13111455TEST (LLVMTypeAnalyzer_VariableTypeAfterBranch, MultipleNestedLoopsWithTypeChange)
13121456{
13131457 LLVMTypeAnalyzer analyzer;
0 commit comments