Skip to content

Instantly share code, notes, and snippets.

@mmastrac
Created December 20, 2022 15:04
Show Gist options
  • Save mmastrac/4c00b7790c8a13e13d1baca08b1b9cd6 to your computer and use it in GitHub Desktop.
Save mmastrac/4c00b7790c8a13e13d1baca08b1b9cd6 to your computer and use it in GitHub Desktop.
Signed integer addition overflow check
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
bool checked_add_intrinsic(int32_t a, int32_t b) {
int res;
// return __builtin_add_overflow(a, b, &res);
return 1;
}
bool checked_add_64(int32_t a, int32_t b) {
int64_t result = (int64_t)a + b;
if (result < INT32_MIN || result > INT32_MAX) {
return true;
}
return false;
}
/* Type your code here, or load an example. */
bool __attribute__ ((noinline)) checked_add(int32_t a_, int32_t b_) {
uint32_t a = *(uint32_t*)&a_;
uint32_t b = *(uint32_t*)&b_;
uint32_t c = ((uint64_t)(a) + (uint64_t)(b)) & 0xffffffff;
// a 0 b 0 c 1
// a 1 b 1 c 0
return ((c ^ a) & (c ^ b)) >> 31;
}
/* Type your code here, or load an example. */
bool __attribute__ ((noinline)) checked_addx(int32_t a, int32_t b) {
uint32_t c = (uint32_t)a + (uint32_t)b;
#define SIGN1(x) ((x & 0x80000000))
#define SIGN2(x) ((x & 0x80000000))
return SIGN2((a & b & ~c)
| (~a & ~b & c)) != 0;
}
int32_t __attribute__ ((noinline)) add(int32_t a, int32_t b) {
return a + b;
}
int main(void) {
int32_t test_cases[] = {
0,
+1,
-1,
INT32_MAX,
INT32_MAX - 1,
INT32_MIN,
INT32_MIN + 1,
};
// printf("%d\n", add(0x7fffffff, 1));
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
int32_t a = test_cases[i];
int32_t b = test_cases[j];
if (checked_add_64(a, b) != checked_add(a, b)) {
printf("Fail 1: %d %d\n", a, b);
}
if (checked_add_intrinsic(a, b) != checked_add(a, b)) {
printf("Fail 2: %d %d\n", a, b);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment