From fb5ef7b426b5eaf15d71fbaee162c6d75df387ac Mon Sep 17 00:00:00 2001 From: Ahmad Rezaii Date: Thu, 23 Jan 2025 15:22:22 -0700 Subject: [PATCH 1/5] add dyno tests for if branches with integral types Signed-off-by: Ahmad Rezaii --- frontend/test/resolution/testIf.cpp | 324 +++++++++++++++++++++++++++- 1 file changed, 323 insertions(+), 1 deletion(-) diff --git a/frontend/test/resolution/testIf.cpp b/frontend/test/resolution/testIf.cpp index f875f159e79a..16902f008205 100644 --- a/frontend/test/resolution/testIf.cpp +++ b/frontend/test/resolution/testIf.cpp @@ -404,6 +404,328 @@ static void testIfVarBorrow() { assert(obj->basicClassType()->name() == "C"); } +// tests for return types of conditional expressions + +// need param and non-param variants +static std::string buildControlFlowProgram(std::string controlFlow, std::string boolVal, std::string typeVal1, std::string typeVal2) { + std::string program = ""; + program += "proc f(arg: bool, type t, type tt) {\n // Inserted control flow\n"; + program += controlFlow; + program += "\n // End inserted control flow\n }"; + program += "\nvar x = f("; + program += boolVal; + program += ", "; + program += typeVal1; + program += ", "; + program += typeVal2; + program += ");"; + return program; +} + +static void testControlFlow(std::string controlFlow, std::string boolVal, std::string typeVal1, std::string typeVal2, const chpl::types::PrimitiveType* expectedType) { + auto context = buildStdContext(); + ErrorGuard guard(context); + auto program = buildControlFlowProgram(controlFlow, boolVal, typeVal1, typeVal2); + std::cout << "--- test program ---" << std::endl; + std::cout << program.c_str() << std::endl; + + auto returnType = resolveTypeOfXInit(context, program, true); + assert(returnType.type()); + returnType.type()->dump(); + assert(returnType.type() == expectedType); +} + +static void testIfExpressionIntegralTypes() { + auto context = buildStdContext(); + ErrorGuard guard(context); + std::string controlFlowParam = " if arg then return 0:t; else return 0:tt;"; + std::string controlFlowNoParam = " var zero:uint;\n if arg then return zero:t; else return zero:tt;"; + // use only ints. 8, 16, 32, 64 bit. use each size with every other size. + //validated against the chart + testControlFlow(controlFlowParam, "true", "int(8)", "int(8)", IntType::get(context, 8)); + testControlFlow(controlFlowParam, "true", "int(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "int(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int(16)", "int(8)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "int(16)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "int(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int(32)", "int(8)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(32)", "int(16)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(32)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "int(8)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "int(16)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "int(32)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "int", IntType::get(context, 64)); + + // do the false versions of the above + testControlFlow(controlFlowParam, "false", "int(8)", "int(8)", IntType::get(context, 8)); + testControlFlow(controlFlowParam, "false", "int(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "int(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int(16)", "int(8)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "int(16)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "int(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int(32)", "int(8)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(32)", "int(16)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(32)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "int(8)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "int(16)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "int(32)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "int", IntType::get(context, 64)); + + // do the uint versions of all the above, true and false versions + testControlFlow(controlFlowParam, "true", "uint(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowParam, "true", "uint(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "uint(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint(16)", "uint(8)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "uint(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "uint(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint(32)", "uint(8)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(32)", "uint(16)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "uint(8)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "uint(16)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "uint(32)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "uint", UintType::get(context, 64)); + // false versions of the above uint calls + testControlFlow(controlFlowParam, "false", "uint(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowParam, "false", "uint(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "uint(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint(16)", "uint(8)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "uint(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "uint(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint(32)", "uint(8)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(32)", "uint(16)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "uint(8)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "uint(16)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "uint(32)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "uint", UintType::get(context, 64)); + + // tests where the first type is int and the second is uint, do all sizes of ints and uints + testControlFlow(controlFlowParam, "true", "int(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowParam, "true", "int(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "int(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int(16)", "uint(8)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "int(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "int(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int(32)", "uint(8)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(32)", "uint(16)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "int(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "uint(8)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "uint(16)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "uint(32)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "int", "uint", UintType::get(context, 64)); + // reverse the order of the types so that the first type is uint and the second is int + testControlFlow(controlFlowParam, "true", "uint(8)", "int(8)", UintType::get(context, 8)); + testControlFlow(controlFlowParam, "true", "uint(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "uint(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint(16)", "int(8)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "uint(16)", "int(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "true", "uint(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint(32)", "int(8)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(32)", "int(16)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(32)", "int(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "true", "uint(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "int(8)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "int(16)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "int(32)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "true", "uint", "int", UintType::get(context, 64)); + + // do the false versions of the above + testControlFlow(controlFlowParam, "false", "int(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowParam, "false", "int(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "int(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int(16)", "uint(8)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "int(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "int(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int(32)", "uint(8)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(32)", "uint(16)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "int(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "uint(8)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "uint(16)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "uint(32)", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "int", "uint", UintType::get(context, 64)); + // reverse the order of the types so that the first type is uint and the second is int + testControlFlow(controlFlowParam, "false", "uint(8)", "int(8)", UintType::get(context, 8)); + testControlFlow(controlFlowParam, "false", "uint(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "uint(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint(16)", "int(8)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "uint(16)", "int(16)", UintType::get(context, 16)); + testControlFlow(controlFlowParam, "false", "uint(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint(32)", "int(8)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(32)", "int(16)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(32)", "int(32)", UintType::get(context, 32)); + testControlFlow(controlFlowParam, "false", "uint(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "int(8)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "int(16)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "int(32)", UintType::get(context, 64)); + testControlFlow(controlFlowParam, "false", "uint", "int", UintType::get(context, 64)); + + // test with no params + // use only ints. 8, 16, 32, 64 bit. use each size with every other size. + testControlFlow(controlFlowNoParam, "true", "int(8)", "int(8)", IntType::get(context, 8)); + testControlFlow(controlFlowNoParam, "true", "int(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "int(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "int(8)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "int(8)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "int(16)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "int(8)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "int(16)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "int(32)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "int", IntType::get(context, 64)); + + // do the false versions of the above + testControlFlow(controlFlowNoParam, "false", "int(8)", "int(8)", IntType::get(context, 8)); + testControlFlow(controlFlowNoParam, "false", "int(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "int(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "int(8)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "int(8)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "int(16)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "int(8)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "int(16)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "int(32)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "int", IntType::get(context, 64)); + + // do the uint versions of all the above, true and false versions + testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint(8)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint(8)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint(16)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "uint(8)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "uint(16)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "uint(32)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "uint", UintType::get(context, 64)); + // false versions of the above uint calls + testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint(8)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint(8)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint(16)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "uint(8)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "uint(16)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "uint(32)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "uint", UintType::get(context, 64)); + + // tests where the first type is int and the second is uint, do all sizes of ints and uints + testControlFlow(controlFlowNoParam, "true", "int(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowNoParam, "true", "int(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "int(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "uint(8)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "uint(8)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "uint(16)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "int(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "uint(8)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "uint(16)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "uint(32)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "int", "uint", UintType::get(context, 64)); + // reverse the order of the types so that the first type is uint and the second is int + testControlFlow(controlFlowNoParam, "true", "uint(8)", "int(8)", UintType::get(context, 8)); + testControlFlow(controlFlowNoParam, "true", "uint(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "uint(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "int(8)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "int(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "int(8)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "int(16)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "int(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "true", "uint(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "int(8)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "int(16)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "int(32)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "true", "uint", "int", UintType::get(context, 64)); + + // do the false versions of the above + testControlFlow(controlFlowNoParam, "false", "int(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(controlFlowNoParam, "false", "int(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "int(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(8)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "uint(8)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(16)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "uint(8)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "uint(16)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "int(32)", "uint", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "uint(8)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "uint(16)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "uint(32)", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "int", "uint", UintType::get(context, 64)); + // reverse the order of the types so that the first type is uint and the second is int + testControlFlow(controlFlowNoParam, "false", "uint(8)", "int(8)", UintType::get(context, 8)); + testControlFlow(controlFlowNoParam, "false", "uint(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "uint(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(8)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "int(8)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "int(16)", UintType::get(context, 16)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(16)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "int(8)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "int(16)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "int(32)", UintType::get(context, 32)); + testControlFlow(controlFlowNoParam, "false", "uint(32)", "int", IntType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "int(8)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "int(16)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "int(32)", UintType::get(context, 64)); + testControlFlow(controlFlowNoParam, "false", "uint", "int", UintType::get(context, 64)); +} + + int main() { test1(); test2(); @@ -418,6 +740,6 @@ int main() { testIfVarErrorUseInElseBranch4(); testIfVarErrorNonClassType(); testIfVarNonNilInThen(); - + testIfExpressionIntegralTypes(); return 0; } From b1fd557efc5c530d048874cf467ca9cded9800a4 Mon Sep 17 00:00:00 2001 From: Ahmad Rezaii Date: Thu, 23 Jan 2025 15:43:51 -0700 Subject: [PATCH 2/5] refactor to reduce test size Signed-off-by: Ahmad Rezaii --- frontend/test/resolution/testIf.cpp | 353 ++++++---------------------- 1 file changed, 73 insertions(+), 280 deletions(-) diff --git a/frontend/test/resolution/testIf.cpp b/frontend/test/resolution/testIf.cpp index 16902f008205..ee24ce17157a 100644 --- a/frontend/test/resolution/testIf.cpp +++ b/frontend/test/resolution/testIf.cpp @@ -435,294 +435,87 @@ static void testControlFlow(std::string controlFlow, std::string boolVal, std::s assert(returnType.type() == expectedType); } -static void testIfExpressionIntegralTypes() { +static void testIfExpressionIntegralTypesHelper(std::string program, std::string boolCondition) { auto context = buildStdContext(); ErrorGuard guard(context); - std::string controlFlowParam = " if arg then return 0:t; else return 0:tt;"; - std::string controlFlowNoParam = " var zero:uint;\n if arg then return zero:t; else return zero:tt;"; // use only ints. 8, 16, 32, 64 bit. use each size with every other size. //validated against the chart - testControlFlow(controlFlowParam, "true", "int(8)", "int(8)", IntType::get(context, 8)); - testControlFlow(controlFlowParam, "true", "int(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "int(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int(16)", "int(8)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "int(16)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "int(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int(32)", "int(8)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(32)", "int(16)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(32)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "int(8)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "int(16)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "int(32)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "int", IntType::get(context, 64)); - - // do the false versions of the above - testControlFlow(controlFlowParam, "false", "int(8)", "int(8)", IntType::get(context, 8)); - testControlFlow(controlFlowParam, "false", "int(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "int(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int(16)", "int(8)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "int(16)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "int(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int(32)", "int(8)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(32)", "int(16)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(32)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "int(8)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "int(16)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "int(32)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "int", IntType::get(context, 64)); - + testControlFlow(program, boolCondition, "int(8)", "int(8)", IntType::get(context, 8)); + testControlFlow(program, boolCondition, "int(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(program, boolCondition, "int(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "int(8)", "int", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int(16)", "int(8)", IntType::get(context, 16)); + testControlFlow(program, boolCondition, "int(16)", "int(16)", IntType::get(context, 16)); + testControlFlow(program, boolCondition, "int(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "int(16)", "int", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int(32)", "int(8)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "int(32)", "int(16)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "int(32)", "int(32)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "int(32)", "int", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "int(8)", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "int(16)", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "int(32)", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "int", IntType::get(context, 64)); // do the uint versions of all the above, true and false versions - testControlFlow(controlFlowParam, "true", "uint(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowParam, "true", "uint(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "uint(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint(16)", "uint(8)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "uint(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "uint(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint(32)", "uint(8)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(32)", "uint(16)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "uint(8)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "uint(16)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "uint(32)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "uint", UintType::get(context, 64)); - // false versions of the above uint calls - testControlFlow(controlFlowParam, "false", "uint(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowParam, "false", "uint(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "uint(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint(16)", "uint(8)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "uint(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "uint(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint(32)", "uint(8)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(32)", "uint(16)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "uint(8)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "uint(16)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "uint(32)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "uint", UintType::get(context, 64)); - + testControlFlow(program, boolCondition, "uint(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(program, boolCondition, "uint(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(program, boolCondition, "uint(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(8)", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint(16)", "uint(8)", UintType::get(context, 16)); + testControlFlow(program, boolCondition, "uint(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(program, boolCondition, "uint(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(16)", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint(32)", "uint(8)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(32)", "uint(16)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(32)", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "uint(8)", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "uint(16)", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "uint(32)", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "uint", UintType::get(context, 64)); // tests where the first type is int and the second is uint, do all sizes of ints and uints - testControlFlow(controlFlowParam, "true", "int(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowParam, "true", "int(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "int(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int(16)", "uint(8)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "int(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "int(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int(32)", "uint(8)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(32)", "uint(16)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "int(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "uint(8)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "uint(16)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "uint(32)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "int", "uint", UintType::get(context, 64)); - // reverse the order of the types so that the first type is uint and the second is int - testControlFlow(controlFlowParam, "true", "uint(8)", "int(8)", UintType::get(context, 8)); - testControlFlow(controlFlowParam, "true", "uint(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "uint(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint(16)", "int(8)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "uint(16)", "int(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "true", "uint(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint(32)", "int(8)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(32)", "int(16)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(32)", "int(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "true", "uint(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "int(8)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "int(16)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "int(32)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "true", "uint", "int", UintType::get(context, 64)); - - // do the false versions of the above - testControlFlow(controlFlowParam, "false", "int(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowParam, "false", "int(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "int(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int(16)", "uint(8)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "int(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "int(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int(32)", "uint(8)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(32)", "uint(16)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "int(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "uint(8)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "uint(16)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "uint(32)", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "int", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "int(8)", "uint(8)", UintType::get(context, 8)); + testControlFlow(program, boolCondition, "int(8)", "uint(16)", UintType::get(context, 16)); + testControlFlow(program, boolCondition, "int(8)", "uint(32)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "int(8)", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "int(16)", "uint(8)", IntType::get(context, 16)); + testControlFlow(program, boolCondition, "int(16)", "uint(16)", UintType::get(context, 16)); + testControlFlow(program, boolCondition, "int(16)", "uint(32)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "int(16)", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "int(32)", "uint(8)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "int(32)", "uint(16)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "int(32)", "uint(32)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "int(32)", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "uint(8)", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "uint(16)", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "uint(32)", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "int", "uint", UintType::get(context, 64)); // reverse the order of the types so that the first type is uint and the second is int - testControlFlow(controlFlowParam, "false", "uint(8)", "int(8)", UintType::get(context, 8)); - testControlFlow(controlFlowParam, "false", "uint(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "uint(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint(16)", "int(8)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "uint(16)", "int(16)", UintType::get(context, 16)); - testControlFlow(controlFlowParam, "false", "uint(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint(32)", "int(8)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(32)", "int(16)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(32)", "int(32)", UintType::get(context, 32)); - testControlFlow(controlFlowParam, "false", "uint(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "int(8)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "int(16)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "int(32)", UintType::get(context, 64)); - testControlFlow(controlFlowParam, "false", "uint", "int", UintType::get(context, 64)); - - // test with no params - // use only ints. 8, 16, 32, 64 bit. use each size with every other size. - testControlFlow(controlFlowNoParam, "true", "int(8)", "int(8)", IntType::get(context, 8)); - testControlFlow(controlFlowNoParam, "true", "int(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "int(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "int(8)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "int(8)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "int(16)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "int(8)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "int(16)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "int(32)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "int", IntType::get(context, 64)); - - // do the false versions of the above - testControlFlow(controlFlowNoParam, "false", "int(8)", "int(8)", IntType::get(context, 8)); - testControlFlow(controlFlowNoParam, "false", "int(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "int(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "int(8)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "int(8)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "int(16)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "int(8)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "int(16)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "int(32)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "int", IntType::get(context, 64)); - - // do the uint versions of all the above, true and false versions - testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint(8)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint(8)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint(16)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "uint(8)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "uint(16)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "uint(32)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "uint", UintType::get(context, 64)); - // false versions of the above uint calls - testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint(8)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint(8)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint(16)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "uint(8)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "uint(16)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "uint(32)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "uint", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint(8)", "int(8)", UintType::get(context, 8)); + testControlFlow(program, boolCondition, "uint(8)", "int(16)", IntType::get(context, 16)); + testControlFlow(program, boolCondition, "uint(8)", "int(32)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(8)", "int", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "uint(16)", "int(8)", UintType::get(context, 16)); + testControlFlow(program, boolCondition, "uint(16)", "int(16)", UintType::get(context, 16)); + testControlFlow(program, boolCondition, "uint(16)", "int(32)", IntType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(16)", "int", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "uint(32)", "int(8)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(32)", "int(16)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(32)", "int(32)", UintType::get(context, 32)); + testControlFlow(program, boolCondition, "uint(32)", "int", IntType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "int(8)", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "int(16)", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "int(32)", UintType::get(context, 64)); + testControlFlow(program, boolCondition, "uint", "int", UintType::get(context, 64)); +} - // tests where the first type is int and the second is uint, do all sizes of ints and uints - testControlFlow(controlFlowNoParam, "true", "int(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowNoParam, "true", "int(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "int(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "uint(8)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "uint(8)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "uint(16)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "int(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "uint(8)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "uint(16)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "uint(32)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "int", "uint", UintType::get(context, 64)); - // reverse the order of the types so that the first type is uint and the second is int - testControlFlow(controlFlowNoParam, "true", "uint(8)", "int(8)", UintType::get(context, 8)); - testControlFlow(controlFlowNoParam, "true", "uint(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "uint(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "int(8)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "int(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "int(8)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "int(16)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "int(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "true", "uint(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "int(8)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "int(16)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "int(32)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "true", "uint", "int", UintType::get(context, 64)); - - // do the false versions of the above - testControlFlow(controlFlowNoParam, "false", "int(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(controlFlowNoParam, "false", "int(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "int(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(8)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "uint(8)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(16)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "uint(8)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "uint(16)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "int(32)", "uint", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "uint(8)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "uint(16)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "uint(32)", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "int", "uint", UintType::get(context, 64)); - // reverse the order of the types so that the first type is uint and the second is int - testControlFlow(controlFlowNoParam, "false", "uint(8)", "int(8)", UintType::get(context, 8)); - testControlFlow(controlFlowNoParam, "false", "uint(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "uint(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(8)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "int(8)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "int(16)", UintType::get(context, 16)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(16)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "int(8)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "int(16)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "int(32)", UintType::get(context, 32)); - testControlFlow(controlFlowNoParam, "false", "uint(32)", "int", IntType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "int(8)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "int(16)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "int(32)", UintType::get(context, 64)); - testControlFlow(controlFlowNoParam, "false", "uint", "int", UintType::get(context, 64)); +static void testIfExpressionIntegralTypes() { + std::string controlFlowParam = " if arg then return 0:t; else return 0:tt;"; + std::string controlFlowNoParam = " var zero:uint;\n if arg then return zero:t; else return zero:tt;"; + testIfExpressionIntegralTypesHelper(controlFlowParam, "true"); + testIfExpressionIntegralTypesHelper(controlFlowParam, "false"); + testIfExpressionIntegralTypesHelper(controlFlowNoParam, "true"); + testIfExpressionIntegralTypesHelper(controlFlowNoParam, "false"); } From 90afcc59c236a5c0450ee8191462641a106ac13d Mon Sep 17 00:00:00 2001 From: Ahmad Rezaii Date: Fri, 24 Jan 2025 16:36:48 -0700 Subject: [PATCH 3/5] add integral return type tests for dyno and prod Signed-off-by: Ahmad Rezaii --- frontend/test/resolution/CMakeLists.txt | 1 + frontend/test/resolution/testIf.cpp | 116 ---- .../resolution/testIntegralReturnType.cpp | 231 +++++++ .../integralReturnTypesInConditional.chpl | 94 +++ .../integralReturnTypesInConditional.good | 640 ++++++++++++++++++ 5 files changed, 966 insertions(+), 116 deletions(-) create mode 100644 frontend/test/resolution/testIntegralReturnType.cpp create mode 100644 test/statements/conditionals/integralReturnTypesInConditional.chpl create mode 100644 test/statements/conditionals/integralReturnTypesInConditional.good diff --git a/frontend/test/resolution/CMakeLists.txt b/frontend/test/resolution/CMakeLists.txt index 57a14f89fe54..1603b368cba8 100644 --- a/frontend/test/resolution/CMakeLists.txt +++ b/frontend/test/resolution/CMakeLists.txt @@ -48,6 +48,7 @@ comp_unit_test(testGetSymbolsAvailableInScope) comp_unit_test(testHeapBuffer) comp_unit_test(testIf) comp_unit_test(testInitSemantics) +comp_unit_test(testIntegralReturnType) comp_unit_test(testInteractive) comp_unit_test(testInterfaces) comp_unit_test(testIterators) diff --git a/frontend/test/resolution/testIf.cpp b/frontend/test/resolution/testIf.cpp index ee24ce17157a..b417e42c1ef6 100644 --- a/frontend/test/resolution/testIf.cpp +++ b/frontend/test/resolution/testIf.cpp @@ -404,121 +404,6 @@ static void testIfVarBorrow() { assert(obj->basicClassType()->name() == "C"); } -// tests for return types of conditional expressions - -// need param and non-param variants -static std::string buildControlFlowProgram(std::string controlFlow, std::string boolVal, std::string typeVal1, std::string typeVal2) { - std::string program = ""; - program += "proc f(arg: bool, type t, type tt) {\n // Inserted control flow\n"; - program += controlFlow; - program += "\n // End inserted control flow\n }"; - program += "\nvar x = f("; - program += boolVal; - program += ", "; - program += typeVal1; - program += ", "; - program += typeVal2; - program += ");"; - return program; -} - -static void testControlFlow(std::string controlFlow, std::string boolVal, std::string typeVal1, std::string typeVal2, const chpl::types::PrimitiveType* expectedType) { - auto context = buildStdContext(); - ErrorGuard guard(context); - auto program = buildControlFlowProgram(controlFlow, boolVal, typeVal1, typeVal2); - std::cout << "--- test program ---" << std::endl; - std::cout << program.c_str() << std::endl; - - auto returnType = resolveTypeOfXInit(context, program, true); - assert(returnType.type()); - returnType.type()->dump(); - assert(returnType.type() == expectedType); -} - -static void testIfExpressionIntegralTypesHelper(std::string program, std::string boolCondition) { - auto context = buildStdContext(); - ErrorGuard guard(context); - // use only ints. 8, 16, 32, 64 bit. use each size with every other size. - //validated against the chart - testControlFlow(program, boolCondition, "int(8)", "int(8)", IntType::get(context, 8)); - testControlFlow(program, boolCondition, "int(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(program, boolCondition, "int(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "int(8)", "int", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int(16)", "int(8)", IntType::get(context, 16)); - testControlFlow(program, boolCondition, "int(16)", "int(16)", IntType::get(context, 16)); - testControlFlow(program, boolCondition, "int(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "int(16)", "int", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int(32)", "int(8)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "int(32)", "int(16)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "int(32)", "int(32)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "int(32)", "int", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "int(8)", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "int(16)", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "int(32)", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "int", IntType::get(context, 64)); - // do the uint versions of all the above, true and false versions - testControlFlow(program, boolCondition, "uint(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(program, boolCondition, "uint(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(program, boolCondition, "uint(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(8)", "uint", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint(16)", "uint(8)", UintType::get(context, 16)); - testControlFlow(program, boolCondition, "uint(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(program, boolCondition, "uint(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(16)", "uint", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint(32)", "uint(8)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(32)", "uint(16)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(32)", "uint", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "uint(8)", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "uint(16)", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "uint(32)", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "uint", UintType::get(context, 64)); - // tests where the first type is int and the second is uint, do all sizes of ints and uints - testControlFlow(program, boolCondition, "int(8)", "uint(8)", UintType::get(context, 8)); - testControlFlow(program, boolCondition, "int(8)", "uint(16)", UintType::get(context, 16)); - testControlFlow(program, boolCondition, "int(8)", "uint(32)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "int(8)", "uint", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "int(16)", "uint(8)", IntType::get(context, 16)); - testControlFlow(program, boolCondition, "int(16)", "uint(16)", UintType::get(context, 16)); - testControlFlow(program, boolCondition, "int(16)", "uint(32)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "int(16)", "uint", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "int(32)", "uint(8)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "int(32)", "uint(16)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "int(32)", "uint(32)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "int(32)", "uint", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "uint(8)", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "uint(16)", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "uint(32)", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "int", "uint", UintType::get(context, 64)); - // reverse the order of the types so that the first type is uint and the second is int - testControlFlow(program, boolCondition, "uint(8)", "int(8)", UintType::get(context, 8)); - testControlFlow(program, boolCondition, "uint(8)", "int(16)", IntType::get(context, 16)); - testControlFlow(program, boolCondition, "uint(8)", "int(32)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(8)", "int", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "uint(16)", "int(8)", UintType::get(context, 16)); - testControlFlow(program, boolCondition, "uint(16)", "int(16)", UintType::get(context, 16)); - testControlFlow(program, boolCondition, "uint(16)", "int(32)", IntType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(16)", "int", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "uint(32)", "int(8)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(32)", "int(16)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(32)", "int(32)", UintType::get(context, 32)); - testControlFlow(program, boolCondition, "uint(32)", "int", IntType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "int(8)", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "int(16)", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "int(32)", UintType::get(context, 64)); - testControlFlow(program, boolCondition, "uint", "int", UintType::get(context, 64)); -} - -static void testIfExpressionIntegralTypes() { - std::string controlFlowParam = " if arg then return 0:t; else return 0:tt;"; - std::string controlFlowNoParam = " var zero:uint;\n if arg then return zero:t; else return zero:tt;"; - testIfExpressionIntegralTypesHelper(controlFlowParam, "true"); - testIfExpressionIntegralTypesHelper(controlFlowParam, "false"); - testIfExpressionIntegralTypesHelper(controlFlowNoParam, "true"); - testIfExpressionIntegralTypesHelper(controlFlowNoParam, "false"); -} - - int main() { test1(); test2(); @@ -533,6 +418,5 @@ int main() { testIfVarErrorUseInElseBranch4(); testIfVarErrorNonClassType(); testIfVarNonNilInThen(); - testIfExpressionIntegralTypes(); return 0; } diff --git a/frontend/test/resolution/testIntegralReturnType.cpp b/frontend/test/resolution/testIntegralReturnType.cpp new file mode 100644 index 000000000000..44e4467edef4 --- /dev/null +++ b/frontend/test/resolution/testIntegralReturnType.cpp @@ -0,0 +1,231 @@ +/* + * Copyright 2021-2025 Hewlett Packard Enterprise Development LP + * Other additional copyright holders may be indicated within. + * + * The entirety of this work is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test-resolution.h" + +#include "chpl/parsing/parsing-queries.h" +#include "chpl/resolution/resolution-queries.h" +#include "chpl/resolution/scope-queries.h" +#include "chpl/types/all-types.h" +#include "chpl/uast/Identifier.h" +#include "chpl/uast/Module.h" +#include "chpl/uast/Record.h" +#include "chpl/uast/Variable.h" + +static std::string buildControlFlowProgram(std::string existingProgram, std::string boolVal, std::string typeVal1, std::string typeVal2) { + std::string program = existingProgram; + program += "\nvar x = f("; + program += boolVal; + program += ", "; + program += typeVal1; + program += ", "; + program += typeVal2; + program += ");\n"; + return program; +} + +// need param and non-param variants +static std::string buildIfExpressionParam(std::string boolVal, std::string typeVal1, std::string typeVal2) { + std::string program = ""; + program += "var x = if "; + program += boolVal; + program += " then 0:"; + program += typeVal1; + program += " else 0:"; + program += typeVal2; + program += ";\n"; + return program; +} + +static std::string buildIfExpressionNoParam(std::string boolVal, std::string typeVal1, std::string typeVal2) { + std::string program = ""; + program += "var zero:uint(8);\n"; + program += "var x = if "; + program += boolVal; + program += " then zero:"; + program += typeVal1; + program += " else zero:"; + program += typeVal2; + program += ";\n"; + return program; +} + +enum class ProgramTestType { + TestGeneric, + TestGenericCast, + TestParamGenericCast, + TestExpression, + TestParamExpression +}; + +static void testIntegralReturn(std::string baseProgram, std::string boolVal, + std::string typeVal1, std::string typeVal2, + const chpl::types::PrimitiveType* expectedType, + ProgramTestType testType) { + auto context = buildStdContext(); + ErrorGuard guard(context); + std::string program; + std::string lineOut = ""; + if (testType == ProgramTestType::TestGeneric) { + program = buildControlFlowProgram(baseProgram, boolVal, typeVal1, typeVal2); + lineOut += "testGeneric: when "; + } else if (testType == ProgramTestType::TestGenericCast) { + program = buildControlFlowProgram(baseProgram, boolVal, typeVal1, typeVal2); + lineOut += "testGenericCast: when "; + } else if (testType == ProgramTestType::TestParamGenericCast) { + program = buildControlFlowProgram(baseProgram, boolVal, typeVal1, typeVal2); + lineOut += "testParamGenericCast: when "; + } else if (testType == ProgramTestType::TestExpression) { + program = buildIfExpressionNoParam(boolVal, typeVal1, typeVal2); + lineOut += "testExpression: when "; + } else if (testType == ProgramTestType::TestParamExpression) { + program = buildIfExpressionParam(boolVal, typeVal1, typeVal2); + lineOut += "testParamExpression: when "; + } + lineOut += boolVal; + lineOut += " "; + lineOut += typeVal1; + lineOut += " "; + lineOut += typeVal2; + lineOut += " then "; + auto returnType = resolveTypeOfXInit(context, program, true); + assert(returnType.type()); + std::cout << lineOut; + returnType.type()->dump(); + // re-enable this when we have the correct types for each call + // assert(returnType.type() == expectedType); +} + +static void +testIfExpressionIntegralTypesHelper(std::string program, + std::string boolCondition, + ProgramTestType testType) { + auto context = buildStdContext(); + ErrorGuard guard(context); + // use only ints. 8, 16, 32, 64 bit. use each size with every other size. + //validated against the chart + testIntegralReturn(program, boolCondition, "int(8)", "int(8)", IntType::get(context, 8), testType); + testIntegralReturn(program, boolCondition, "int(8)", "int(16)", IntType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "int(8)", "int(32)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(8)", "int(64)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(16)", "int(8)", IntType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "int(16)", "int(16)", IntType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "int(16)", "int(32)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(16)", "int(64)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(32)", "int(8)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(32)", "int(16)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(32)", "int(32)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(32)", "int(64)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "int(8)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "int(16)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "int(32)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "int(64)", IntType::get(context, 64), testType); + // do the uint versions of all the above, true and false versions + testIntegralReturn(program, boolCondition, "uint(8)", "uint(8)", UintType::get(context, 8), testType); + testIntegralReturn(program, boolCondition, "uint(8)", "uint(16)", UintType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "uint(8)", "uint(32)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(8)", "uint(64)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "uint(8)", UintType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "uint(16)", UintType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "uint(32)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "uint(64)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(32)", "uint(8)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(32)", "uint(16)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(32)", "uint(32)", UintType::get(context, 32), testType);; + testIntegralReturn(program, boolCondition, "uint(32)", "uint(64)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(64)", "uint(8)", UintType::get(context, 64), testType);; + testIntegralReturn(program, boolCondition, "uint(64)", "uint(16)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(64)", "uint(32)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(64)", "uint(64)", UintType::get(context, 64), testType); + // tests where the first type is int and the second is uint, do all sizes of ints and uints + testIntegralReturn(program, boolCondition, "int(8)", "uint(8)", UintType::get(context, 8), testType); + testIntegralReturn(program, boolCondition, "int(8)", "uint(16)", UintType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "int(8)", "uint(32)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(8)", "uint(64)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(16)", "uint(8)", IntType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "int(16)", "uint(16)", UintType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "int(16)", "uint(32)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(16)", "uint(64)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(32)", "uint(8)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(32)", "uint(16)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(32)", "uint(32)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "int(32)", "uint(64)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "uint(8)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "uint(16)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "uint(32)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "int(64)", "uint(64)", UintType::get(context, 64), testType); + // reverse the order of the types so that the first type is uint and the second is int + testIntegralReturn(program, boolCondition, "uint(8)", "int(8)", UintType::get(context, 8), testType); + testIntegralReturn(program, boolCondition, "uint(8)", "int(16)", IntType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "uint(8)", "int(32)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(8)", "int(64)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "int(8)", UintType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "int(16)", UintType::get(context, 16), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "int(32)", IntType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(16)", "int(64)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(32)", "int(8)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(32)", "int(16)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(32)", "int(32)", UintType::get(context, 32), testType); + testIntegralReturn(program, boolCondition, "uint(32)", "int(64)", IntType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(64)", "int(8)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(64)", "int(16)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(64)", "int(32)", UintType::get(context, 64), testType); + testIntegralReturn(program, boolCondition, "uint(64)", "int(64)", UintType::get(context, 64), testType); +} + +static void testConditionalIntegralTypes() { + std::string testGeneric = + R"""( + proc f(arg: bool, type t, type tt) { + var i: t = 0; + var u: tt = 0; + if arg then return i; else return u; + } + )"""; + std::string testGenericCast = + R"""( + proc f(arg: bool, type t, type tt) { + var zero: uint(8); + if arg then return zero:t; else return zero:tt; + } + )"""; + std::string testParamGenericCast = + R"""( + proc f(arg: bool, type t, type tt) { + if arg then return 0:t; else return 0:tt; + } + )"""; + + testIfExpressionIntegralTypesHelper(testGeneric, "true", ProgramTestType::TestGeneric); + testIfExpressionIntegralTypesHelper(testGeneric, "false", ProgramTestType::TestGeneric); + testIfExpressionIntegralTypesHelper(testParamGenericCast, "true", ProgramTestType::TestParamGenericCast); + testIfExpressionIntegralTypesHelper(testParamGenericCast, "false", ProgramTestType::TestParamGenericCast); + testIfExpressionIntegralTypesHelper(testGenericCast, "true", ProgramTestType::TestGenericCast); + testIfExpressionIntegralTypesHelper(testGenericCast, "false", ProgramTestType::TestGenericCast); + testIfExpressionIntegralTypesHelper("", "true", ProgramTestType::TestExpression); + testIfExpressionIntegralTypesHelper("", "false", ProgramTestType::TestExpression); + testIfExpressionIntegralTypesHelper("", "true", ProgramTestType::TestParamExpression); + testIfExpressionIntegralTypesHelper("", "false", ProgramTestType::TestParamExpression); +} + +int main() { + testConditionalIntegralTypes(); + return 0; +} + diff --git a/test/statements/conditionals/integralReturnTypesInConditional.chpl b/test/statements/conditionals/integralReturnTypesInConditional.chpl new file mode 100644 index 000000000000..2b1bd461392b --- /dev/null +++ b/test/statements/conditionals/integralReturnTypesInConditional.chpl @@ -0,0 +1,94 @@ +proc testGeneric(arg: bool, type t, type tt) { + var i: t = 0; + var u: tt = 0; + if arg then return i; + else return u; +} + +proc testGenericCast(arg: bool, type t, type tt) { + var zero: uint(8); + if arg then return zero:t; + else return zero:tt; +} + +proc testParamGenericCast(arg: bool, type t, type tt) { + if arg then return 0:t; + else return 0:tt; +} + +proc testExpression(arg: bool, type t, type tt) { + var zero: uint(8); + var x = if arg then zero:t else zero:tt; + writeln("testExpression: when ", arg:string, " ", t:string, " ", + tt:string, " then ", x.type:string); +} + +proc testParamExpression(arg: bool, type t, type tt) { + var x = if arg then 0:t else 0:tt; + writeln("testParamExpression: when ", arg:string, " ", t:string, " ", + tt:string, " then ", x.type:string); +} + +const A = [true, false]; + +const Ti = (0:int(8), 0:int(16), 0:int(32), 0:int(64)); +const Tu = (0:uint(8), 0:uint(16), 0:uint(32), 0:uint(64)); + +for a in A { + for ti in Ti { + for tti in Ti { + var xxx = testGeneric(a, ti.type, tti.type); + writeln("testGeneric: when ", a:string, " ", ti.type:string, " ", + tti.type:string, " then ", xxx.type:string); + var yyy = testGenericCast(a, ti.type, tti.type); + writeln("testGenericCast: when ", a:string, " ", ti.type:string, " ", + tti.type:string, " then ", yyy.type:string); + testExpression(a, ti.type, tti.type); + testParamExpression(a, ti.type, tti.type); + var zzz = testParamGenericCast(a, ti.type, tti.type); + writeln("testParamGenericCast: when ", a:string, " ", ti.type:string, " ", + tti.type:string, " then ", zzz.type:string); + } + for tu in Tu { + testExpression(a, ti.type, tu.type); + testExpression(a, tu.type, ti.type); + testParamExpression(a, ti.type, tu.type); + testParamExpression(a, tu.type, ti.type); + var x = testGeneric(a, ti.type, tu.type); + writeln("testGeneric: when ", a:string, " ", ti.type:string, " ", + tu.type:string, " then ", x.type:string); + var xx = testGeneric(a, tu.type, ti.type); + writeln("testGeneric: when ", a:string, " ", tu.type:string, " ", + ti.type:string, " then " , xx.type:string); + + var y = testGenericCast(a, ti.type, tu.type); + writeln("testGenericCast: when ", a:string, " ", ti.type:string, " ", + tu.type:string, " then " , y.type:string); + var yy = testGenericCast(a, tu.type, ti.type); + writeln("testGenericCast: when ", a:string, " ", tu.type:string, " ", + ti.type:string, " then " , yy.type:string); + + var z = testParamGenericCast(a, ti.type, tu.type); + writeln("testParamGenericCast: when ", a:string, " ", ti.type:string, " ", + tu.type:string, " then ", z.type:string); + var zz = testParamGenericCast(a, tu.type, ti.type); + writeln("testParamGenericCast: when ", a:string, " ", tu.type:string, " ", + ti.type:string, " then ", zz.type:string); + } + } + for tz in Tu { + for tzz in Tu { + var xxx = testGeneric(a, tz.type, tzz.type); + writeln("testGeneric: when ", a:string, " ", tz.type:string, " ", + tzz.type:string, " then " , xxx.type:string); + var yyy = testGenericCast(a, tz.type, tzz.type); + writeln("testGenericCast: when ", a:string, " ", tz.type:string, " ", + tzz.type:string, " then " , yyy.type:string); + testExpression(a, tz.type, tzz.type); + testParamExpression(a, tz.type, tzz.type); + var zzz = testParamGenericCast(a, tz.type, tzz.type); + writeln("testParamGenericCast: when ", a:string, " ", tz.type:string, " ", + tzz.type:string, " then ", zzz.type:string); + } + } +} diff --git a/test/statements/conditionals/integralReturnTypesInConditional.good b/test/statements/conditionals/integralReturnTypesInConditional.good new file mode 100644 index 000000000000..b0a5af205226 --- /dev/null +++ b/test/statements/conditionals/integralReturnTypesInConditional.good @@ -0,0 +1,640 @@ +testGeneric: when true int(8) int(8) then int(8) +testGenericCast: when true int(8) int(8) then int(8) +testExpression: when true int(8) int(8) then int(8) +testParamExpression: when true int(8) int(8) then int(8) +testParamGenericCast: when true int(8) int(8) then int(8) +testGeneric: when true int(8) int(16) then int(16) +testGenericCast: when true int(8) int(16) then int(16) +testExpression: when true int(8) int(16) then int(16) +testParamExpression: when true int(8) int(16) then int(8) +testParamGenericCast: when true int(8) int(16) then int(8) +testGeneric: when true int(8) int(32) then int(32) +testGenericCast: when true int(8) int(32) then int(32) +testExpression: when true int(8) int(32) then int(32) +testParamExpression: when true int(8) int(32) then int(8) +testParamGenericCast: when true int(8) int(32) then int(8) +testGeneric: when true int(8) int(64) then int(64) +testGenericCast: when true int(8) int(64) then int(64) +testExpression: when true int(8) int(64) then int(64) +testParamExpression: when true int(8) int(64) then int(8) +testParamGenericCast: when true int(8) int(64) then int(8) +testExpression: when true int(8) uint(8) then uint(8) +testExpression: when true uint(8) int(8) then uint(8) +testParamExpression: when true int(8) uint(8) then int(8) +testParamExpression: when true uint(8) int(8) then uint(8) +testGeneric: when true int(8) uint(8) then uint(8) +testGeneric: when true uint(8) int(8) then uint(8) +testGenericCast: when true int(8) uint(8) then uint(8) +testGenericCast: when true uint(8) int(8) then uint(8) +testParamGenericCast: when true int(8) uint(8) then int(8) +testParamGenericCast: when true uint(8) int(8) then uint(8) +testExpression: when true int(8) uint(16) then uint(16) +testExpression: when true uint(16) int(8) then uint(16) +testParamExpression: when true int(8) uint(16) then int(8) +testParamExpression: when true uint(16) int(8) then uint(16) +testGeneric: when true int(8) uint(16) then uint(16) +testGeneric: when true uint(16) int(8) then uint(16) +testGenericCast: when true int(8) uint(16) then uint(16) +testGenericCast: when true uint(16) int(8) then uint(16) +testParamGenericCast: when true int(8) uint(16) then int(8) +testParamGenericCast: when true uint(16) int(8) then uint(16) +testExpression: when true int(8) uint(32) then uint(32) +testExpression: when true uint(32) int(8) then uint(32) +testParamExpression: when true int(8) uint(32) then int(8) +testParamExpression: when true uint(32) int(8) then uint(32) +testGeneric: when true int(8) uint(32) then uint(32) +testGeneric: when true uint(32) int(8) then uint(32) +testGenericCast: when true int(8) uint(32) then uint(32) +testGenericCast: when true uint(32) int(8) then uint(32) +testParamGenericCast: when true int(8) uint(32) then int(8) +testParamGenericCast: when true uint(32) int(8) then uint(32) +testExpression: when true int(8) uint(64) then uint(64) +testExpression: when true uint(64) int(8) then uint(64) +testParamExpression: when true int(8) uint(64) then int(8) +testParamExpression: when true uint(64) int(8) then uint(64) +testGeneric: when true int(8) uint(64) then uint(64) +testGeneric: when true uint(64) int(8) then uint(64) +testGenericCast: when true int(8) uint(64) then uint(64) +testGenericCast: when true uint(64) int(8) then uint(64) +testParamGenericCast: when true int(8) uint(64) then int(8) +testParamGenericCast: when true uint(64) int(8) then uint(64) +testGeneric: when true int(16) int(8) then int(16) +testGenericCast: when true int(16) int(8) then int(16) +testExpression: when true int(16) int(8) then int(16) +testParamExpression: when true int(16) int(8) then int(16) +testParamGenericCast: when true int(16) int(8) then int(16) +testGeneric: when true int(16) int(16) then int(16) +testGenericCast: when true int(16) int(16) then int(16) +testExpression: when true int(16) int(16) then int(16) +testParamExpression: when true int(16) int(16) then int(16) +testParamGenericCast: when true int(16) int(16) then int(16) +testGeneric: when true int(16) int(32) then int(32) +testGenericCast: when true int(16) int(32) then int(32) +testExpression: when true int(16) int(32) then int(32) +testParamExpression: when true int(16) int(32) then int(16) +testParamGenericCast: when true int(16) int(32) then int(16) +testGeneric: when true int(16) int(64) then int(64) +testGenericCast: when true int(16) int(64) then int(64) +testExpression: when true int(16) int(64) then int(64) +testParamExpression: when true int(16) int(64) then int(16) +testParamGenericCast: when true int(16) int(64) then int(16) +testExpression: when true int(16) uint(8) then int(16) +testExpression: when true uint(8) int(16) then int(16) +testParamExpression: when true int(16) uint(8) then int(16) +testParamExpression: when true uint(8) int(16) then uint(8) +testGeneric: when true int(16) uint(8) then int(16) +testGeneric: when true uint(8) int(16) then int(16) +testGenericCast: when true int(16) uint(8) then int(16) +testGenericCast: when true uint(8) int(16) then int(16) +testParamGenericCast: when true int(16) uint(8) then int(16) +testParamGenericCast: when true uint(8) int(16) then uint(8) +testExpression: when true int(16) uint(16) then uint(16) +testExpression: when true uint(16) int(16) then uint(16) +testParamExpression: when true int(16) uint(16) then int(16) +testParamExpression: when true uint(16) int(16) then uint(16) +testGeneric: when true int(16) uint(16) then uint(16) +testGeneric: when true uint(16) int(16) then uint(16) +testGenericCast: when true int(16) uint(16) then uint(16) +testGenericCast: when true uint(16) int(16) then uint(16) +testParamGenericCast: when true int(16) uint(16) then int(16) +testParamGenericCast: when true uint(16) int(16) then uint(16) +testExpression: when true int(16) uint(32) then uint(32) +testExpression: when true uint(32) int(16) then uint(32) +testParamExpression: when true int(16) uint(32) then int(16) +testParamExpression: when true uint(32) int(16) then uint(32) +testGeneric: when true int(16) uint(32) then uint(32) +testGeneric: when true uint(32) int(16) then uint(32) +testGenericCast: when true int(16) uint(32) then uint(32) +testGenericCast: when true uint(32) int(16) then uint(32) +testParamGenericCast: when true int(16) uint(32) then int(16) +testParamGenericCast: when true uint(32) int(16) then uint(32) +testExpression: when true int(16) uint(64) then uint(64) +testExpression: when true uint(64) int(16) then uint(64) +testParamExpression: when true int(16) uint(64) then int(16) +testParamExpression: when true uint(64) int(16) then uint(64) +testGeneric: when true int(16) uint(64) then uint(64) +testGeneric: when true uint(64) int(16) then uint(64) +testGenericCast: when true int(16) uint(64) then uint(64) +testGenericCast: when true uint(64) int(16) then uint(64) +testParamGenericCast: when true int(16) uint(64) then int(16) +testParamGenericCast: when true uint(64) int(16) then uint(64) +testGeneric: when true int(32) int(8) then int(32) +testGenericCast: when true int(32) int(8) then int(32) +testExpression: when true int(32) int(8) then int(32) +testParamExpression: when true int(32) int(8) then int(32) +testParamGenericCast: when true int(32) int(8) then int(32) +testGeneric: when true int(32) int(16) then int(32) +testGenericCast: when true int(32) int(16) then int(32) +testExpression: when true int(32) int(16) then int(32) +testParamExpression: when true int(32) int(16) then int(32) +testParamGenericCast: when true int(32) int(16) then int(32) +testGeneric: when true int(32) int(32) then int(32) +testGenericCast: when true int(32) int(32) then int(32) +testExpression: when true int(32) int(32) then int(32) +testParamExpression: when true int(32) int(32) then int(32) +testParamGenericCast: when true int(32) int(32) then int(32) +testGeneric: when true int(32) int(64) then int(64) +testGenericCast: when true int(32) int(64) then int(64) +testExpression: when true int(32) int(64) then int(64) +testParamExpression: when true int(32) int(64) then int(32) +testParamGenericCast: when true int(32) int(64) then int(32) +testExpression: when true int(32) uint(8) then int(32) +testExpression: when true uint(8) int(32) then int(32) +testParamExpression: when true int(32) uint(8) then int(32) +testParamExpression: when true uint(8) int(32) then uint(8) +testGeneric: when true int(32) uint(8) then int(32) +testGeneric: when true uint(8) int(32) then int(32) +testGenericCast: when true int(32) uint(8) then int(32) +testGenericCast: when true uint(8) int(32) then int(32) +testParamGenericCast: when true int(32) uint(8) then int(32) +testParamGenericCast: when true uint(8) int(32) then uint(8) +testExpression: when true int(32) uint(16) then int(32) +testExpression: when true uint(16) int(32) then int(32) +testParamExpression: when true int(32) uint(16) then int(32) +testParamExpression: when true uint(16) int(32) then uint(16) +testGeneric: when true int(32) uint(16) then int(32) +testGeneric: when true uint(16) int(32) then int(32) +testGenericCast: when true int(32) uint(16) then int(32) +testGenericCast: when true uint(16) int(32) then int(32) +testParamGenericCast: when true int(32) uint(16) then int(32) +testParamGenericCast: when true uint(16) int(32) then uint(16) +testExpression: when true int(32) uint(32) then uint(32) +testExpression: when true uint(32) int(32) then uint(32) +testParamExpression: when true int(32) uint(32) then int(32) +testParamExpression: when true uint(32) int(32) then uint(32) +testGeneric: when true int(32) uint(32) then uint(32) +testGeneric: when true uint(32) int(32) then uint(32) +testGenericCast: when true int(32) uint(32) then uint(32) +testGenericCast: when true uint(32) int(32) then uint(32) +testParamGenericCast: when true int(32) uint(32) then int(32) +testParamGenericCast: when true uint(32) int(32) then uint(32) +testExpression: when true int(32) uint(64) then uint(64) +testExpression: when true uint(64) int(32) then uint(64) +testParamExpression: when true int(32) uint(64) then int(32) +testParamExpression: when true uint(64) int(32) then uint(64) +testGeneric: when true int(32) uint(64) then uint(64) +testGeneric: when true uint(64) int(32) then uint(64) +testGenericCast: when true int(32) uint(64) then uint(64) +testGenericCast: when true uint(64) int(32) then uint(64) +testParamGenericCast: when true int(32) uint(64) then int(32) +testParamGenericCast: when true uint(64) int(32) then uint(64) +testGeneric: when true int(64) int(8) then int(64) +testGenericCast: when true int(64) int(8) then int(64) +testExpression: when true int(64) int(8) then int(64) +testParamExpression: when true int(64) int(8) then int(64) +testParamGenericCast: when true int(64) int(8) then int(64) +testGeneric: when true int(64) int(16) then int(64) +testGenericCast: when true int(64) int(16) then int(64) +testExpression: when true int(64) int(16) then int(64) +testParamExpression: when true int(64) int(16) then int(64) +testParamGenericCast: when true int(64) int(16) then int(64) +testGeneric: when true int(64) int(32) then int(64) +testGenericCast: when true int(64) int(32) then int(64) +testExpression: when true int(64) int(32) then int(64) +testParamExpression: when true int(64) int(32) then int(64) +testParamGenericCast: when true int(64) int(32) then int(64) +testGeneric: when true int(64) int(64) then int(64) +testGenericCast: when true int(64) int(64) then int(64) +testExpression: when true int(64) int(64) then int(64) +testParamExpression: when true int(64) int(64) then int(64) +testParamGenericCast: when true int(64) int(64) then int(64) +testExpression: when true int(64) uint(8) then int(64) +testExpression: when true uint(8) int(64) then int(64) +testParamExpression: when true int(64) uint(8) then int(64) +testParamExpression: when true uint(8) int(64) then uint(8) +testGeneric: when true int(64) uint(8) then int(64) +testGeneric: when true uint(8) int(64) then int(64) +testGenericCast: when true int(64) uint(8) then int(64) +testGenericCast: when true uint(8) int(64) then int(64) +testParamGenericCast: when true int(64) uint(8) then int(64) +testParamGenericCast: when true uint(8) int(64) then uint(8) +testExpression: when true int(64) uint(16) then int(64) +testExpression: when true uint(16) int(64) then int(64) +testParamExpression: when true int(64) uint(16) then int(64) +testParamExpression: when true uint(16) int(64) then uint(16) +testGeneric: when true int(64) uint(16) then int(64) +testGeneric: when true uint(16) int(64) then int(64) +testGenericCast: when true int(64) uint(16) then int(64) +testGenericCast: when true uint(16) int(64) then int(64) +testParamGenericCast: when true int(64) uint(16) then int(64) +testParamGenericCast: when true uint(16) int(64) then uint(16) +testExpression: when true int(64) uint(32) then int(64) +testExpression: when true uint(32) int(64) then int(64) +testParamExpression: when true int(64) uint(32) then int(64) +testParamExpression: when true uint(32) int(64) then uint(32) +testGeneric: when true int(64) uint(32) then int(64) +testGeneric: when true uint(32) int(64) then int(64) +testGenericCast: when true int(64) uint(32) then int(64) +testGenericCast: when true uint(32) int(64) then int(64) +testParamGenericCast: when true int(64) uint(32) then int(64) +testParamGenericCast: when true uint(32) int(64) then uint(32) +testExpression: when true int(64) uint(64) then uint(64) +testExpression: when true uint(64) int(64) then uint(64) +testParamExpression: when true int(64) uint(64) then int(64) +testParamExpression: when true uint(64) int(64) then uint(64) +testGeneric: when true int(64) uint(64) then uint(64) +testGeneric: when true uint(64) int(64) then uint(64) +testGenericCast: when true int(64) uint(64) then uint(64) +testGenericCast: when true uint(64) int(64) then uint(64) +testParamGenericCast: when true int(64) uint(64) then int(64) +testParamGenericCast: when true uint(64) int(64) then uint(64) +testGeneric: when true uint(8) uint(8) then uint(8) +testGenericCast: when true uint(8) uint(8) then uint(8) +testExpression: when true uint(8) uint(8) then uint(8) +testParamExpression: when true uint(8) uint(8) then uint(8) +testParamGenericCast: when true uint(8) uint(8) then uint(8) +testGeneric: when true uint(8) uint(16) then uint(16) +testGenericCast: when true uint(8) uint(16) then uint(16) +testExpression: when true uint(8) uint(16) then uint(16) +testParamExpression: when true uint(8) uint(16) then uint(8) +testParamGenericCast: when true uint(8) uint(16) then uint(8) +testGeneric: when true uint(8) uint(32) then uint(32) +testGenericCast: when true uint(8) uint(32) then uint(32) +testExpression: when true uint(8) uint(32) then uint(32) +testParamExpression: when true uint(8) uint(32) then uint(8) +testParamGenericCast: when true uint(8) uint(32) then uint(8) +testGeneric: when true uint(8) uint(64) then uint(64) +testGenericCast: when true uint(8) uint(64) then uint(64) +testExpression: when true uint(8) uint(64) then uint(64) +testParamExpression: when true uint(8) uint(64) then uint(8) +testParamGenericCast: when true uint(8) uint(64) then uint(8) +testGeneric: when true uint(16) uint(8) then uint(16) +testGenericCast: when true uint(16) uint(8) then uint(16) +testExpression: when true uint(16) uint(8) then uint(16) +testParamExpression: when true uint(16) uint(8) then uint(16) +testParamGenericCast: when true uint(16) uint(8) then uint(16) +testGeneric: when true uint(16) uint(16) then uint(16) +testGenericCast: when true uint(16) uint(16) then uint(16) +testExpression: when true uint(16) uint(16) then uint(16) +testParamExpression: when true uint(16) uint(16) then uint(16) +testParamGenericCast: when true uint(16) uint(16) then uint(16) +testGeneric: when true uint(16) uint(32) then uint(32) +testGenericCast: when true uint(16) uint(32) then uint(32) +testExpression: when true uint(16) uint(32) then uint(32) +testParamExpression: when true uint(16) uint(32) then uint(16) +testParamGenericCast: when true uint(16) uint(32) then uint(16) +testGeneric: when true uint(16) uint(64) then uint(64) +testGenericCast: when true uint(16) uint(64) then uint(64) +testExpression: when true uint(16) uint(64) then uint(64) +testParamExpression: when true uint(16) uint(64) then uint(16) +testParamGenericCast: when true uint(16) uint(64) then uint(16) +testGeneric: when true uint(32) uint(8) then uint(32) +testGenericCast: when true uint(32) uint(8) then uint(32) +testExpression: when true uint(32) uint(8) then uint(32) +testParamExpression: when true uint(32) uint(8) then uint(32) +testParamGenericCast: when true uint(32) uint(8) then uint(32) +testGeneric: when true uint(32) uint(16) then uint(32) +testGenericCast: when true uint(32) uint(16) then uint(32) +testExpression: when true uint(32) uint(16) then uint(32) +testParamExpression: when true uint(32) uint(16) then uint(32) +testParamGenericCast: when true uint(32) uint(16) then uint(32) +testGeneric: when true uint(32) uint(32) then uint(32) +testGenericCast: when true uint(32) uint(32) then uint(32) +testExpression: when true uint(32) uint(32) then uint(32) +testParamExpression: when true uint(32) uint(32) then uint(32) +testParamGenericCast: when true uint(32) uint(32) then uint(32) +testGeneric: when true uint(32) uint(64) then uint(64) +testGenericCast: when true uint(32) uint(64) then uint(64) +testExpression: when true uint(32) uint(64) then uint(64) +testParamExpression: when true uint(32) uint(64) then uint(32) +testParamGenericCast: when true uint(32) uint(64) then uint(32) +testGeneric: when true uint(64) uint(8) then uint(64) +testGenericCast: when true uint(64) uint(8) then uint(64) +testExpression: when true uint(64) uint(8) then uint(64) +testParamExpression: when true uint(64) uint(8) then uint(64) +testParamGenericCast: when true uint(64) uint(8) then uint(64) +testGeneric: when true uint(64) uint(16) then uint(64) +testGenericCast: when true uint(64) uint(16) then uint(64) +testExpression: when true uint(64) uint(16) then uint(64) +testParamExpression: when true uint(64) uint(16) then uint(64) +testParamGenericCast: when true uint(64) uint(16) then uint(64) +testGeneric: when true uint(64) uint(32) then uint(64) +testGenericCast: when true uint(64) uint(32) then uint(64) +testExpression: when true uint(64) uint(32) then uint(64) +testParamExpression: when true uint(64) uint(32) then uint(64) +testParamGenericCast: when true uint(64) uint(32) then uint(64) +testGeneric: when true uint(64) uint(64) then uint(64) +testGenericCast: when true uint(64) uint(64) then uint(64) +testExpression: when true uint(64) uint(64) then uint(64) +testParamExpression: when true uint(64) uint(64) then uint(64) +testParamGenericCast: when true uint(64) uint(64) then uint(64) +testGeneric: when false int(8) int(8) then int(8) +testGenericCast: when false int(8) int(8) then int(8) +testExpression: when false int(8) int(8) then int(8) +testParamExpression: when false int(8) int(8) then int(8) +testParamGenericCast: when false int(8) int(8) then int(8) +testGeneric: when false int(8) int(16) then int(16) +testGenericCast: when false int(8) int(16) then int(16) +testExpression: when false int(8) int(16) then int(16) +testParamExpression: when false int(8) int(16) then int(8) +testParamGenericCast: when false int(8) int(16) then int(8) +testGeneric: when false int(8) int(32) then int(32) +testGenericCast: when false int(8) int(32) then int(32) +testExpression: when false int(8) int(32) then int(32) +testParamExpression: when false int(8) int(32) then int(8) +testParamGenericCast: when false int(8) int(32) then int(8) +testGeneric: when false int(8) int(64) then int(64) +testGenericCast: when false int(8) int(64) then int(64) +testExpression: when false int(8) int(64) then int(64) +testParamExpression: when false int(8) int(64) then int(8) +testParamGenericCast: when false int(8) int(64) then int(8) +testExpression: when false int(8) uint(8) then uint(8) +testExpression: when false uint(8) int(8) then uint(8) +testParamExpression: when false int(8) uint(8) then int(8) +testParamExpression: when false uint(8) int(8) then uint(8) +testGeneric: when false int(8) uint(8) then uint(8) +testGeneric: when false uint(8) int(8) then uint(8) +testGenericCast: when false int(8) uint(8) then uint(8) +testGenericCast: when false uint(8) int(8) then uint(8) +testParamGenericCast: when false int(8) uint(8) then int(8) +testParamGenericCast: when false uint(8) int(8) then uint(8) +testExpression: when false int(8) uint(16) then uint(16) +testExpression: when false uint(16) int(8) then uint(16) +testParamExpression: when false int(8) uint(16) then int(8) +testParamExpression: when false uint(16) int(8) then uint(16) +testGeneric: when false int(8) uint(16) then uint(16) +testGeneric: when false uint(16) int(8) then uint(16) +testGenericCast: when false int(8) uint(16) then uint(16) +testGenericCast: when false uint(16) int(8) then uint(16) +testParamGenericCast: when false int(8) uint(16) then int(8) +testParamGenericCast: when false uint(16) int(8) then uint(16) +testExpression: when false int(8) uint(32) then uint(32) +testExpression: when false uint(32) int(8) then uint(32) +testParamExpression: when false int(8) uint(32) then int(8) +testParamExpression: when false uint(32) int(8) then uint(32) +testGeneric: when false int(8) uint(32) then uint(32) +testGeneric: when false uint(32) int(8) then uint(32) +testGenericCast: when false int(8) uint(32) then uint(32) +testGenericCast: when false uint(32) int(8) then uint(32) +testParamGenericCast: when false int(8) uint(32) then int(8) +testParamGenericCast: when false uint(32) int(8) then uint(32) +testExpression: when false int(8) uint(64) then uint(64) +testExpression: when false uint(64) int(8) then uint(64) +testParamExpression: when false int(8) uint(64) then int(8) +testParamExpression: when false uint(64) int(8) then uint(64) +testGeneric: when false int(8) uint(64) then uint(64) +testGeneric: when false uint(64) int(8) then uint(64) +testGenericCast: when false int(8) uint(64) then uint(64) +testGenericCast: when false uint(64) int(8) then uint(64) +testParamGenericCast: when false int(8) uint(64) then int(8) +testParamGenericCast: when false uint(64) int(8) then uint(64) +testGeneric: when false int(16) int(8) then int(16) +testGenericCast: when false int(16) int(8) then int(16) +testExpression: when false int(16) int(8) then int(16) +testParamExpression: when false int(16) int(8) then int(16) +testParamGenericCast: when false int(16) int(8) then int(16) +testGeneric: when false int(16) int(16) then int(16) +testGenericCast: when false int(16) int(16) then int(16) +testExpression: when false int(16) int(16) then int(16) +testParamExpression: when false int(16) int(16) then int(16) +testParamGenericCast: when false int(16) int(16) then int(16) +testGeneric: when false int(16) int(32) then int(32) +testGenericCast: when false int(16) int(32) then int(32) +testExpression: when false int(16) int(32) then int(32) +testParamExpression: when false int(16) int(32) then int(16) +testParamGenericCast: when false int(16) int(32) then int(16) +testGeneric: when false int(16) int(64) then int(64) +testGenericCast: when false int(16) int(64) then int(64) +testExpression: when false int(16) int(64) then int(64) +testParamExpression: when false int(16) int(64) then int(16) +testParamGenericCast: when false int(16) int(64) then int(16) +testExpression: when false int(16) uint(8) then int(16) +testExpression: when false uint(8) int(16) then int(16) +testParamExpression: when false int(16) uint(8) then int(16) +testParamExpression: when false uint(8) int(16) then uint(8) +testGeneric: when false int(16) uint(8) then int(16) +testGeneric: when false uint(8) int(16) then int(16) +testGenericCast: when false int(16) uint(8) then int(16) +testGenericCast: when false uint(8) int(16) then int(16) +testParamGenericCast: when false int(16) uint(8) then int(16) +testParamGenericCast: when false uint(8) int(16) then uint(8) +testExpression: when false int(16) uint(16) then uint(16) +testExpression: when false uint(16) int(16) then uint(16) +testParamExpression: when false int(16) uint(16) then int(16) +testParamExpression: when false uint(16) int(16) then uint(16) +testGeneric: when false int(16) uint(16) then uint(16) +testGeneric: when false uint(16) int(16) then uint(16) +testGenericCast: when false int(16) uint(16) then uint(16) +testGenericCast: when false uint(16) int(16) then uint(16) +testParamGenericCast: when false int(16) uint(16) then int(16) +testParamGenericCast: when false uint(16) int(16) then uint(16) +testExpression: when false int(16) uint(32) then uint(32) +testExpression: when false uint(32) int(16) then uint(32) +testParamExpression: when false int(16) uint(32) then int(16) +testParamExpression: when false uint(32) int(16) then uint(32) +testGeneric: when false int(16) uint(32) then uint(32) +testGeneric: when false uint(32) int(16) then uint(32) +testGenericCast: when false int(16) uint(32) then uint(32) +testGenericCast: when false uint(32) int(16) then uint(32) +testParamGenericCast: when false int(16) uint(32) then int(16) +testParamGenericCast: when false uint(32) int(16) then uint(32) +testExpression: when false int(16) uint(64) then uint(64) +testExpression: when false uint(64) int(16) then uint(64) +testParamExpression: when false int(16) uint(64) then int(16) +testParamExpression: when false uint(64) int(16) then uint(64) +testGeneric: when false int(16) uint(64) then uint(64) +testGeneric: when false uint(64) int(16) then uint(64) +testGenericCast: when false int(16) uint(64) then uint(64) +testGenericCast: when false uint(64) int(16) then uint(64) +testParamGenericCast: when false int(16) uint(64) then int(16) +testParamGenericCast: when false uint(64) int(16) then uint(64) +testGeneric: when false int(32) int(8) then int(32) +testGenericCast: when false int(32) int(8) then int(32) +testExpression: when false int(32) int(8) then int(32) +testParamExpression: when false int(32) int(8) then int(32) +testParamGenericCast: when false int(32) int(8) then int(32) +testGeneric: when false int(32) int(16) then int(32) +testGenericCast: when false int(32) int(16) then int(32) +testExpression: when false int(32) int(16) then int(32) +testParamExpression: when false int(32) int(16) then int(32) +testParamGenericCast: when false int(32) int(16) then int(32) +testGeneric: when false int(32) int(32) then int(32) +testGenericCast: when false int(32) int(32) then int(32) +testExpression: when false int(32) int(32) then int(32) +testParamExpression: when false int(32) int(32) then int(32) +testParamGenericCast: when false int(32) int(32) then int(32) +testGeneric: when false int(32) int(64) then int(64) +testGenericCast: when false int(32) int(64) then int(64) +testExpression: when false int(32) int(64) then int(64) +testParamExpression: when false int(32) int(64) then int(32) +testParamGenericCast: when false int(32) int(64) then int(32) +testExpression: when false int(32) uint(8) then int(32) +testExpression: when false uint(8) int(32) then int(32) +testParamExpression: when false int(32) uint(8) then int(32) +testParamExpression: when false uint(8) int(32) then uint(8) +testGeneric: when false int(32) uint(8) then int(32) +testGeneric: when false uint(8) int(32) then int(32) +testGenericCast: when false int(32) uint(8) then int(32) +testGenericCast: when false uint(8) int(32) then int(32) +testParamGenericCast: when false int(32) uint(8) then int(32) +testParamGenericCast: when false uint(8) int(32) then uint(8) +testExpression: when false int(32) uint(16) then int(32) +testExpression: when false uint(16) int(32) then int(32) +testParamExpression: when false int(32) uint(16) then int(32) +testParamExpression: when false uint(16) int(32) then uint(16) +testGeneric: when false int(32) uint(16) then int(32) +testGeneric: when false uint(16) int(32) then int(32) +testGenericCast: when false int(32) uint(16) then int(32) +testGenericCast: when false uint(16) int(32) then int(32) +testParamGenericCast: when false int(32) uint(16) then int(32) +testParamGenericCast: when false uint(16) int(32) then uint(16) +testExpression: when false int(32) uint(32) then uint(32) +testExpression: when false uint(32) int(32) then uint(32) +testParamExpression: when false int(32) uint(32) then int(32) +testParamExpression: when false uint(32) int(32) then uint(32) +testGeneric: when false int(32) uint(32) then uint(32) +testGeneric: when false uint(32) int(32) then uint(32) +testGenericCast: when false int(32) uint(32) then uint(32) +testGenericCast: when false uint(32) int(32) then uint(32) +testParamGenericCast: when false int(32) uint(32) then int(32) +testParamGenericCast: when false uint(32) int(32) then uint(32) +testExpression: when false int(32) uint(64) then uint(64) +testExpression: when false uint(64) int(32) then uint(64) +testParamExpression: when false int(32) uint(64) then int(32) +testParamExpression: when false uint(64) int(32) then uint(64) +testGeneric: when false int(32) uint(64) then uint(64) +testGeneric: when false uint(64) int(32) then uint(64) +testGenericCast: when false int(32) uint(64) then uint(64) +testGenericCast: when false uint(64) int(32) then uint(64) +testParamGenericCast: when false int(32) uint(64) then int(32) +testParamGenericCast: when false uint(64) int(32) then uint(64) +testGeneric: when false int(64) int(8) then int(64) +testGenericCast: when false int(64) int(8) then int(64) +testExpression: when false int(64) int(8) then int(64) +testParamExpression: when false int(64) int(8) then int(64) +testParamGenericCast: when false int(64) int(8) then int(64) +testGeneric: when false int(64) int(16) then int(64) +testGenericCast: when false int(64) int(16) then int(64) +testExpression: when false int(64) int(16) then int(64) +testParamExpression: when false int(64) int(16) then int(64) +testParamGenericCast: when false int(64) int(16) then int(64) +testGeneric: when false int(64) int(32) then int(64) +testGenericCast: when false int(64) int(32) then int(64) +testExpression: when false int(64) int(32) then int(64) +testParamExpression: when false int(64) int(32) then int(64) +testParamGenericCast: when false int(64) int(32) then int(64) +testGeneric: when false int(64) int(64) then int(64) +testGenericCast: when false int(64) int(64) then int(64) +testExpression: when false int(64) int(64) then int(64) +testParamExpression: when false int(64) int(64) then int(64) +testParamGenericCast: when false int(64) int(64) then int(64) +testExpression: when false int(64) uint(8) then int(64) +testExpression: when false uint(8) int(64) then int(64) +testParamExpression: when false int(64) uint(8) then int(64) +testParamExpression: when false uint(8) int(64) then uint(8) +testGeneric: when false int(64) uint(8) then int(64) +testGeneric: when false uint(8) int(64) then int(64) +testGenericCast: when false int(64) uint(8) then int(64) +testGenericCast: when false uint(8) int(64) then int(64) +testParamGenericCast: when false int(64) uint(8) then int(64) +testParamGenericCast: when false uint(8) int(64) then uint(8) +testExpression: when false int(64) uint(16) then int(64) +testExpression: when false uint(16) int(64) then int(64) +testParamExpression: when false int(64) uint(16) then int(64) +testParamExpression: when false uint(16) int(64) then uint(16) +testGeneric: when false int(64) uint(16) then int(64) +testGeneric: when false uint(16) int(64) then int(64) +testGenericCast: when false int(64) uint(16) then int(64) +testGenericCast: when false uint(16) int(64) then int(64) +testParamGenericCast: when false int(64) uint(16) then int(64) +testParamGenericCast: when false uint(16) int(64) then uint(16) +testExpression: when false int(64) uint(32) then int(64) +testExpression: when false uint(32) int(64) then int(64) +testParamExpression: when false int(64) uint(32) then int(64) +testParamExpression: when false uint(32) int(64) then uint(32) +testGeneric: when false int(64) uint(32) then int(64) +testGeneric: when false uint(32) int(64) then int(64) +testGenericCast: when false int(64) uint(32) then int(64) +testGenericCast: when false uint(32) int(64) then int(64) +testParamGenericCast: when false int(64) uint(32) then int(64) +testParamGenericCast: when false uint(32) int(64) then uint(32) +testExpression: when false int(64) uint(64) then uint(64) +testExpression: when false uint(64) int(64) then uint(64) +testParamExpression: when false int(64) uint(64) then int(64) +testParamExpression: when false uint(64) int(64) then uint(64) +testGeneric: when false int(64) uint(64) then uint(64) +testGeneric: when false uint(64) int(64) then uint(64) +testGenericCast: when false int(64) uint(64) then uint(64) +testGenericCast: when false uint(64) int(64) then uint(64) +testParamGenericCast: when false int(64) uint(64) then int(64) +testParamGenericCast: when false uint(64) int(64) then uint(64) +testGeneric: when false uint(8) uint(8) then uint(8) +testGenericCast: when false uint(8) uint(8) then uint(8) +testExpression: when false uint(8) uint(8) then uint(8) +testParamExpression: when false uint(8) uint(8) then uint(8) +testParamGenericCast: when false uint(8) uint(8) then uint(8) +testGeneric: when false uint(8) uint(16) then uint(16) +testGenericCast: when false uint(8) uint(16) then uint(16) +testExpression: when false uint(8) uint(16) then uint(16) +testParamExpression: when false uint(8) uint(16) then uint(8) +testParamGenericCast: when false uint(8) uint(16) then uint(8) +testGeneric: when false uint(8) uint(32) then uint(32) +testGenericCast: when false uint(8) uint(32) then uint(32) +testExpression: when false uint(8) uint(32) then uint(32) +testParamExpression: when false uint(8) uint(32) then uint(8) +testParamGenericCast: when false uint(8) uint(32) then uint(8) +testGeneric: when false uint(8) uint(64) then uint(64) +testGenericCast: when false uint(8) uint(64) then uint(64) +testExpression: when false uint(8) uint(64) then uint(64) +testParamExpression: when false uint(8) uint(64) then uint(8) +testParamGenericCast: when false uint(8) uint(64) then uint(8) +testGeneric: when false uint(16) uint(8) then uint(16) +testGenericCast: when false uint(16) uint(8) then uint(16) +testExpression: when false uint(16) uint(8) then uint(16) +testParamExpression: when false uint(16) uint(8) then uint(16) +testParamGenericCast: when false uint(16) uint(8) then uint(16) +testGeneric: when false uint(16) uint(16) then uint(16) +testGenericCast: when false uint(16) uint(16) then uint(16) +testExpression: when false uint(16) uint(16) then uint(16) +testParamExpression: when false uint(16) uint(16) then uint(16) +testParamGenericCast: when false uint(16) uint(16) then uint(16) +testGeneric: when false uint(16) uint(32) then uint(32) +testGenericCast: when false uint(16) uint(32) then uint(32) +testExpression: when false uint(16) uint(32) then uint(32) +testParamExpression: when false uint(16) uint(32) then uint(16) +testParamGenericCast: when false uint(16) uint(32) then uint(16) +testGeneric: when false uint(16) uint(64) then uint(64) +testGenericCast: when false uint(16) uint(64) then uint(64) +testExpression: when false uint(16) uint(64) then uint(64) +testParamExpression: when false uint(16) uint(64) then uint(16) +testParamGenericCast: when false uint(16) uint(64) then uint(16) +testGeneric: when false uint(32) uint(8) then uint(32) +testGenericCast: when false uint(32) uint(8) then uint(32) +testExpression: when false uint(32) uint(8) then uint(32) +testParamExpression: when false uint(32) uint(8) then uint(32) +testParamGenericCast: when false uint(32) uint(8) then uint(32) +testGeneric: when false uint(32) uint(16) then uint(32) +testGenericCast: when false uint(32) uint(16) then uint(32) +testExpression: when false uint(32) uint(16) then uint(32) +testParamExpression: when false uint(32) uint(16) then uint(32) +testParamGenericCast: when false uint(32) uint(16) then uint(32) +testGeneric: when false uint(32) uint(32) then uint(32) +testGenericCast: when false uint(32) uint(32) then uint(32) +testExpression: when false uint(32) uint(32) then uint(32) +testParamExpression: when false uint(32) uint(32) then uint(32) +testParamGenericCast: when false uint(32) uint(32) then uint(32) +testGeneric: when false uint(32) uint(64) then uint(64) +testGenericCast: when false uint(32) uint(64) then uint(64) +testExpression: when false uint(32) uint(64) then uint(64) +testParamExpression: when false uint(32) uint(64) then uint(32) +testParamGenericCast: when false uint(32) uint(64) then uint(32) +testGeneric: when false uint(64) uint(8) then uint(64) +testGenericCast: when false uint(64) uint(8) then uint(64) +testExpression: when false uint(64) uint(8) then uint(64) +testParamExpression: when false uint(64) uint(8) then uint(64) +testParamGenericCast: when false uint(64) uint(8) then uint(64) +testGeneric: when false uint(64) uint(16) then uint(64) +testGenericCast: when false uint(64) uint(16) then uint(64) +testExpression: when false uint(64) uint(16) then uint(64) +testParamExpression: when false uint(64) uint(16) then uint(64) +testParamGenericCast: when false uint(64) uint(16) then uint(64) +testGeneric: when false uint(64) uint(32) then uint(64) +testGenericCast: when false uint(64) uint(32) then uint(64) +testExpression: when false uint(64) uint(32) then uint(64) +testParamExpression: when false uint(64) uint(32) then uint(64) +testParamGenericCast: when false uint(64) uint(32) then uint(64) +testGeneric: when false uint(64) uint(64) then uint(64) +testGenericCast: when false uint(64) uint(64) then uint(64) +testExpression: when false uint(64) uint(64) then uint(64) +testParamExpression: when false uint(64) uint(64) then uint(64) +testParamGenericCast: when false uint(64) uint(64) then uint(64) From 41a138180847b91ce64eaa003f044c5c2f647714 Mon Sep 17 00:00:00 2001 From: Ahmad Rezaii Date: Fri, 24 Jan 2025 16:41:20 -0700 Subject: [PATCH 4/5] fix spacing, comment Signed-off-by: Ahmad Rezaii --- frontend/test/resolution/testIf.cpp | 1 + frontend/test/resolution/testIntegralReturnType.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/test/resolution/testIf.cpp b/frontend/test/resolution/testIf.cpp index b417e42c1ef6..f875f159e79a 100644 --- a/frontend/test/resolution/testIf.cpp +++ b/frontend/test/resolution/testIf.cpp @@ -418,5 +418,6 @@ int main() { testIfVarErrorUseInElseBranch4(); testIfVarErrorNonClassType(); testIfVarNonNilInThen(); + return 0; } diff --git a/frontend/test/resolution/testIntegralReturnType.cpp b/frontend/test/resolution/testIntegralReturnType.cpp index 44e4467edef4..8e427cacf332 100644 --- a/frontend/test/resolution/testIntegralReturnType.cpp +++ b/frontend/test/resolution/testIntegralReturnType.cpp @@ -119,7 +119,6 @@ testIfExpressionIntegralTypesHelper(std::string program, auto context = buildStdContext(); ErrorGuard guard(context); // use only ints. 8, 16, 32, 64 bit. use each size with every other size. - //validated against the chart testIntegralReturn(program, boolCondition, "int(8)", "int(8)", IntType::get(context, 8), testType); testIntegralReturn(program, boolCondition, "int(8)", "int(16)", IntType::get(context, 16), testType); testIntegralReturn(program, boolCondition, "int(8)", "int(32)", IntType::get(context, 32), testType); From 59e37fb5aa2d6dcc0078a9d18a747476b9f67a8d Mon Sep 17 00:00:00 2001 From: Ahmad Rezaii Date: Wed, 5 Mar 2025 15:58:46 -0700 Subject: [PATCH 5/5] try stupid things Signed-off-by: Ahmad Rezaii --- compiler/resolution/resolveFunction.cpp | 37 ++++++++++++++----------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/compiler/resolution/resolveFunction.cpp b/compiler/resolution/resolveFunction.cpp index 1c9b7eebdbb9..6871f736ac87 100644 --- a/compiler/resolution/resolveFunction.cpp +++ b/compiler/resolution/resolveFunction.cpp @@ -1965,12 +1965,12 @@ void resolveIfExprType(CondStmt* stmt) { retType = thenType; } else { bool promote = false; - - if (canDispatch(elseType, elseSym, thenType, NULL, fn, &promote) && - promote == false) { + bool paramNarrows = false; + if (canDispatch(elseType, elseSym, thenType, NULL, fn, &promote, ¶mNarrows) && + promote == false && !paramNarrows) { retType = thenType; - } else if (canDispatch(thenType, thenSym, elseType, NULL, fn, &promote) && - promote == false) { + } else if (canDispatch(thenType, thenSym, elseType, NULL, fn, &promote, ¶mNarrows) && + promote == false && !paramNarrows) { retType = elseType; } } @@ -2102,19 +2102,24 @@ void resolveReturnTypeAndYieldedType(FnSymbol* fn, Type** yieldedType) { for (int j = 0; j < retTypes.n; j++) { if (retTypes.v[i] != retTypes.v[j]) { bool requireScalarPromotion = false; + bool paramNarrows = false; + if (canDispatch(retTypes.v[j], + retSymbols.v[j], + retTypes.v[i], + NULL, + fn, + &requireScalarPromotion, + ¶mNarrows) == false) { + best = false; + } - if (canDispatch(retTypes.v[j], - retSymbols.v[j], - retTypes.v[i], - NULL, - fn, - &requireScalarPromotion) == false) { - best = false; - } + if (requireScalarPromotion) { + best = false; + } - if (requireScalarPromotion) { - best = false; - } + if (paramNarrows && fn->retTag != RET_PARAM) { + best = false; + } } }