smatch misidentifies uninitialized variable after switch with no default:
I've got a simple reproducer for the issue that I found when scanning our ice driver in the kernel with smatch.
original repro against smatch HEAD 0951ed5915c0 ("db: fix uninitialized variable false positives") smatch reported: ~/git/smatch/smatch_scripts/kchecker drivers/net/ethernet/intel/ice/ice_ptp_hw.c drivers/net/ethernet/intel/ice/ice_ptp_hw.c:2852 ice_ptp_port_cmd_e810() error: uninitialized symbol 'cmd_val'.
Below is a simple c-code reproducer, compile with:
gcc -o srt -Wextra -Wall smatch_switch_repro.c
see error with
~/git/smatch/smatch smatch_switch_repro.c
smatch_switch_repro.c:43 badfunc() error: uninitialized symbol 'my_int'.
One bit of data that might be useful: it works fine with badfunc content inline in main() and fails when badfunc is a function with the enum argument. It also succeeds when there is a "default:" label and a simple assignment in that case (see the reproducer below and bit of commented out code)
// SPDX-License-Identifier: BSD-3-Clause
/*
* Copyright 2021, Intel Corporation
*
* A quick demo of a smatch false positive
*/
#include <stdio.h>
enum three_values
{
value_one,
value_two,
value_three
};
void badfunc(const enum three_values cmd)
{
unsigned int my_int, new_int; //uninitialized
switch (cmd) {
case value_one:
printf("one\n");
my_int = 1;
break;
case value_two:
printf("two\n");
my_int = 2;
break;
case value_three:
printf("three\n");
my_int = 3;
break;
/* no default because all enum values handled, which has value
* to developers because it forces compile error if not all enum values
* handled and enum is changed */
//default:
//my_int = 4;
//break;
}
new_int = 0;
new_int |= my_int;
printf("data: %d\n", new_int);
}
int main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
enum three_values my_enum = value_two;
badfunc(my_enum);
return 0;
}
@error27 - this one worked out pretty well, I hope this simple reproducer helps you figure out a fix.