diff options
author | drh <drh@noemail.net> | 2017-01-03 21:57:11 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2017-01-03 21:57:11 +0000 |
commit | a3a40211bd9067ea6b1faf9166c45a864c08080b (patch) | |
tree | aaf8145e96ab44d79ef5caed03e4da195411d678 /src | |
parent | 5c41d00f42c577f54eb78bab974345cc8d92aeac (diff) | |
parent | 7433ae5df65c2d1d3fded425c431150b91674144 (diff) | |
download | sqlite-a3a40211bd9067ea6b1faf9166c45a864c08080b.tar.gz sqlite-a3a40211bd9067ea6b1faf9166c45a864c08080b.zip |
Use compiler intrinsic functions for signed integer math when overflow
detection is needed.
FossilOrigin-Name: d3ac32a6e7f1823450feb3d1089802542090d164
Diffstat (limited to 'src')
-rw-r--r-- | src/sqliteInt.h | 8 | ||||
-rw-r--r-- | src/util.c | 19 |
2 files changed, 25 insertions, 2 deletions
diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 31cedf40e..0257e721b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -110,6 +110,14 @@ # define GCC_VERSION 0 #endif +/* What version of CLANG is being used. 0 means CLANG is not being used */ +#ifdef __clang__ +# define CLANG_VERSION \ + (__clang_major__*1000000+__clang_minor__*1000+__clang_patchlevel__) +#else +# define CLANG_VERSION 0 +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE diff --git a/src/util.c b/src/util.c index b9684c6c0..ca14ab852 100644 --- a/src/util.c +++ b/src/util.c @@ -1141,7 +1141,7 @@ u32 sqlite3Get4byte(const u8 *p){ memcpy(&x,p,4); return x; #elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4003000 + && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u32 x; memcpy(&x,p,4); return __builtin_bswap32(x); @@ -1159,7 +1159,7 @@ void sqlite3Put4byte(unsigned char *p, u32 v){ #if SQLITE_BYTEORDER==4321 memcpy(p,&v,4); #elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ - && defined(__GNUC__) && GCC_VERSION>=4003000 + && (GCC_VERSION>=4003000 || CLANG_VERSION>=3000000) u32 x = __builtin_bswap32(v); memcpy(p,&x,4); #elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \ @@ -1279,6 +1279,10 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** overflow, leave *pA unchanged and return 1. */ int sqlite3AddInt64(i64 *pA, i64 iB){ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) + return __builtin_add_overflow(*pA, iB, pA); +#else i64 iA = *pA; testcase( iA==0 ); testcase( iA==1 ); testcase( iB==-1 ); testcase( iB==0 ); @@ -1293,8 +1297,13 @@ int sqlite3AddInt64(i64 *pA, i64 iB){ } *pA += iB; return 0; +#endif } int sqlite3SubInt64(i64 *pA, i64 iB){ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) + return __builtin_sub_overflow(*pA, iB, pA); +#else testcase( iB==SMALLEST_INT64+1 ); if( iB==SMALLEST_INT64 ){ testcase( (*pA)==(-1) ); testcase( (*pA)==0 ); @@ -1304,8 +1313,13 @@ int sqlite3SubInt64(i64 *pA, i64 iB){ }else{ return sqlite3AddInt64(pA, -iB); } +#endif } int sqlite3MulInt64(i64 *pA, i64 iB){ +#if !defined(SQLITE_DISABLE_INTRINSIC) \ + && (GCC_VERSION>=5004000 || CLANG_VERSION>=4000000) + return __builtin_mul_overflow(*pA, iB, pA); +#else i64 iA = *pA; if( iB>0 ){ if( iA>LARGEST_INT64/iB ) return 1; @@ -1321,6 +1335,7 @@ int sqlite3MulInt64(i64 *pA, i64 iB){ } *pA = iA*iB; return 0; +#endif } /* |