Both signed and unsigned integer operations are required to either wrap or give 
undefined results in C.  To my mind this is a horrible problem which gets 
kicked down the road by the expansion of the size of variable size every few 
years, presumably accompanies by the sacrificing of farmyard animals to some 
deity or other..  But I'm pleased(!) to see it's now being exploited as an 
attack vector and there's a proposal in C23 to formalise a checked integer 
macro (though just for addition, subtraction, and multiplication, apparently on 
the basis that Java omits checking for division so the C standards people won't 
do it either?).
The implementation I've seen so far actually depends on the implementation 
behaving in a sensible fashion and wrapping/truncating rather giving a totally 
unpredictable result, so we'll have to see what happens with the vote on this.
This is actually what's driving this exploration.  I can, I think, better 
implement checked arithmetic in 32 and 64 bit modes using functions akin to the 
proposed C23 standard, but using the hardware to do the checking, eg:   

bool ckd_add_u32(__uint32_t *result, __uint32_t u32a, __uint32_t u32b, bool 
abort) {
    __uint32_t ccpm;

    const __uint32_t carrybit = 0x20000000;

    __uint32_t sum = u32a;

    asm("alr %[r1],%[r2] \n\t"
        "ipm %[r3]"
        : [r1] "+r" (sum),    // output
          [r3] "=r" (ccpm)
        : [r2] "r"  (u32b)    // input
        :                    // clobbers
       );

    bool overflow = (ccpm & carrybit) != 0;    // check if carry bit set

    char msgbuf[100];
    sprintf( msgbuf, "a: %11u, b: %11u, sum: %11u ccpm: 0x%08x, overflow: %s",
            u32a, u32b, sum, ccpm, overflow ? "true" : "false" );
    wtopc_text( msgbuf );

    if (abort && overflow) {
        serrc_op( (enum t_serrc)(SERRC_EXIT), 0xDEAD00, "INTEGER OVERFLOW 
OCCURRED", NULL );
    }

    *result = sum;

    return overflow;
}
which I think is relatively efficient, at least if inlined.

16, and 8, bit operations are, I think, a bit more tricky to do like this and 
might have to use post-operation checks.  I need to have a think about that.


Best wishes / Mejores deseos /  Meilleurs vœux

Ian ... 

    On Thursday, April 14, 2022, 06:25:11 PM GMT+2, Paul Gilmartin 
<00000014e0e4a59b-dmarc-requ...@listserv.uga.edu> wrote:  
 
 On Apr 14, 2022, at 09:21:28, Robin Vowels wrote:
> 
> On 2022-04-15 00:31, Seymour J Metz wrote:
>> The S/360 architecture uses two's complement arithmetic, and that
>> remains the case through z. Accordingly, signed and unsigned
>> arithmetic are the same except for the condition code, except when
>> sign extension is an issue, e.g., adding a word to a grande register..
> 
> If the relevant overflow mask bit is set,
> integer overflow causes an interrupt.
>  
A couple C implementations (other than XL C/C++ which I haven't
checked) require integer overflow interrupts disabled at runtime.

ANSI C requires unsigned operations to be performed with modulo
arithmetic.  For integer overflow either (I don't recall which)
the behavior is unpredictable, allowing an interrupt, or the
value or the result is unpredictable, not allowing interrupt.

Pre-ANSI  C specified unsigned-preserving, so:
    -1 > (unsigned) 0. /* Ugh!  */

ANSI  C specified value-preserving, so:
    -1 < (unsigned) 0

-- 
gil
  

Reply via email to