Posted to tcl by apn at Mon Oct 17 13:38:55 GMT 2022view pretty

I'm trying to nail down a Tk bug that @fvogel and I think is a compiler bug.
The C fragment in (HandleGenerateEvent) code looks like:
 
   	if (badOpt) {
	    /* >>> This always executed irrespective of value of badOpt */
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s event doesn't accept \"%s\" option", name, Tcl_GetString(optionPtr)));
	    Tcl_SetErrorCode(interp, "TK", "EVENT", "BAD_OPTION", NULL);
	    return TCL_ERROR;
	}

The generated assembler is 

; 3971 :     	if (badOpt) {

	mov	eax, edi
	sete	al
	test	eax, eax
	je	SHORT $LN48@HandleEven
$LN43@HandleEven:
        (error handling code. Tcl_SetObjResult/SetErrorCode)

This looks broken to me. edi contains badOpt indicating the passed option is invalid. It doesn't make sense that it is copied into eax which is immediately overwritten by the sete instruction before the test. So instead of testing badOpt (di), the code tests the value of the ZF flag at the time the code is entered (which is copied into al). The value of badOpt/di is never checked.

Comments

Posted by chw at Mon Oct 17 14:03:19 GMT 2022 [text] [code]

MOV EAX,EDI does not affect the condition codes. SETE thus depends on what the zero flag had before the MOV. TEST would set the zero flag when the SETE had made the entire EAX all zeroes. Conclusion: your analysis is correct. The compiler produced nonsense.