From af8fd924ff9705a74998f0468fcd3b297a9e744b Mon Sep 17 00:00:00 2001 From: Ryszard Glab Date: Tue, 1 Feb 2000 12:40:29 +0000 Subject: [PATCH] ChangeLog 20000201-13:00 GMT+1 --- harbour/ChangeLog | 15 ++++++++++ harbour/source/compiler/genc.c | 9 +++++- harbour/source/compiler/harbour.c | 50 +++++++++++++++++++++++-------- harbour/source/compiler/harbour.y | 25 ++++++++-------- 4 files changed, 73 insertions(+), 26 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 1c0d72fb3c..96dcbada4d 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,18 @@ +20000201-13:00 GMT+1 Ryszard Glab + + *source/compiler/harbour.c + *source/compiler/harbour.y + *source/compiler/genc.c + * fixed GPF (core dump) if private/public variable was initialized + with a codeblock with a local parameter, e.g. + PRIVATE var:={ | x | expression } + * static variables cannot be initialized with a codeblock which + uses a local variable, e.g. + LOCAL locvar + STATIC stavar:={ || locvar } + Notice that Clipper is compiling it however it generates a runtime + error if such codeblock is evaluated. + 20000131-21:20 GMT+1 Victor Szakats * include/hbextern.ch source/runner/stdalone/external.prg diff --git a/harbour/source/compiler/genc.c b/harbour/source/compiler/genc.c index 6362e4dcf6..ae33bd32ec 100644 --- a/harbour/source/compiler/genc.c +++ b/harbour/source/compiler/genc.c @@ -747,7 +747,14 @@ void hb_compGenCCode( PHB_FNAME pFileName ) /* generates the C language ou fprintf( yyc, "\t%i, %i,", pFunc->pCode[ lPCodePos ], pFunc->pCode[ lPCodePos + 1 ] ); - if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %s */", hb_compVariableFind( pFunc->pLocals, w )->szName ); + /* NOTE: + * When a codeblock is used to initialize a static variable + * the the names of local variables cannot be determined + * because at the time of C code generation we don't know + * in which function was defined this local variable + */ + if( (pFunc->cScope & (FS_INIT | FS_EXIT)) != (FS_INIT | FS_EXIT) ) + if( hb_comp_bGenCVerbose ) fprintf( yyc, "\t/* %s */", hb_compVariableFind( pFunc->pLocals, w )->szName ); fprintf( yyc, "\n" ); lPCodePos +=2; } diff --git a/harbour/source/compiler/harbour.c b/harbour/source/compiler/harbour.c index 4419c81ea2..2102bfb20a 100644 --- a/harbour/source/compiler/harbour.c +++ b/harbour/source/compiler/harbour.c @@ -69,7 +69,7 @@ static void hb_compGenFieldPCode( BYTE , int, char *, PFUNCTION ); /* gener static void hb_compGenVariablePCode( BYTE , char * ); /* generates the pcode for undeclared variable */ static void hb_compGenVarPCode( BYTE , char * ); /* generates the pcode for undeclared variable */ -static void hb_compFixReturns( void ); /* fixes all last defined function returns jumps offsets */ +void hb_compFixReturns( void ); /* fixes all last defined function returns jumps offsets */ static PFUNCTION hb_compFunctionNew( char *, char ); /* creates and initialises the _FUNC structure */ static void hb_compCheckDuplVars( PVAR pVars, char * szVarName, int iVarScope ); /*checks for duplicate variables definitions */ @@ -221,9 +221,6 @@ int main( int argc, char * argv[] ) /* we create the output file name */ hb_compOutputFile(); - /* fix all previous function returns offsets */ - hb_compFixReturns(); - if( ! hb_comp_bQuiet ) { if( ! hb_comp_bStartProc ) @@ -379,13 +376,6 @@ void hb_compVariableAdd( char * szVarName, char cValueType ) hb_compGenError( hb_comp_szErrors, 'E', ERR_FOLLOWS_EXEC, ( hb_comp_iVarScope == VS_LOCAL ? "LOCAL" : "STATIC" ), NULL ); } - /* When static variable is added then hb_comp_functions.pLast points to function - * that will initialise variables. The function where variable is being - * defined is stored in pOwner member. - */ - if( hb_comp_iVarScope == VS_STATIC ) - pFunc = pFunc->pOwner; - /* Check if a declaration of duplicated variable name is requested */ if( pFunc->szName ) { @@ -947,8 +937,12 @@ static int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a PFUNCTION pFunc = hb_comp_functions.pLast; if( pFunc->szName ) + { /* we are in a function/procedure -we don't need any tricks */ + if( pFunc->pOwner ) + pFunc =pFunc->pOwner; return hb_compVariableGetPos( pFunc->pLocals, szVarName ); + } else { /* we are in a codeblock */ @@ -960,10 +954,21 @@ static int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a * where the codeblock is defined */ PFUNCTION pOutBlock = pFunc; /* the outermost codeblock */ + BOOL bStatic; pFunc = pFunc->pOwner; while( pFunc ) { + bStatic = FALSE; + if( ( pFunc->cScope & (FS_INIT | FS_EXIT) ) == (FS_INIT | FS_EXIT) ) + { + /* we are in a codeblock used to initialize a static variable - + * skip to a function where this static variable was declared + */ + pFunc = pFunc->pOwner; + bStatic = TRUE; + } + iVar = hb_compVariableGetPos( pFunc->pLocals, szVarName ); if( iVar ) { @@ -976,6 +981,25 @@ static int hb_compLocalGetPos( char * szVarName ) /* returns the order + 1 of a hb_compGenError( hb_comp_szErrors, 'E', ERR_OUTER_VAR, szVarName, NULL ); return iVar; } + else if( bStatic ) + { + /* local variable was referenced in a codeblock during + * initialization of static variable. This cannot be supported + * because static variables are initialized at program + * startup when there is no local variables yet - hence we + * cannot detach this local variable + * For example: + * LOCAL locvar + * STATIC stavar:={ | x | locvar} + * + * NOTE: Clipper creates such a codeblock however at the + * time of codeblock evaluation it generates a runtime error: + * 'bound error: array acccess' + * Called from: (b)STATICS$(0) + */ + hb_compGenError( hb_comp_szErrors, 'E', ERR_ILLEGAL_INIT, "(b)", szVarName ); + return iVar; + } else { /* We want to access a local variable defined in a function @@ -1337,7 +1361,7 @@ static void hb_compGenVariablePCode( BYTE bPCode, char * szVarName ) void hb_compGenFieldPCode( BYTE bPCode, int wVar, char * szVarName, PFUNCTION pFunc ) { PVAR pField; - + if( ! pFunc->szName ) { /* we have to check the list of nested codeblock up to a function @@ -1884,7 +1908,7 @@ static void hb_compCheckDuplVars( PVAR pVar, char * szVarName, int iVarScope ) } } -static void hb_compFixReturns( void ) /* fixes all last defined function returns jumps offsets */ +void hb_compFixReturns( void ) /* fixes all last defined function returns jumps offsets */ { if( hb_comp_iWarnings && hb_comp_functions.pLast ) { diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 8e6b617eab..6d04507ba8 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -88,6 +88,7 @@ static void hb_compVariableDim( char *, HB_EXPR_PTR ); /* Misc functions defined in harbour.c */ extern void hb_compGenError( char* _szErrors[], char cPrefix, int iError, char * szError1, char * szError2 ); extern void hb_compGenWarning( char* _szWarnings[], char cPrefix, int iWarning, char * szWarning1, char * szWarning2); +void hb_compFixReturns( void ); /* fixes all last defined function returns jumps offsets */ #ifdef HARBOUR_YYDEBUG @@ -1046,42 +1047,39 @@ ExtVarDef : VarDef } ; -VarDef : IdentName AsType +VarDef : IdentName AsType { hb_compVariableAdd( $1, $2 ); } { if( hb_comp_iVarScope == VS_STATIC ) { hb_compStaticDefStart(); /* switch to statics pcode buffer */ - hb_compVariableAdd( $1, $2 ); hb_compStaticDefEnd(); } else if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE ) { - hb_compVariableAdd( $1, $2 ); hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), FALSE ); } - else - hb_compVariableAdd( $1, $2 ); } - | IdentName AsType INASSIGN Expression + | IdentName AsType { hb_compVariableAdd( $1, $2 ); + $$ = hb_comp_iVarScope; + } + INASSIGN Expression { + hb_comp_iVarScope = $3; if( hb_comp_iVarScope == VS_STATIC ) { hb_compStaticDefStart(); /* switch to statics pcode buffer */ - hb_compVariableAdd( $1, $2 ); - hb_compExprDelete( hb_compExprGenStatement( hb_compExprAssignStatic( hb_compExprNewVar( $1 ), $4 ) ) ); + hb_compExprDelete( hb_compExprGenStatement( hb_compExprAssignStatic( hb_compExprNewVar( $1 ), $5 ) ) ); hb_compStaticDefEnd(); } else if( hb_comp_iVarScope == VS_PUBLIC || hb_comp_iVarScope == VS_PRIVATE ) { - hb_compExprDelete( hb_compExprGenPush( $4 ) ); - hb_compVariableAdd( $1, $2 ); + hb_compExprDelete( hb_compExprGenPush( $5 ) ); hb_compRTVariableAdd( hb_compExprNewRTVar( $1, NULL ), TRUE ); } else { - hb_compVariableAdd( $1, $2 ); - hb_compExprDelete( hb_compExprGenStatement( hb_compExprAssign( hb_compExprNewVar( $1 ), $4 ) ) ); + hb_compExprDelete( hb_compExprGenStatement( hb_compExprAssign( hb_compExprNewVar( $1 ), $5 ) ) ); } } @@ -1438,6 +1436,9 @@ int hb_compYACCMain( char * szName ) yyparse(); + /* fix all previous function returns offsets */ + hb_compFixReturns(); + hb_compExternGen(); /* generates EXTERN symbols names */ if( hb_comp_pInitFunc )