Index: ext/fts3/fts3.c ================================================================== --- ext/fts3/fts3.c +++ ext/fts3/fts3.c @@ -4335,13 +4335,14 @@ aPoslist = pExpr->pRight->pPhrase->doclist.pList; nToken = pExpr->pRight->pPhrase->nToken; for(p=pExpr->pLeft; p && res; p=p->pLeft){ int nNear; + Fts3Phrase *pPhrase; assert( p->pParent && p->pParent->pLeft==p ); nNear = p->pParent->nNear; - Fts3Phrase *pPhrase = ( + pPhrase = ( p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase ); res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase); } } Index: ext/rtree/rtree.c ================================================================== --- ext/rtree/rtree.c +++ ext/rtree/rtree.c @@ -1570,10 +1570,11 @@ float fMinGrowth = 0.0; float fMinArea = 0.0; #if VARIANT_RSTARTREE_CHOOSESUBTREE float fMinOverlap = 0.0; + float overlap; #endif int nCell = NCELL(pNode); RtreeCell cell; RtreeNode *pChild; @@ -1602,18 +1603,19 @@ */ for(iCell=0; iCelliDepth-1) ){ overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell); + }else{ + overlap = 0.0; } if( (iCell==0) || (overlappSrcDb->mutex); sqlite3BtreeEnter(p->pSrc); - mutex = p->pSrcDb->mutex; + MUTEX_LOGIC( mutex = p->pSrcDb->mutex; ) if( p->pDestDb ){ sqlite3_mutex_enter(p->pDestDb->mutex); } /* Detach this backup from the source pager. */ Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -1764,21 +1764,23 @@ */ if( isMemdb==0 && isTempDb==0 ){ if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ int nFullPathname = pVfs->mxPathname+1; char *zFullPathname = sqlite3Malloc(nFullPathname); - sqlite3_mutex *mutexShared; + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) p->sharable = 1; if( !zFullPathname ){ sqlite3_free(p); return SQLITE_NOMEM; } sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); +#if SQLITE_THREADSAFE mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); sqlite3_mutex_enter(mutexOpen); mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(mutexShared); +#endif for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ assert( pBt->nRef>0 ); if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) && sqlite3PagerVfs(pBt->pPager)==pVfs ){ int iDb; @@ -1880,13 +1882,13 @@ #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* Add the new BtShared object to the linked list sharable BtShareds. */ if( p->sharable ){ - sqlite3_mutex *mutexShared; + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) pBt->nRef = 1; - mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); if( pBt->mutex==0 ){ rc = SQLITE_NOMEM; db->mallocFailed = 0; @@ -1964,16 +1966,16 @@ ** true if the BtShared.nRef counter reaches zero and return ** false if it is still positive. */ static int removeFromSharingList(BtShared *pBt){ #ifndef SQLITE_OMIT_SHARED_CACHE - sqlite3_mutex *pMaster; + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) BtShared *pList; int removed = 0; assert( sqlite3_mutex_notheld(pBt->mutex) ); - pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) sqlite3_mutex_enter(pMaster); pBt->nRef--; if( pBt->nRef<=0 ){ if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){ GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext; Index: src/lempar.c ================================================================== --- src/lempar.c +++ src/lempar.c @@ -714,11 +714,13 @@ ParseTOKENTYPE yyminor /* The value for the token */ ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; int yyact; /* The parser action. */ +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) int yyendofinput; /* True if we are at the end of input */ +#endif #ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif yyParser *yypParser; /* The parser */ @@ -737,11 +739,13 @@ yypParser->yyerrcnt = -1; yypParser->yystack[0].stateno = 0; yypParser->yystack[0].major = 0; } yyminorunion.yy0 = yyminor; +#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) yyendofinput = (yymajor==0); +#endif ParseARG_STORE; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); @@ -749,11 +753,10 @@ #endif do{ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); if( yyactyyerrcnt--; yymajor = YYNOCODE; }else if( yyact < YYNSTATE + YYNRULE ){ yy_reduce(yypParser,yyact-YYNSTATE); Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -104,11 +104,11 @@ ** ** * Recursive calls to this routine from thread X return immediately ** without blocking. */ int sqlite3_initialize(void){ - sqlite3_mutex *pMaster; /* The main static mutex */ + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ int rc; /* Result code */ #ifdef SQLITE_OMIT_WSD rc = sqlite3_wsd_init(4096, 24); if( rc!=SQLITE_OK ){ @@ -138,11 +138,11 @@ ** This operation is protected by the STATIC_MASTER mutex. Note that ** MutexAlloc() is called for a static mutex prior to initializing the ** malloc subsystem - this implies that the allocation of a static ** mutex must not require support from the malloc subsystem. */ - pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) sqlite3_mutex_enter(pMaster); sqlite3GlobalConfig.isMutexInit = 1; if( !sqlite3GlobalConfig.isMallocInit ){ rc = sqlite3MallocInit(); } Index: src/mutex.h ================================================================== --- src/mutex.h +++ src/mutex.h @@ -58,14 +58,17 @@ /* ** If this is a no-op implementation, implement everything as macros. */ #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) #define sqlite3_mutex_free(X) -#define sqlite3_mutex_enter(X) +#define sqlite3_mutex_enter(X) #define sqlite3_mutex_try(X) SQLITE_OK -#define sqlite3_mutex_leave(X) +#define sqlite3_mutex_leave(X) #define sqlite3_mutex_held(X) ((void)(X),1) #define sqlite3_mutex_notheld(X) ((void)(X),1) #define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) #define sqlite3MutexInit() SQLITE_OK #define sqlite3MutexEnd() +#define MUTEX_LOGIC(X) +#else +#define MUTEX_LOGIC(X) X #endif /* defined(SQLITE_MUTEX_OMIT) */ Index: src/os.c ================================================================== --- src/os.c +++ src/os.c @@ -295,16 +295,16 @@ ** Register a VFS with the system. It is harmless to register the same ** VFS multiple times. The new VFS becomes the default if makeDflt is ** true. */ int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ - sqlite3_mutex *mutex = 0; + MUTEX_LOGIC(sqlite3_mutex *mutex;) #ifndef SQLITE_OMIT_AUTOINIT int rc = sqlite3_initialize(); if( rc ) return rc; #endif - mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); if( makeDflt || vfsList==0 ){ pVfs->pNext = vfsList; vfsList = pVfs; Index: src/os_unix.c ================================================================== --- src/os_unix.c +++ src/os_unix.c @@ -526,11 +526,11 @@ return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } #endif -#ifdef SQLITE_DEBUG +#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) /* ** Helper function for printing out trace information from debugging ** binaries. This returns the string represetation of the supplied ** integer lock-type. */ Index: src/where.c ================================================================== --- src/where.c +++ src/where.c @@ -2474,11 +2474,10 @@ assert( roundUp==0 || roundUp==1 ); assert( pIdx->nSample>0 ); if( pVal==0 ) return SQLITE_ERROR; n = pIdx->aiRowEst[0]; aSample = pIdx->aSample; - i = 0; eType = sqlite3_value_type(pVal); if( eType==SQLITE_INTEGER ){ v = sqlite3_value_int64(pVal); r = (i64)v; Index: test/tkt3793.test ================================================================== --- test/tkt3793.test +++ test/tkt3793.test @@ -98,20 +98,22 @@ # associated with [db1]. # # Note: Before the bug was fixed, if [db2] was opened with the "-fullmutex 1" # option, then this test case would cause an assert() to fail. # -set ::busyconnection db1 -db1 eval {SELECT * FROM t2 ORDER BY a LIMIT 20} { - do_test tkt3793-2.[incr x] { set ::busyconnection } db1 - set ::busyconnection db2 - - db2 eval { SELECT count(*) FROM t2 } - do_test tkt3793-2.[incr x] { set ::busyconnection } db2 - set ::busyconnection db1 -} - +ifcapable threadsafe { + set ::busyconnection db1 + db1 eval {SELECT * FROM t2 ORDER BY a LIMIT 20} { + do_test tkt3793-2.[incr x] { set ::busyconnection } db1 + set ::busyconnection db2 + + db2 eval { SELECT count(*) FROM t2 } + do_test tkt3793-2.[incr x] { set ::busyconnection } db2 + set ::busyconnection db1 + } +} + do_test tkt3793-3 { db1 close db2 close } {} ADDED tool/warnings-clang.sh Index: tool/warnings-clang.sh ================================================================== --- /dev/null +++ tool/warnings-clang.sh @@ -0,0 +1,13 @@ +#/bin/sh +# +# Run this script in a directory with a working makefile to check for +# compiler warnings in SQLite. +# +rm -f sqlite3.c +make sqlite3.c +echo '************* FTS4 and RTREE ****************' +scan-build gcc -c -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ + -DSQLITE_DEBUG sqlite3.c 2>&1 | grep -v 'ANALYZE:' +echo '********** ENABLE_STAT3. THREADSAFE=0 *******' +scan-build gcc -c -DSQLITE_ENABLE_STAT3 -DSQLITE_THREADSAFE=0 \ + -DSQLITE_DEBUG sqlite3.c 2>&1 | grep -v 'ANALYZE:'