From 4a240516eb1b3dda7b9659672a3b11e7335f7b74 Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Mon, 7 Sep 2026 05:09:27 +0100 Subject: [PATCH] Fixed signedness warnings for function returns and structure members --- amd64.c | 60 +++++++++++++++++++++++++++++++++++++----------- i386.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 108 insertions(+), 23 deletions(-) diff --git a/amd64.c b/amd64.c index 2aca9a9..332ff49 100644 --- a/amd64.c +++ b/amd64.c @@ -8154,7 +8154,7 @@ static int current_expression_mentions_64bit_symbol_now (void); static int rhs_current_operand_is_unsigned_now (void); static int rhs_current_operand_signedness_for_warning_now (void); -static void warn_signedness_comparison_now (int left_signedness); +static void warn_signedness_comparison_values_now (int left_signedness, int right_signedness, const char *report_start, const char *report_caret); static int64_s parse_floating_const_expr_bits_now (int size); @@ -27746,9 +27746,14 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { int lhs_pointer_depth; int lhs_signedness; + int rhs_signedness; int rhs_is_enum; + int is_unsigned; + const char *rhs_report_start; + const char *rhs_report_caret; + lhs_signedness = rhs_current_operand_signedness_for_warning_now (); is_unsigned = emit_load_assignment_binary_expression_prec_to_reg (reg, 1); @@ -27756,6 +27761,8 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { if (lhs_pointer_depth > 0) { lhs_signedness = -1; + } else if (postfix_member_seen) { + lhs_signedness = postfix_member_is_unsigned ? 1 : 0; } else if (lhs_signedness < 0) { lhs_signedness = is_unsigned ? 1 : 0; } @@ -27769,7 +27776,11 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { op = tok.kind; get_token (); - warn_signedness_comparison_now (lhs_signedness); + rhs_signedness = rhs_current_operand_signedness_for_warning_now (); + + rhs_report_start = tok.report_start; + rhs_report_caret = tok.report_caret; + rhs_is_enum = 0; if (tok.kind == TOK_IDENT && tok.ident && !find_local_symbol (tok.ident) && find_global_symbol (tok.ident) < 0 && resolve_enum_constant (tok.ident, &rhs_enum_value)) { @@ -27808,6 +27819,7 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { */ if (rhs_is_enum) { + warn_signedness_comparison_values_now (lhs_signedness, rhs_signedness, rhs_report_start, rhs_report_caret); emit_statement_const32_to_rdx (rhs_enum_value); if (lhs_pointer_depth > 0) { @@ -27826,9 +27838,19 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { } if (!emit_statement_rhs_const32_to_rdx_if_possible ()) { + emit_load_assignment_binary_expression_to_reg ("rdx"); + + if (rhs_last_pointer_depth > 0) { + rhs_signedness = -1; + } else if (postfix_member_seen) { + rhs_signedness = postfix_member_is_unsigned ? 1 : 0; + } + } + warn_signedness_comparison_values_now (lhs_signedness, rhs_signedness, rhs_report_start, rhs_report_caret); + if (lhs_pointer_depth > 0 || rhs_last_pointer_depth > 0) { is_unsigned = 1; } @@ -33912,31 +33934,28 @@ static int rhs_current_operand_signedness_for_warning_now (void) { } -static void warn_signedness_comparison_now (int left_signedness) { - - int right_signedness; +static void warn_signedness_comparison_values_now (int left_signedness, int right_signedness, const char *report_start, const char *report_caret) { if (!(state->warn & WARN_SIGNEDNESS)) { return; } - - right_signedness = rhs_current_operand_signedness_for_warning_now (); - + if (left_signedness < 0 || right_signedness < 0) { return; } - + /* Code 2 is a non-negative signed integer constant. The usual arithmetic * conversions can represent it in the unsigned type without changing its * value, matching the useful -Wsign-compare behaviour. */ if (left_signedness == 2 || right_signedness == 2) { return; } - + if (left_signedness != right_signedness) { + report_line_at (get_filename (), get_line_number (), REPORT_WARNING, - tok.report_start, tok.report_caret, - "comparison of integer expressions of different signedness"); + report_start, report_caret, "comparison of integer expressions of different signedness"); + } } @@ -34545,8 +34564,13 @@ static int emit_statement_ident_immediate_compare_jump_if_false_now (int label) enum token_kind op; int lhs_signedness; + int rhs_signedness; + int is_unsigned; + const char *rhs_report_start; + const char *rhs_report_caret; + if (!source_condition_ident_immediate_compare_now (tok.caret) && !source_condition_ident_immediate_compare_now (tok.start)) { return 0; @@ -34575,7 +34599,9 @@ static int emit_statement_ident_immediate_compare_jump_if_false_now (int label) op = tok.kind; get_token (); - warn_signedness_comparison_now (lhs_signedness); + rhs_signedness = rhs_current_operand_signedness_for_warning_now (); + rhs_report_start = tok.report_start; + rhs_report_caret = tok.report_caret; if (rhs_current_operand_is_unsigned_now ()) { is_unsigned = 1; @@ -34589,6 +34615,14 @@ static int emit_statement_ident_immediate_compare_jump_if_false_now (int label) } + if (rhs_last_pointer_depth > 0) { + rhs_signedness = -1; + } else if (postfix_member_seen) { + rhs_signedness = postfix_member_is_unsigned ? 1 : 0; + } + + warn_signedness_comparison_values_now (lhs_signedness, rhs_signedness, rhs_report_start, rhs_report_caret); + emit_statement_cmp_rax_rdx_jump_if_false_and_tail (op, is_unsigned, label); return 1; diff --git a/i386.c b/i386.c index 646ee10..dda6887 100644 --- a/i386.c +++ b/i386.c @@ -7359,6 +7359,8 @@ static int current_expression_mentions_64bit_symbol_now (void); static int rhs_current_operand_is_unsigned_now (void); static int rhs_current_operand_signedness_for_warning_now (void); + +static void warn_signedness_comparison_values_now (int left_signedness, int right_signedness, const char *report_start, const char *report_caret); static void warn_signedness_comparison_now (int left_signedness); static int64_s parse_floating_const_expr_bits_now (int size); @@ -24060,6 +24062,12 @@ static void emit_call_identifier_to_reg_now (const char *name, const char *reg, set_rhs_last_pointer_info (get_global_symbol_pointer_depth (name), get_global_symbol_pointed_size (name)); + if (get_global_symbol_pointer_depth (name) == 0) { + rhs_last_scalar_is_unsigned = get_global_symbol_unsigned (name) ? 1 : 0; + } else { + rhs_last_scalar_is_unsigned = -1; + } + pending_struct_return_lhs = 0; pending_struct_return_global_name = 0; pending_struct_return_stack_address = 0; @@ -24972,9 +24980,14 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { int lhs_pointer_depth; int lhs_signedness; + int rhs_signedness; int rhs_is_enum; + int is_unsigned; + const char *rhs_report_start; + const char *rhs_report_caret; + lhs_signedness = rhs_current_operand_signedness_for_warning_now (); is_unsigned = emit_load_assignment_binary_expression_prec_to_reg (reg, 1); @@ -24982,6 +24995,8 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { if (lhs_pointer_depth > 0) { lhs_signedness = -1; + } else if (postfix_member_seen) { + lhs_signedness = postfix_member_is_unsigned ? 1 : 0; } else if (lhs_signedness < 0) { lhs_signedness = is_unsigned ? 1 : 0; } @@ -24995,7 +25010,11 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { op = tok.kind; get_token (); - warn_signedness_comparison_now (lhs_signedness); + rhs_signedness = rhs_current_operand_signedness_for_warning_now (); + + rhs_report_start = tok.report_start; + rhs_report_caret = tok.report_caret; + rhs_is_enum = 0; if (tok.kind == TOK_IDENT && tok.ident && !find_local_symbol (tok.ident) && find_global_symbol (tok.ident) < 0 && resolve_enum_constant (tok.ident, &rhs_enum_value)) { @@ -25034,6 +25053,7 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { */ if (rhs_is_enum) { + warn_signedness_comparison_values_now (lhs_signedness, rhs_signedness, rhs_report_start, rhs_report_caret); emit_statement_const32_to_edx (rhs_enum_value); if (lhs_pointer_depth > 0) { @@ -25052,9 +25072,19 @@ static void emit_load_assignment_compare_expression_to_reg (const char *reg) { } if (!emit_statement_rhs_const32_to_edx_if_possible ()) { + emit_load_assignment_binary_expression_to_reg ("edx"); + + if (rhs_last_pointer_depth > 0) { + rhs_signedness = -1; + } else if (postfix_member_seen) { + rhs_signedness = postfix_member_is_unsigned ? 1 : 0; + } + } + warn_signedness_comparison_values_now (lhs_signedness, rhs_signedness, rhs_report_start, rhs_report_caret); + if (lhs_pointer_depth > 0 || rhs_last_pointer_depth > 0) { is_unsigned = 1; } @@ -31301,23 +31331,21 @@ static int rhs_current_operand_signedness_for_warning_now (void) { } -static void warn_signedness_comparison_now (int left_signedness) { +static void warn_signedness_comparison_values_now (int left_signedness, int right_signedness, const char *report_start, const char *report_caret) { - int right_signedness; - if (!(state->warn & WARN_SIGNEDNESS)) { return; } - right_signedness = rhs_current_operand_signedness_for_warning_now (); - if (left_signedness < 0 || right_signedness < 0) { return; } - /* Code 2 is a non-negative signed integer constant. The usual arithmetic + /** + * Code 2 is a non-negative signed integer constant. The usual arithmetic * conversions can represent it in the unsigned type without changing its - * value, matching the useful -Wsign-compare behaviour. */ + * value, matching the useful -Wsign-compare behaviour. + */ if (left_signedness == 2 || right_signedness == 2) { return; } @@ -31325,12 +31353,20 @@ static void warn_signedness_comparison_now (int left_signedness) { if (left_signedness != right_signedness) { report_line_at (get_filename (), get_line_number (), REPORT_WARNING, - tok.report_start, tok.report_caret, "comparison of integer expressions of different signedness"); + report_start, report_caret, "comparison of integer expressions of different signedness"); } } +static void warn_signedness_comparison_now (int left_signedness) { + + warn_signedness_comparison_values_now (left_signedness, + rhs_current_operand_signedness_for_warning_now (), + tok.report_start, tok.report_caret); + +} + static int rhs_current_operand_is_unsigned_now (void) { if (token_is_sizeof_keyword ()) { @@ -31935,8 +31971,13 @@ static int emit_statement_ident_immediate_compare_jump_if_false_now (int label) enum token_kind op; int lhs_signedness; + int rhs_signedness; + int is_unsigned; + const char *rhs_report_start; + const char *rhs_report_caret; + if (!source_condition_ident_immediate_compare_now (tok.caret) && !source_condition_ident_immediate_compare_now (tok.start)) { return 0; @@ -32015,7 +32056,9 @@ static int emit_statement_ident_immediate_compare_jump_if_false_now (int label) op = tok.kind; get_token (); - warn_signedness_comparison_now (lhs_signedness); + rhs_signedness = rhs_current_operand_signedness_for_warning_now (); + rhs_report_start = tok.report_start; + rhs_report_caret = tok.report_caret; if (rhs_current_operand_is_unsigned_now ()) { is_unsigned = 1; @@ -32029,6 +32072,14 @@ static int emit_statement_ident_immediate_compare_jump_if_false_now (int label) } + if (rhs_last_pointer_depth > 0) { + rhs_signedness = -1; + } else if (postfix_member_seen) { + rhs_signedness = postfix_member_is_unsigned ? 1 : 0; + } + + warn_signedness_comparison_values_now (lhs_signedness, rhs_signedness, rhs_report_start, rhs_report_caret); + emit_statement_cmp_eax_edx_jump_if_false_and_tail (op, is_unsigned, label); return 1; -- 2.34.1