Skip to content

Missing breaks #3290

@BsAtHome

Description

@BsAtHome

There are two unresolved switch case fall-through warnings that need review.

Problem case 1:

The code in emc/rs274ngc/interp_o_word.cc seems to be executed as a result of a python callable O-word, where the return value is integer. When the return value is double (RET_DOUBLE), then the case is concluded with a break. However, when the return value is integer (RET_INT), then the case falls through to the default case. Code in question (lines 621-659):

int Interp::handler_returned( setup_pointer settings,  context_pointer active_frame, const char *name, bool osub) {
...
    switch (active_frame->pystuff.impl->py_return_type) {
...
    case RET_DOUBLE: 
	if (osub) { // float values are ok for osubs
	    settings->return_value = active_frame->pystuff.impl->py_returned_double;
	    settings->value_returned = 1;
	} else {
	    ERS("handler_returned: %s returned double: %f - invalid", 
			name, active_frame->pystuff.impl->py_returned_double);
	}
	break;

    case RET_INT: 
	if (osub) { // let's be liberal with types - widen to double return value
	    settings->return_value = (double) active_frame->pystuff.impl->py_returned_int;
	    settings->value_returned = 1;
	} else 
	    return active_frame->pystuff.impl->py_returned_int;

    case RET_ERRORMSG:
...

Not only is the break missing, but the else-clause within the RET_INT case is different from the RET_DOUBLE case. The double case calls (expands macro) ERS(), which stacks an error message and returns an INTERP_ERROR. The RET_INT case does not do the same thing.

I think the resolution should be to align the RET_INT case with the RET_DOUBLE case and change the RET_INT case to have both a break at the end and call ERS() in the else-clause.

Problem case 2:

Another part of the code in emc/rs274ngc/interp_o_word.cc handles O-word returns. There is a case in a sub-switch that handles INTERP_EXECUTE_FINISH, which falls through to the default case. Code in question (lines 392-514):

int Interp::execute_return(setup_pointer settings, context_pointer current_frame,int call_type) {
...
    switch (call_type) {

    case CT_REMAP:
	switch (settings->call_state) {
	case CS_NORMAL:
   	case CS_REEXEC_EPILOG:
...
		switch (status = handler_returned(settings, current_frame, current_frame->subName, false)) {
		case INTERP_EXECUTE_FINISH:
		    settings->call_state = CS_REEXEC_EPILOG;
		    eblock->call_type = CT_REMAP;
		    CHP(status);
		default:
		    settings->call_state = CS_NORMAL;
		    settings->sequence_number = previous_frame->sequence_number;
		    CHP(status);
		    // leave_context() is done by falling through into CT_NGC_OWORD_SUB code
		}
	    }
	}
	// fall through to normal NGC return handling 
...

Falling through from INTERP_EXECUTE_FINISH causes settings->calls_state to be overwritten, which seems the wrong thing to do.

I think there should be a break at the end of the INTERP_EXECUTE_FINISH case (after the CHP(status) macro).

Please advise on these two problem cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions