aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2017-01-03 21:57:11 +0000
committerdrh <drh@noemail.net>2017-01-03 21:57:11 +0000
commita3a40211bd9067ea6b1faf9166c45a864c08080b (patch)
treeaaf8145e96ab44d79ef5caed03e4da195411d678 /src
parent5c41d00f42c577f54eb78bab974345cc8d92aeac (diff)
parent7433ae5df65c2d1d3fded425c431150b91674144 (diff)
downloadsqlite-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.h8
-rw-r--r--src/util.c19
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
}
/*