From 85b04f0bc3f3b01c7aa759314d2315c2d4a657e2 Mon Sep 17 00:00:00 2001 From: Ron Pinkas Date: Mon, 7 Jun 1999 11:15:02 +0000 Subject: [PATCH] 19990607-03:05 PST Ron Pinkas * include/hberrors.h added WARN_VAR_NOT_USED * source/compiler/harbour.y added warning message "Variable \'%s\' declared but not used in function: %s" added linked list FunVars to record the usage of declared variables added logic to maintain FunVars added logic to check usage as per FunVars in GenReturn() --- harbour/ChangeLog | 9 ++ harbour/include/hberrors.h | 1 + harbour/source/compiler/harbour.y | 153 +++++++++++++++++++++++++++-- harbour/tests/working/testvars.prg | 27 +++++ 4 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 harbour/tests/working/testvars.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 75c825acc4..d4d68e1eed 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,12 @@ +19990607-03:05 PST Ron Pinkas + * include/hberrors.h + added WARN_VAR_NOT_USED + * source/compiler/harbour.y + added warning message "Variable \'%s\' declared but not used in function: %s" + added linked list FunVars to record the usage of declared variables + added logic to maintain FunVars + added logic to check usage as per FunVars in GenReturn() + 19990607-09:40 Alexander Kresin + source/rtl/natmsg/msgru866.c + source/rtl/natmsg/msgr1251.c diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h index d2b89301f7..38336a3766 100644 --- a/harbour/include/hberrors.h +++ b/harbour/include/hberrors.h @@ -25,6 +25,7 @@ #define ERR_SYNTAX2 20 #define WARN_AMBIGUOUS_VAR 1 +#define WARN_VAR_NOT_USED 2 void GenError( int, char*, char * ); /* generic parsing error management function */ diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index fcbaa36d37..996b88eadf 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -266,7 +266,18 @@ char * _szErrors[] = { "Statement not allowed outside of procedure or function", }; /* Table with parse warnings */ -char * _szWarnings[] = { "Ambiguous reference, assuming memvar: \'%s\'" }; +char * _szWarnings[] = { "Ambiguous reference, assuming memvar: \'%s\'", + "Variable \'%s\' declared but not used in function: %s" }; + +typedef struct _DECLARED_VAR +{ + char * szVarName; + char cVarType; + int iVarUsed; + struct _DECLARED_VAR *pNextVar; +} DECLARED_VAR, * PDECLARED_VAR; + +DECLARED_VAR FunVars = { "", 'U', 0, 0 }; /* Table with reserved functions names * NOTE: THIS TABLE MUST BE SORTED ALPHABETICALLY @@ -442,10 +453,10 @@ PATHNAMES *_pIncludePath = NULL; /*the highest precedence*/ %type IDENTIFIER LITERAL FunStart MethStart IdSend ObjectData -%type DOUBLE +%type DOUBLE %type ArgList ElemList ExpList FunCall FunScope IncDec Logical Params ParamList %type INTEGER BlockExpList Argument IfBegin VarId VarList MethParams ObjFunCall -%type MethCall BlockList FieldList +%type MethCall BlockList FieldList %type INTLONG WhileBegin BlockBegin %type IfElseIf Cases @@ -1461,9 +1472,9 @@ void AddSearchPath( char *szPath, PATHNAMES * *pSearchList ) if( pPath ) { while( pPath->pNext ) - pPath =pPath->pNext; - pPath->pNext =(PATHNAMES *)OurMalloc( sizeof(PATHNAMES) ); - pPath =pPath->pNext; + pPath = pPath->pNext; + pPath->pNext = ( PATHNAMES * ) OurMalloc( sizeof( PATHNAMES ) ); + pPath = pPath->pNext; } else { @@ -1519,6 +1530,7 @@ void AddVar( char * szVarName ) { PVAR pVar, pLastVar; PFUNCTION pFunc =functions.pLast; + PDECLARED_VAR pVarDef; if( ! _iStartProc && functions.iCount <= 1 && iVarScope == VS_LOCAL ) { @@ -1538,6 +1550,24 @@ void AddVar( char * szVarName ) GenError( ERR_FOLLOWS_EXEC, (iVarScope==VS_LOCAL?"LOCAL":"STATIC"), NULL ); } + pVarDef = &FunVars; + while ( pVarDef->pNextVar ) + { + pVarDef = pVarDef->pNextVar; + } + + pVarDef->szVarName = strdup( szVarName ); + pVarDef->cVarType = 'U'; + pVarDef->iVarUsed = 0; + pVarDef->pNextVar = ( PDECLARED_VAR ) OurMalloc( sizeof( DECLARED_VAR ) ); + + pVarDef = pVarDef->pNextVar; + + pVarDef->szVarName = ""; + pVarDef->cVarType = 'U'; + pVarDef->iVarUsed = 0; + pVarDef->pNextVar = 0; + /* When static variable is added then functions.pLast points to function * that will initialise variables. The function where variable is being * defined is stored in pOwner member. @@ -2534,6 +2564,34 @@ void GenExterns( void ) /* generates the symbols for the EXTERN names */ void GenReturn( WORD wOffset ) /* generates a return offset to later on fill it with the proper exiting pcode address */ { PRETURN pReturn = ( PRETURN ) OurMalloc( sizeof( _RETURN ) ), pLast; + PDECLARED_VAR pVarDef, pRelease; + + if ( _iWarnings ) + { + pVarDef = &FunVars; + if ( *(pVarDef->szVarName) && ! pVarDef->iVarUsed ) + GenWarning( WARN_VAR_NOT_USED, pVarDef->szVarName, functions.pLast->szName ); + + pVarDef = pVarDef->pNextVar; + + FunVars.szVarName = ""; + FunVars.cVarType = 'U'; + FunVars.iVarUsed = 0; + FunVars.pNextVar = 0; + + while ( pVarDef ) + { + + if ( *(pVarDef->szVarName) && ! pVarDef->iVarUsed ) + GenWarning( WARN_VAR_NOT_USED, pVarDef->szVarName, functions.pLast->szName ); + + pRelease = pVarDef; + + pVarDef = pVarDef->pNextVar; + + OurFree( pRelease ); + } + } pReturn->wOffset = wOffset; pReturn->pNext = 0; @@ -2925,13 +2983,51 @@ void MessageFix( char * szMsgName ) /* fix a generated message to an object */ void PopId( char * szVarName ) /* generates the pcode to pop a value from the virtual machine stack onto a variable */ { WORD wVar; + PDECLARED_VAR pVarDef; + int iFound = 0; if( ( wVar = GetLocalVarPos( szVarName ) ) ) + { GenPCode3( _POPLOCAL, LOBYTE( wVar ), HIBYTE( wVar ) ); - else if( ( wVar = GetStaticVarPos( szVarName ) ) ) - GenPCode3( _POPSTATIC, LOBYTE( wVar ), HIBYTE( wVar ) ); + if ( _iWarnings ) + { + pVarDef = &FunVars; + do + { + if ( ( iFound = ! strcmp( pVarDef->szVarName, szVarName ) ) ) + break; + pVarDef = pVarDef->pNextVar; + } while ( pVarDef->pNextVar ); + + if ( iFound ) + pVarDef->iVarUsed++; + else + GenError( 0, "Compiler Error, Declared variable \'%s\' not found in linked list", szVarName ); + } + } + else if( ( wVar = GetStaticVarPos( szVarName ) ) ) + { + GenPCode3( _POPSTATIC, LOBYTE( wVar ), HIBYTE( wVar ) ); + + if ( _iWarnings ) + { + pVarDef = &FunVars; + do + { + if ( ( iFound = ! strcmp( pVarDef->szVarName, szVarName ) ) ) + break; + + pVarDef = pVarDef->pNextVar; + } while ( pVarDef->pNextVar ); + + if ( iFound ) + pVarDef->iVarUsed++; + else + GenError( 0, "Compiler Error, Declared variable \'%s\' not found in linked list", szVarName ); + } + } else { GenWarning( WARN_AMBIGUOUS_VAR, szVarName, NULL ); @@ -2951,6 +3047,8 @@ void PopId( char * szVarName ) /* generates the pcode to pop a value from the vi void PushId( char * szVarName ) /* generates the pcode to push a variable value to the virtual machine stack */ { WORD wVar; + PDECLARED_VAR pVarDef; + int iFound = 0; if( iVarScope == VS_STATIC ) { @@ -2961,10 +3059,47 @@ void PushId( char * szVarName ) /* generates the pcode to push a variable value } if( ( wVar = GetLocalVarPos( szVarName ) ) ) + { GenPCode3( _PUSHLOCAL, LOBYTE( wVar ), HIBYTE( wVar ) ); + if ( _iWarnings ) + { + pVarDef = &FunVars; + do + { + if ( ( iFound = ! strcmp( pVarDef->szVarName, szVarName ) ) ) + break; + + pVarDef = pVarDef->pNextVar; + } while ( pVarDef->pNextVar ); + + if ( iFound ) + pVarDef->iVarUsed++; + else + GenError( 0, "Compiler Error, Declared variable \'%s\' not found in linked list", szVarName ); + } + } else if( ( wVar = GetStaticVarPos( szVarName ) ) ) - GenPCode3( _PUSHSTATIC, LOBYTE( wVar ), HIBYTE( wVar ) ); + { + GenPCode3( _PUSHSTATIC, LOBYTE( wVar ), HIBYTE( wVar ) ); + + if ( _iWarnings ) + { + pVarDef = &FunVars; + do + { + if ( ( iFound = ! strcmp( pVarDef->szVarName, szVarName ) ) ) + break; + + pVarDef = pVarDef->pNextVar; + } while ( pVarDef->pNextVar ); + + if ( iFound ) + pVarDef->iVarUsed++; + else + GenError( 0, "Compiler Error, Declared variable \'%s\' not found in linked list", szVarName ); + } + } else { diff --git a/harbour/tests/working/testvars.prg b/harbour/tests/working/testvars.prg new file mode 100644 index 0000000000..d5f72911c5 --- /dev/null +++ b/harbour/tests/working/testvars.prg @@ -0,0 +1,27 @@ +Function Main(Param1) + + local i, j, k + + i := 1 + j := 2 + + Sub( @j ) + + QOut( j ) + +return NIL + +Function Sub( j ) + + m->i := 1 + j := 3 + +return NIL + +Function arrvar() + + //local i := {1} + + i[1] := 2 + +return NIL