pharo-project / pharo-vm

This is the VM used by Pharo
http://pharo.org
Other
110 stars 67 forks source link

Compiler warning: Wsometimes-uninitialized #794

Open jordanmontt opened 2 months ago

jordanmontt commented 2 months ago

If one compiles the vm with the warning Wsometimes-uninitialized, we have one case of a sometimes uninitialized variable. This happens in the method StackToRegisterMappingCogit>>#genSpecialSelectorArithmetic in the line 20, for the result temp variable:

genSpecialSelectorArithmetic
"More code ......." 

         primDescriptor opcode caseOf: {
            [AddRR] -> [result := rcvrInt + argInt].
            [SubRR] -> [result := rcvrInt - argInt].
            [AndRR] -> [result := rcvrInt bitAnd: argInt].
            [OrRR]  -> [result := rcvrInt bitOr: argInt] }.
        (objectMemory isIntegerValue: result) ifTrue:
            ["Must annotate the bytecode for correct pc mapping."
            ^self ssPop: 2; ssPushAnnotatedConstant: (objectMemory integerObjectOf: result)].

" More code ...."

Indeed, the variable result, if non of the cases of the caseOf: is met, then is left uninitialized. But, if we look at the implementation of Object>>#caseOf:, when non of the cases is satisfied, an error is raised. So actually the variable is NEVER uninitialized, because when that happens we have an error.

This is translated into C as the following:

switch ((primDescriptor->opcode)) {
            case AddRR:
            {
                result = rcvrInt + argInt;
            }
            break;
            case SubRR:
            {
                result = rcvrInt - argInt;
            }
            break;
            case AndRR:
            {
                result = rcvrInt & argInt;
            }
            break;
            case OrRR:
            {
                result = rcvrInt | argInt;
            }
            break;
            default:
            error("Case not found and no otherwise clause");

        }

As one can see, indeed if non of the cases is satisfied, the function error is called. But, the C compiler does not know that and it produced the warning.

Possible solutions We could refactor the method to always initialize the variable, but I don't know if that is a good idea since is good to have an error.

We could annotate the C code to say to the compiler to not produce the warning ONLY for that variable in that method.