X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Fexpressc.c;h=f8c75530f67eb365f497e48a8980407c1c9e8b8c;hb=8e63120c630c94c598d4e2d6ba823dac59bce8fa;hp=6651547081a0fb45ffa93c83ac9ff00113ded6b0;hpb=d11f2f726ed7feea617476d99cf7505ddd9a27ce;p=inform.git diff --git a/src/expressc.c b/src/expressc.c index 6651547..f8c7553 100644 --- a/src/expressc.c +++ b/src/expressc.c @@ -1,8 +1,8 @@ /* ------------------------------------------------------------------------- */ /* "expressc" : The expression code generator */ /* */ -/* Part of Inform 6.35 */ -/* copyright (c) Graham Nelson 1993 - 2021 */ +/* Part of Inform 6.40 */ +/* copyright (c) Graham Nelson 1993 - 2022 */ /* */ /* Inform is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -403,7 +403,7 @@ static void value_in_void_context_z(assembly_operand AO) case SHORT_CONSTANT_OT: t = ""; if (AO.marker == SYMBOL_MV) - t = (char *) (symbs[AO.value]); + t = (symbols[AO.value].name); break; case VARIABLE_OT: t = variable_name(AO.value); @@ -466,13 +466,13 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, size_ao = zero_ao; size_ao.value = -1; for (x=0; x' to access a --> or table array"); } else { - if ((array_types[y] == BYTE_ARRAY) - || (array_types[y] == STRING_ARRAY)) + if ((arrays[y].type == BYTE_ARRAY) + || (arrays[y].type == STRING_ARRAY)) warning("Using '-->' to access a -> or string array"); } } @@ -520,15 +520,15 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, max_ao = size_ao; if (byte_flag - && ((array_types[y] == WORD_ARRAY) - || (array_types[y] == TABLE_ARRAY))) + && ((arrays[y].type == WORD_ARRAY) + || (arrays[y].type == TABLE_ARRAY))) { max_ao.value = size_ao.value*2 + 1; type_ao.value += 8; } if ((!byte_flag) - && ((array_types[y] == BYTE_ARRAY) - || (array_types[y] == STRING_ARRAY) - || (array_types[y] == BUFFER_ARRAY))) + && ((arrays[y].type == BYTE_ARRAY) + || (arrays[y].type == STRING_ARRAY) + || (arrays[y].type == BUFFER_ARRAY))) { if ((size_ao.value % 2) == 0) max_ao.value = size_ao.value/2 - 1; else max_ao.value = (size_ao.value-1)/2; @@ -540,10 +540,10 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, if (max_ao.value >= 256) max_ao.type = LONG_CONSTANT_OT; /* Can't write to the size entry in a string or table */ - if (((array_types[y] == STRING_ARRAY) - || (array_types[y] == TABLE_ARRAY)) + if (((arrays[y].type == STRING_ARRAY) + || (arrays[y].type == TABLE_ARRAY)) && (!read_flag)) - { if ((array_types[y] == TABLE_ARRAY) && byte_flag) + { if ((arrays[y].type == TABLE_ARRAY) && byte_flag) zero_ao.value = 2; else zero_ao.value = 1; } @@ -716,6 +716,25 @@ static void compile_conditional_z(int oc, ASSERT_ZCODE(); + switch (oc) { + case test_attr_zc: + check_warn_symbol_type(&AO1, OBJECT_T, 0, "\"has/hasnt\" expression"); + check_warn_symbol_type(&AO2, ATTRIBUTE_T, 0, "\"has/hasnt\" expression"); + break; + case jin_zc: + check_warn_symbol_type(&AO1, OBJECT_T, 0, "\"in/notin\" expression"); + check_warn_symbol_type(&AO2, OBJECT_T, CLASS_T, "\"in/notin\" expression"); + break; + case 200: + /* first argument can be anything */ + check_warn_symbol_type(&AO2, CLASS_T, 0, "\"ofclass\" expression"); + break; + case 201: + /* first argument can be anything */ + check_warn_symbol_type(&AO2, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"provides\" expression"); + break; + } + if (oc<200) { if ((runtime_error_checking_switch) && (oc == jin_zc)) { if (flag) error_label = next_label++; @@ -785,7 +804,7 @@ static void value_in_void_context_g(assembly_operand AO) case ZEROCONSTANT_OT: t = ""; if (AO.marker == SYMBOL_MV) - t = (char *) (symbs[AO.value]); + t = (symbols[AO.value].name); break; case GLOBALVAR_OT: case LOCALVAR_OT: @@ -831,30 +850,30 @@ static void access_memory_g(int oc, assembly_operand AO1, assembly_operand AO2, { size_ao = zero_ao; size_ao.value = -1; for (x=0; x' to access a --> or table array"); } else { - if ((array_types[y] == BYTE_ARRAY) - || (array_types[y] == STRING_ARRAY)) + if ((arrays[y].type == BYTE_ARRAY) + || (arrays[y].type == STRING_ARRAY)) warning("Using '-->' to access a -> or string array"); } } @@ -876,25 +895,25 @@ static void access_memory_g(int oc, assembly_operand AO1, assembly_operand AO2, Here "size_ao.value" = largest permitted entry of its own kind */ max_ao = size_ao; if (data_len == 1 - && ((array_types[y] == WORD_ARRAY) - || (array_types[y] == TABLE_ARRAY))) + && ((arrays[y].type == WORD_ARRAY) + || (arrays[y].type == TABLE_ARRAY))) { max_ao.value = size_ao.value*4 + 3; type_ao.value += 8; } if (data_len == 4 - && ((array_types[y] == BYTE_ARRAY) - || (array_types[y] == STRING_ARRAY) - || (array_types[y] == BUFFER_ARRAY))) + && ((arrays[y].type == BYTE_ARRAY) + || (arrays[y].type == STRING_ARRAY) + || (arrays[y].type == BUFFER_ARRAY))) { max_ao.value = (size_ao.value-3)/4; type_ao.value += 16; } max_ao.value++; /* Can't write to the size entry in a string or table */ - if (((array_types[y] == STRING_ARRAY) - || (array_types[y] == TABLE_ARRAY)) + if (((arrays[y].type == STRING_ARRAY) + || (arrays[y].type == TABLE_ARRAY)) && (!read_flag)) - { if ((array_types[y] == TABLE_ARRAY) && data_len == 1) + { if ((arrays[y].type == TABLE_ARRAY) && data_len == 1) zero_ao.value = 4; else zero_ao.value = 1; } @@ -995,7 +1014,8 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, assembly_operand AO, AO2, AO3; int ln; int check_sp = FALSE, passed_label, failed_label, last_label; - + int pre_unreach; + if (veneer_mode) return AO1; @@ -1017,6 +1037,8 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, return AO1; } + pre_unreach = execution_never_reaches_here; + passed_label = next_label++; failed_label = next_label++; @@ -1037,6 +1059,8 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, /* Allow classes */ /* Test if zero... */ assembleg_1_branch(jz_gc, AO, failed_label); + if (!pre_unreach && execution_never_reaches_here) + execution_never_reaches_here |= EXECSTATE_NOWARN; /* Test if first byte is 0x70... */ assembleg_3(aloadb_gc, AO, zero_operand, stack_pointer); INITAO(&AO3); @@ -1047,6 +1071,8 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, else { /* Test if zero... */ assembleg_1_branch(jz_gc, AO, failed_label); + if (!pre_unreach && execution_never_reaches_here) + execution_never_reaches_here |= EXECSTATE_NOWARN; /* Test if first byte is 0x70... */ assembleg_3(aloadb_gc, AO, zero_operand, stack_pointer); INITAO(&AO3); @@ -1057,7 +1083,7 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, INITAOTV(&AO3, BYTECONSTANT_OT, GOBJFIELD_PARENT()); assembleg_3(aload_gc, AO, AO3, stack_pointer); ln = symbol_index("Class", -1); - AO3.value = svals[ln]; + AO3.value = symbols[ln].value; AO3.marker = OBJECT_MV; AO3.type = CONSTANT_OT; assembleg_2_branch(jne_gc, stack_pointer, AO3, passed_label); @@ -1078,7 +1104,7 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, else { /* Build the symbol for "Object" */ ln = symbol_index("Object", -1); - AO2.value = svals[ln]; + AO2.value = symbols[ln].value; AO2.marker = OBJECT_MV; AO2.type = CONSTANT_OT; if (check_sp) { @@ -1116,6 +1142,8 @@ static void compile_conditional_g(condclass *cc, switch ((cc-condclasses)*2 + 500) { case HAS_CC: + check_warn_symbol_type(&AO1, OBJECT_T, 0, "\"has/hasnt\" expression"); + check_warn_symbol_type(&AO2, ATTRIBUTE_T, 0, "\"has/hasnt\" expression"); if (runtime_error_checking_switch) { if (flag) error_label = next_label++; @@ -1194,6 +1222,8 @@ static void compile_conditional_g(condclass *cc, break; case IN_CC: + check_warn_symbol_type(&AO1, OBJECT_T, 0, "\"in/notin\" expression"); + check_warn_symbol_type(&AO2, OBJECT_T, CLASS_T, "\"in/notin\" expression"); if (runtime_error_checking_switch) { if (flag) error_label = next_label++; @@ -1208,12 +1238,16 @@ static void compile_conditional_g(condclass *cc, break; case OFCLASS_CC: + /* first argument can be anything */ + check_warn_symbol_type(&AO2, CLASS_T, 0, "\"ofclass\" expression"); assembleg_call_2(veneer_routine(OC__Cl_VR), AO1, AO2, stack_pointer); the_zc = (flag ? jnz_gc : jz_gc); AO1 = stack_pointer; break; case PROVIDES_CC: + /* first argument can be anything */ + check_warn_symbol_type(&AO2, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"provides\" expression"); assembleg_call_2(veneer_routine(OP__Pr_VR), AO1, AO2, stack_pointer); the_zc = (flag ? jnz_gc : jz_gc); AO1 = stack_pointer; @@ -1275,6 +1309,12 @@ static void generate_code_from(int n, int void_flag) if ((opnum == LOGAND_OP) || (opnum == LOGOR_OP)) { generate_code_from(below, FALSE); + if (execution_never_reaches_here) { + /* If the condition never falls through to here, then it + was an "... && 0 && ..." test. Our convention is to skip + the "not reached" warnings for this case. */ + execution_never_reaches_here |= EXECSTATE_NOWARN; + } generate_code_from(ET[below].right, FALSE); goto OperatorGenerated; } @@ -1685,6 +1725,8 @@ static void generate_code_from(int n, int void_flag) case PROP_ADD_OP: { assembly_operand AO = ET[below].value; + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".&\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".&\" expression"); if (runtime_error_checking_switch && (!veneer_mode)) AO = check_nonzero_at_runtime(AO, -1, PROP_ADD_RTE); assemblez_2_to(get_prop_addr_zc, AO, @@ -1695,6 +1737,8 @@ static void generate_code_from(int n, int void_flag) case PROP_NUM_OP: { assembly_operand AO = ET[below].value; + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".#\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".#\" expression"); if (runtime_error_checking_switch && (!veneer_mode)) AO = check_nonzero_at_runtime(AO, -1, PROP_NUM_RTE); assemblez_2_to(get_prop_addr_zc, AO, @@ -1707,49 +1751,70 @@ static void generate_code_from(int n, int void_flag) break; case PROPERTY_OP: - { assembly_operand AO = ET[below].value; - + { + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".\" expression"); if (runtime_error_checking_switch && (!veneer_mode)) assemblez_3_to(call_vs_zc, veneer_routine(RT__ChPR_VR), - AO, ET[ET[below].right].value, temp_var1); + ET[below].value, ET[ET[below].right].value, temp_var1); else - assemblez_2_to(get_prop_zc, AO, + assemblez_2_to(get_prop_zc, ET[below].value, ET[ET[below].right].value, temp_var1); if (!void_flag) write_result_z(Result, temp_var1); } break; case MESSAGE_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".\" expression"); j=1; AI.operand[0] = veneer_routine(RV__Pr_VR); goto GenFunctionCallZ; case MPROP_ADD_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".&\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".&\" expression"); j=1; AI.operand[0] = veneer_routine(RA__Pr_VR); goto GenFunctionCallZ; case MPROP_NUM_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".#\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".#\" expression"); j=1; AI.operand[0] = veneer_routine(RL__Pr_VR); goto GenFunctionCallZ; case MESSAGE_SETEQUALS_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".\" expression"); j=1; AI.operand[0] = veneer_routine(WV__Pr_VR); goto GenFunctionCallZ; case MESSAGE_INC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\"++.\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"++.\" expression"); j=1; AI.operand[0] = veneer_routine(IB__Pr_VR); goto GenFunctionCallZ; case MESSAGE_DEC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\"--.\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"--.\" expression"); j=1; AI.operand[0] = veneer_routine(DB__Pr_VR); goto GenFunctionCallZ; case MESSAGE_POST_INC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".++\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".++\" expression"); j=1; AI.operand[0] = veneer_routine(IA__Pr_VR); goto GenFunctionCallZ; case MESSAGE_POST_DEC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".--\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".--\" expression"); j=1; AI.operand[0] = veneer_routine(DA__Pr_VR); goto GenFunctionCallZ; case SUPERCLASS_OP: j=1; AI.operand[0] = veneer_routine(RA__Sc_VR); goto GenFunctionCallZ; case PROP_CALL_OP: + check_warn_symbol_has_metaclass(&ET[below].value, "\".()\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".()\" expression"); j=1; AI.operand[0] = veneer_routine(CA__Pr_VR); goto GenFunctionCallZ; case MESSAGE_CALL_OP: + check_warn_symbol_has_metaclass(&ET[below].value, "\".()\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".()\" expression"); j=1; AI.operand[0] = veneer_routine(CA__Pr_VR); goto GenFunctionCallZ; @@ -1853,6 +1918,7 @@ static void generate_code_from(int n, int void_flag) case INDIRECT_SYSF: j=0; i = ET[below].right; + check_warn_symbol_type(&ET[i].value, ROUTINE_T, 0, "indirect function call"); goto IndirectFunctionCallZ; case CHILDREN_SYSF: @@ -1928,6 +1994,7 @@ static void generate_code_from(int n, int void_flag) } break; } + check_warn_symbol_type(&ET[below].value, ROUTINE_T, 0, "function call"); GenFunctionCallZ: @@ -1985,6 +2052,8 @@ static void generate_code_from(int n, int void_flag) break; case PROPERTY_SETEQUALS_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".\" expression"); if (!void_flag) { if (runtime_error_checking_switch) assemblez_4_to(call_zc, veneer_routine(RT__ChPS_VR), @@ -2128,6 +2197,8 @@ static void generate_code_from(int n, int void_flag) break; case PROPERTY_INC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\"++.\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"++.\" expression"); assemblez_store(temp_var1, ET[below].value); assemblez_store(temp_var2, ET[ET[below].right].value); assemblez_2_to(get_prop_zc, temp_var1, temp_var2, temp_var3); @@ -2140,6 +2211,8 @@ static void generate_code_from(int n, int void_flag) break; case PROPERTY_DEC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\"--.\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"--.\" expression"); assemblez_store(temp_var1, ET[below].value); assemblez_store(temp_var2, ET[ET[below].right].value); assemblez_2_to(get_prop_zc, temp_var1, temp_var2, temp_var3); @@ -2152,6 +2225,8 @@ static void generate_code_from(int n, int void_flag) break; case PROPERTY_POST_INC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".++\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".++\" expression"); assemblez_store(temp_var1, ET[below].value); assemblez_store(temp_var2, ET[ET[below].right].value); assemblez_2_to(get_prop_zc, temp_var1, temp_var2, temp_var3); @@ -2164,6 +2239,8 @@ static void generate_code_from(int n, int void_flag) break; case PROPERTY_POST_DEC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".--\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".--\" expression"); assemblez_store(temp_var1, ET[below].value); assemblez_store(temp_var2, ET[ET[below].right].value); assemblez_2_to(get_prop_zc, temp_var1, temp_var2, temp_var3); @@ -2181,7 +2258,7 @@ static void generate_code_from(int n, int void_flag) compiler_error("Expr code gen: Can't generate yet"); } } - else { + else { /* Glulx */ assembly_operand AO, AO2; if (operators[opnum].opcode_number_g != -1) { @@ -2375,37 +2452,53 @@ static void generate_code_from(int n, int void_flag) case PROPERTY_OP: case MESSAGE_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".\" expression"); AO = veneer_routine(RV__Pr_VR); goto TwoArgFunctionCall; case MPROP_ADD_OP: case PROP_ADD_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".&\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".&\" expression"); AO = veneer_routine(RA__Pr_VR); goto TwoArgFunctionCall; case MPROP_NUM_OP: case PROP_NUM_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".#\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".#\" expression"); AO = veneer_routine(RL__Pr_VR); goto TwoArgFunctionCall; case PROP_CALL_OP: case MESSAGE_CALL_OP: + check_warn_symbol_has_metaclass(&ET[below].value, "\".()\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".()\" expression"); AO2 = veneer_routine(CA__Pr_VR); i = below; goto DoFunctionCall; case MESSAGE_INC_OP: case PROPERTY_INC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\"++.\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"++.\" expression"); AO = veneer_routine(IB__Pr_VR); goto TwoArgFunctionCall; case MESSAGE_DEC_OP: case PROPERTY_DEC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\"--.\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\"--.\" expression"); AO = veneer_routine(DB__Pr_VR); goto TwoArgFunctionCall; case MESSAGE_POST_INC_OP: case PROPERTY_POST_INC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".++\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".++\" expression"); AO = veneer_routine(IA__Pr_VR); goto TwoArgFunctionCall; case MESSAGE_POST_DEC_OP: case PROPERTY_POST_DEC_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".--\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".--\" expression"); AO = veneer_routine(DA__Pr_VR); goto TwoArgFunctionCall; case SUPERCLASS_OP: @@ -2425,6 +2518,8 @@ static void generate_code_from(int n, int void_flag) case PROPERTY_SETEQUALS_OP: case MESSAGE_SETEQUALS_OP: + check_warn_symbol_type(&ET[below].value, OBJECT_T, CLASS_T, "\".\" expression"); + check_warn_symbol_type(&ET[ET[below].right].value, PROPERTY_T, INDIVIDUAL_PROPERTY_T, "\".\" expression"); if (runtime_error_checking_switch && (!veneer_mode)) AO = veneer_routine(RT__ChPS_VR); else @@ -2615,6 +2710,7 @@ static void generate_code_from(int n, int void_flag) case INDIRECT_SYSF: i = ET[below].right; + check_warn_symbol_type(&ET[i].value, ROUTINE_T, 0, "indirect function call"); goto IndirectFunctionCallG; case GLK_SYSF: @@ -2684,6 +2780,7 @@ static void generate_code_from(int n, int void_flag) break; } + check_warn_symbol_type(&ET[below].value, ROUTINE_T, 0, "function call"); i = below; IndirectFunctionCallG: @@ -2776,6 +2873,7 @@ static void generate_code_from(int n, int void_flag) if (ET[n].to_expression) { + int32 donelabel; if (void_flag) { warning("Logical expression has no side-effects"); if (ET[n].true_label != -1) @@ -2784,18 +2882,26 @@ static void generate_code_from(int n, int void_flag) assemble_label_no(ET[n].false_label); } else if (ET[n].true_label != -1) - { assemblez_1(push_zc, zero_operand); - assemblez_jump(next_label++); + { + donelabel = next_label++; + if (!execution_never_reaches_here) { + assemblez_1(push_zc, zero_operand); + assemblez_jump(donelabel); + } assemble_label_no(ET[n].true_label); assemblez_1(push_zc, one_operand); - assemble_label_no(next_label-1); + assemble_forward_label_no(donelabel); } else - { assemblez_1(push_zc, one_operand); - assemblez_jump(next_label++); + { + donelabel = next_label++; + if (!execution_never_reaches_here) { + assemblez_1(push_zc, one_operand); + assemblez_jump(donelabel); + } assemble_label_no(ET[n].false_label); assemblez_1(push_zc, zero_operand); - assemble_label_no(next_label-1); + assemble_forward_label_no(donelabel); } ET[n].value = stack_pointer; } @@ -2808,6 +2914,7 @@ static void generate_code_from(int n, int void_flag) if (ET[n].to_expression) { + int32 donelabel; if (void_flag) { warning("Logical expression has no side-effects"); if (ET[n].true_label != -1) @@ -2816,18 +2923,26 @@ static void generate_code_from(int n, int void_flag) assemble_label_no(ET[n].false_label); } else if (ET[n].true_label != -1) - { assembleg_store(stack_pointer, zero_operand); - assembleg_jump(next_label++); + { + donelabel = next_label++; + if (!execution_never_reaches_here) { + assembleg_store(stack_pointer, zero_operand); + assembleg_jump(donelabel); + } assemble_label_no(ET[n].true_label); assembleg_store(stack_pointer, one_operand); - assemble_label_no(next_label-1); + assemble_forward_label_no(donelabel); } else - { assembleg_store(stack_pointer, one_operand); - assembleg_jump(next_label++); + { + donelabel = next_label++; + if (!execution_never_reaches_here) { + assembleg_store(stack_pointer, one_operand); + assembleg_jump(donelabel); + } assemble_label_no(ET[n].false_label); assembleg_store(stack_pointer, zero_operand); - assemble_label_no(next_label-1); + assemble_forward_label_no(donelabel); } ET[n].value = stack_pointer; }