diff --git a/harbour/ChangeLog b/harbour/ChangeLog index df41ac2b95..584aefbe6b 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,24 @@ +20000430-22:15 GMT-8 Ron Pinkas + * harbour/source/compiler/harbour.y + ! Fixed { hb_compVariableDim( $1, $2 ); } to { hb_comp_cVarType = 'A'; hb_compVariableDim( $1, $2 ); } + so that correct type is saved. + + * harbour/source/compiler/hbpcode.c + * Enhancements to hb_compStrongType() + + * harbour/source/compiler/hbgenerr.c + + added : + "3Can\'t use array index with NON Array" + "3Incompatible return value: \'%s\' expected: \'%s\'" + + * harbour/include/hberrors.h + + added : + #define HB_COMP_WARN_NOT_ARRAY 13 + #define HB_COMP_RETURN_TYPE 14 + + * harbour/tests/testwarn.prg + + Added code to demonstrate more warnings. + 20000430-23:00 GMT+2 Maurilio Longo * source/rtl/teditor.prg @@ -27,6 +48,8 @@ 20000430-13:50 GMT+1 Ryszard Glab *source/compiler/harbour.c + *fixed possible memory reallocation error in hb_compNOOPadd() + *fixed possible memory reallocation error in hb_compNOOPadd() *source/compiler/hbpcode.c diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h index 77bba52565..c572de6641 100644 --- a/harbour/include/hberrors.h +++ b/harbour/include/hberrors.h @@ -103,9 +103,11 @@ extern "C" { #define HB_COMP_WARN_OPERANDS_INCOMPATBLE 10 #define HB_COMP_WARN_ASSIGN_SUSPECT 11 #define HB_COMP_WARN_OPERAND_SUSPECT 12 -#define HB_COMP_WARN_MEANINGLESS 13 -#define HB_COMP_WARN_UNREACHABLE 14 -#define HB_COMP_WARN_DUPL_ANNOUNCE 15 +#define HB_COMP_WARN_NOT_ARRAY 13 +#define HB_COMP_RETURN_TYPE 14 +#define HB_COMP_WARN_MEANINGLESS 15 +#define HB_COMP_WARN_UNREACHABLE 16 +#define HB_COMP_WARN_DUPL_ANNOUNCE 17 /* * Errors generated by Harbour preprocessor diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index 342b37d82c..25c4786311 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -1085,7 +1085,7 @@ VarDef : IdentName AsType { hb_compVariableAdd( $1, $2 ); } } | IdentName DimList { hb_compVariableDim( $1, $2 ); } - | IdentName DimList AS_ARRAY { hb_compVariableDim( $1, $2 ); } + | IdentName DimList AS_ARRAY { hb_comp_cVarType = 'A'; hb_compVariableDim( $1, $2 ); } ; /* NOTE: DimList and DimIndex is the same as ArrayIndex and IndexList diff --git a/harbour/source/compiler/hbgenerr.c b/harbour/source/compiler/hbgenerr.c index 06c384b5a9..2228f7dc5c 100644 --- a/harbour/source/compiler/hbgenerr.c +++ b/harbour/source/compiler/hbgenerr.c @@ -103,6 +103,8 @@ char * hb_comp_szWarnings[] = "3Incompatible operand types: \'%s\' and: \'%s\'", "3Suspicious type in assignment to: \'%s\' expected: \'%s\'", "3Suspicious operand type: \'UnKnown\' expected: \'%s\'", + "3Can\'t use array index with NON Array", + "3Incompatible return value: \'%s\' expected: \'%s\'", "0Meaningless use of expression: \'%s\'", "2Unreachable code", "1Redundant \'ANNOUNCE %s\' statement ignored" diff --git a/harbour/source/compiler/hbpcode.c b/harbour/source/compiler/hbpcode.c index 5bc8b53b15..c3177c895f 100644 --- a/harbour/source/compiler/hbpcode.c +++ b/harbour/source/compiler/hbpcode.c @@ -224,7 +224,19 @@ void hb_compStrongType( int iSize ) case HB_P_SWAPALIAS : case HB_P_RETVALUE : - /* TODO Check effect on stack. */ + pFunc->iStackIndex--; + + if ( ! pFunc->pOwner ) + pSym = hb_compSymbolFind( pFunc->szName, NULL ); + + /* The function was declared, but return value doesn't mateche the declaration */ + if ( pSym && pSym->cType != ' ' && pSym->cType != pFunc->pStack[ pFunc->iStackIndex ] ) + { + sprintf( szType1, "%c", pSym->cType ); + sprintf( szType2, "%c", pFunc->pStack[ pFunc->iStackIndex ] ); + + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_RETURN_TYPE, szType2, szType1 ); + } break; case HB_P_DO : @@ -308,6 +320,44 @@ void hb_compStrongType( int iSize ) case HB_P_NEGATE : case HB_P_MULT : case HB_P_POWER : + pFunc->iStackIndex--; + + if ( pFunc->iStackIndex < 1 ) + /* TODO Error Message after finalizing all possible pcodes. */ + break; + + sprintf( szType1, "%c", pFunc->pStack[ pFunc->iStackIndex - 1 ] ); + sprintf( szType2, "%c", pFunc->pStack[ pFunc->iStackIndex ] ); + + if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' && pFunc->pStack[ pFunc->iStackIndex - 1 ] == ' ' ) + /* Override the last item with the new result type which is already there */ + ; + else if ( pFunc->pStack[ pFunc->iStackIndex ] == 'N' && pFunc->pStack[ pFunc->iStackIndex - 1 ] == 'N' ) + /* Override the last item with the new result type wich is already there */ + ; + else if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == ' ' ) + { + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_SUSPECT, szType2, NULL ); + + /* Override the last item with the new result type */ + pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' '; + } + else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) + { + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_SUSPECT, szType1, NULL ); + + /* Override the last item with the new result type wich is already there */ + } + else + { + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERANDS_INCOMPATBLE, szType1, szType2 ); + + /* Override the last item with the new result type */ + pFunc->pStack[ pFunc->iStackIndex - 1 ] = 'U'; + } + + break; + case HB_P_EQUAL : case HB_P_EXACTLYEQUAL : case HB_P_NOTEQUAL : @@ -348,7 +398,7 @@ void hb_compStrongType( int iSize ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERANDS_INCOMPATBLE, szType1, szType2 ); /* Override the last item with the new result type */ - pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' '; + pFunc->pStack[ pFunc->iStackIndex - 1 ] = 'U'; } break; @@ -401,9 +451,9 @@ void hb_compStrongType( int iSize ) break; /* Blcks */ - case HB_P_MPUSHBLOCK : - case HB_P_PUSHBLOCK : - pFunc->pStack[ pFunc->iStackIndex++ ] = 'B'; + case HB_P_ENDBLOCK : + /* Override the last value of the block left on the stack. */ + pFunc->pStack[ pFunc->iStackIndex ] = 'B'; break; /* Undefined */ @@ -451,11 +501,12 @@ void hb_compStrongType( int iSize ) if ( pSym ) { - /* TODO: Check this!!! */ + /* TODO: Check this!!! if ( ( pSym->cScope & HB_FS_PUBLIC ) == HB_FS_PUBLIC || ( pSym->cScope & HB_FS_STATIC ) == HB_FS_STATIC || ( pSym->cScope & HB_FS_INIT ) == HB_FS_INIT || ( pSym->cScope & HB_FS_EXIT ) == HB_FS_EXIT ) + */ /* Storing a Book Mark of the last pushed symbol so we know how many bytes to pop when encountering function call. */ pFunc->pFunctionCalls[ pFunc->iFunctionIndex++ ] = pFunc->iStackIndex; @@ -553,13 +604,7 @@ void hb_compStrongType( int iSize ) case HB_P_PUSHMEMVAR : pSym = hb_compSymbolGetPos( pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256 ); if ( pSym ) - { - /* Review with Ryszard. */ - if ( pVar->cType == 'U' ) - pVar->cType = ' '; - pFunc->pStack[ pFunc->iStackIndex++ ] = pSym->cType; - } else pFunc->pStack[ pFunc->iStackIndex++ ] = ' '; @@ -568,6 +613,24 @@ void hb_compStrongType( int iSize ) /* Arrays. */ + case HB_P_ARRAYDIM : + wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + + pFunc->iStackIndex -= wVar; + + pFunc->pStack[ pFunc->iStackIndex++ ] = 'A'; + + break; + + case HB_P_ARRAYGEN : + wVar = pFunc->pCode[ ulPos + 1 ] + pFunc->pCode[ ulPos + 2 ] * 256; + + pFunc->iStackIndex -= wVar; + + pFunc->pStack[ pFunc->iStackIndex++ ] = 'A'; + + break; + case HB_P_ARRAYPUSH : /* TODO: Deal with Array Elements. */ pFunc->pStack[ pFunc->iStackIndex++ ] = ' '; @@ -582,13 +645,21 @@ void hb_compStrongType( int iSize ) case HB_P_MPUSHVARIABLE : case HB_P_MACROPUSHALIASED : case HB_P_MACROPUSH : - pFunc->pStack[ pFunc->iStackIndex++ ] = ' '; + /* Replace the value of the macro expression with unknown result of expanded macro. */ + pFunc->pStack[ pFunc->iStackIndex ] = ' '; break; case HB_P_MACROSYMBOL : - /* TODO: check affect on stack. */ + /* Replace Macro Variable Symbol Name type with unknown type of expanded macro Function Call */ + pFunc->pStack[ pFunc->iStackIndex ] = ' '; + + /* Storing a Book Mark of the last pushed symbol so we know how many bytes to pop when encountering function call. */ + pFunc->pFunctionCalls[ pFunc->iFunctionIndex++ ] = pFunc->iStackIndex; + break; + case HB_P_MACROTEXT : - /* TODO: check affect on stack. */ + /* Stack already has type C. */ + /*pFunc->pStack[ pFunc->iStackIndex ] = 'C';*/ break; /*-----------------4/26/00 0:15AM------------------- @@ -597,13 +668,12 @@ void hb_compStrongType( int iSize ) case HB_P_POP : case HB_P_POPALIAS : - case HB_P_POPFIELD : - /* TODO: Add support for FIELD declarations. */ - case HB_P_POPALIASEDFIELD : - /* TODO: Add support for FIELD declarations. */ pFunc->iStackIndex--; break; + case HB_P_POPFIELD : + case HB_P_POPALIASEDFIELD : + /* TODO: Add support for FIELD declarations. */ case HB_P_POPMEMVAR : case HB_P_POPVARIABLE : case HB_P_POPALIASEDVAR : @@ -639,10 +709,18 @@ void hb_compStrongType( int iSize ) /* we are accesing variables within a codeblock */ if( wVar < 0 ) - /* TODO: Deal with Codeblock Refernced locals. */ - ; + { + /* Finding the Function owning the block. */ + pTmp = pFunc->pOwner; + + /* Might be a nested block. */ + while ( pTmp->pOwner ) + pTmp = pTmp->pOwner; + + pVar = hb_compVariableFind( pTmp->pLocals, -iVar ); + } else - pVar = hb_compVariableFind( pFunc->pLocals, wVar ); + pVar = hb_compVariableFind( pFunc->pLocals, iVar ); if ( pVar->cType != ' ' ) { @@ -664,14 +742,22 @@ void hb_compStrongType( int iSize ) /* TODO Error Message after finalizing all possible pcodes. */ break; - iVar = pFunc->pCode[ ulPos + 1 ]; + iVar = ( char ) pFunc->pCode[ ulPos + 1 ]; - /* we are accesing variables within a codeblock */ + /* we are accesing local variable refernced within a codeblock */ if( iVar < 0 ) - /* TODO: Deal with Codeblock Refernced locals. */ - ; + { + /* Finding the Function owning the block. */ + pTmp = pFunc->pOwner; + + /* Might be a nested block. */ + while ( pTmp->pOwner ) + pTmp = pTmp->pOwner; + + pVar = hb_compVariableFind( pTmp->pLocals, -iVar ); + } else - pVar = hb_compVariableFind( pFunc->pLocals, iVar ); + pVar = hb_compVariableFind( pFunc->pLocals, iVar ); if ( pVar->cType != ' ' ) { @@ -726,6 +812,7 @@ void hb_compStrongType( int iSize ) break; case HB_P_ARRAYPOP : + /* Poping the Array Index. */ pFunc->iStackIndex--; if ( pFunc->iStackIndex < 0 ) @@ -733,22 +820,14 @@ void hb_compStrongType( int iSize ) break; /* TODO: Deal with Array Elements. */ - if ( pFunc->pStack[ pFunc->iStackIndex ] != ' ' ) - { - } + if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == ' ' ) + ; + else if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] != 'A' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_NOT_ARRAY, NULL, NULL ); - break; + /* Poping the Assigned Value. */ + pFunc->iStackIndex--; - case HB_P_ARRAYDIM : - pFunc->iStackIndex -= 2; - /* TODO: Deal with Array Elements. */ - /* Pop the values used to generate the array. */ - break; - - case HB_P_ARRAYGEN : - pFunc->iStackIndex -= 2; - /* TODO: Deal with Array Elements. */ - /* Pop the values used to generate the array. */ break; } diff --git a/harbour/tests/testwarn.prg b/harbour/tests/testwarn.prg index aa0de15692..59875d89f8 100644 --- a/harbour/tests/testwarn.prg +++ b/harbour/tests/testwarn.prg @@ -11,13 +11,33 @@ DECLARE FUNCTION nMyFunc( ) AS NUMERIC FUNCTION Main() - LOCAL n AS NUMERIC + LOCAL n AS NUMERIC, cVar AS CHARACTER, a[5,5,5] AS ARRAY + + n := &SomeFun( 2, 3 ) + + n := &(cVar) + + n := "&SomeVar" + + n := &Var.1 + + n := V&SomeVar.1 + + n[2] := 4 + + cVar := {|nb AS NUMERIC , cb AS CHARACTER, db AS DATE| n := .F., nb := 'A', cb := 1, db := 0, n := 'wrong type', 0 } ? "This is a compiler test." + n := 'C is Wrong Type for n' + + n := {1,2,3} + + n := a + n := nMyFunc() - cVar := {|n AS NUMERIC , c AS CHARACTER, d AS DATE| n := 'A', c := 1, d := 0, .T. } + IIF( n, 2, 3 ) RETURN NIL