Re: [cc65] Compiler code generation bug?

From: David Littell <littelld1verizon.net>
Date: 2013-03-09 23:45:24
On Mar 8, 2013, at 6:45 AM, Oliver Schmidt wrote:

> Hi Dave,
> 
> Insights welcomed!
> 
> Maybe I'm misunderstadning something and my comment isn't relevant but it seems to me that you might not take 'integer promotions' into account:
> 

Thank you very much for the reply.  This is indeed what's happened.  It's always "interesting" and "fun" when a language picks and chooses when to butt in and "do the right thing and protect me from myself" instead of assuming I really do know what I want...  ;-)

> "Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int. Integer promotions are applied as part of the usual arithmetic conversions to certain argument expressions; operands of the unary +, -, and ~ operators; and operands of the shift operators."
> 
> From: https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules
> 

Well, that exactly what's going on.  There's even an example of how the absolute wrong thing is done in the case of the bitwise complement.  It obviously should complement the base type first and then promote instead of doing the promotion first.  But, broken is as broken does...

Their example shows how a cast corrects the problem created by the their ill-timed promotion.  That's pretty funny because these same geniuses warn that weirdo casts are a sure sign of a typing problem...

However, when I add a cast to the original offending if():

; 
; if( Byte != ((uint8_t) ~Marker[ i ]) )
;
L000E:  ldy     #$02
        lda     (sp),y
        jsr     pusha0
        lda     #<(_Marker)
        ldy     #$02
        clc
        adc     (sp),y
        sta     ptr1
        lda     #>(_Marker)
        iny
        adc     (sp),y
        sta     ptr1+1
        lda     (ptr1,x)
        jsr     complax
        jsr     tosicmp
        beq     L0012
;
; bad();
;
        jsr     _bad

...I still get the call to the integer-sized tosicmp instead of tosicmp0.  Is there more over-eager integer promotion here too?  ;-)

Only when I add something hideous to do what the cast should have done do I finally get the correct tosicmp0:

;                                                                                                                        
; if( Byte != (~Marker[ i ] & ((0x1 << (sizeof( Marker[ i ] ) * 8)) - 1)) )                                              
;                                                                                                                        
L0012:  ldy     #$02                                                                                                     
        lda     (sp),y                                                                                                   
        jsr     pusha0                                                                                                   
        lda     #<(_Marker)                                                                                              
        ldy     #$02                                                                                                     
        clc                                                                                                              
        adc     (sp),y                                                                                                   
        sta     ptr1                                                                                                     
        lda     #>(_Marker)                                                                                              
        iny                                                                                                              
        adc     (sp),y                                                                                                   
        sta     ptr1+1                                                                                                   
        lda     (ptr1,x)                                                                                                 
        jsr     complax                                                                                                  
        jsr     tosicmp0                                                                                                 
        beq     L0017                                                                                                    
;                                                                                                                        
; bad();                                                                                                                 
;                                                                                                                        
        jsr     _bad


There was a time when I loved C because it could be trusted to not get in the way very much at all.  Those days are gone, I guess.  Now I get to write a new macro: "FixStupidIntPromotion()".  Whee!


Thanks,
Dave


----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Sat Mar 9 23:45:53 2013

This archive was generated by hypermail 2.1.8 : 2013-03-09 23:45:57 CET