diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 915c354a5a..cd14581786 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,4 +1,16 @@ -20000504-22:40 GMT-8 Ron Pinkas +20000506-16:35 GMT-8 Ron Pinkas + + * source/compiler/hbpcode.c + + Added logic to hb_compStrongType() to support object methods and properties. + * Enhanced logic of array checks. + + * include/hberrors.h + ! Added #define HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT + + * source/compiler/hbgenerr.c + * Added : 4Suspicious type in assignment to declared array element expected: \'%s\'" + +20000506-12:10 GMT-8 Ron Pinkas * source/compiler/hbpcode.c + Added logic to allow PLUS an MINUS to accept any type as long as same. @@ -66,10 +78,10 @@ + Added "Adaptive Type Checking" to control type mismatch in undeclared variables. * include/hberrors.h - ! Added #define HB_COMP_ARRAY_ASSIGN_TYPE to HB_COMP_WARN_ARRAY_ASSIGN_TYPE + ! Modified #define HB_COMP_ARRAY_ASSIGN_TYPE to HB_COMP_WARN_ARRAY_ASSIGN_TYPE * source/compiler/hbgenerr.c - * Added : Moved "Suspecious ..." to level w4 + * Moved "Suspecious ..." to level w4 * tests/testwarn.prg + Added code to demonstrate "Adaptive Type Checking". diff --git a/harbour/include/hberrors.h b/harbour/include/hberrors.h index bd8f57e6aa..a86801b24c 100644 --- a/harbour/include/hberrors.h +++ b/harbour/include/hberrors.h @@ -111,9 +111,10 @@ extern "C" { #define HB_COMP_WARN_DECLARATION_CONFLICT 18 #define HB_COMP_WARN_NOT_INITIALIZED 19 #define HB_COMP_WARN_ARRAY_ASSIGN_TYPE 20 -#define HB_COMP_WARN_MEANINGLESS 21 -#define HB_COMP_WARN_UNREACHABLE 22 -#define HB_COMP_WARN_DUPL_ANNOUNCE 23 +#define HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT 21 +#define HB_COMP_WARN_MEANINGLESS 22 +#define HB_COMP_WARN_UNREACHABLE 23 +#define HB_COMP_WARN_DUPL_ANNOUNCE 24 /* * Errors generated by Harbour preprocessor diff --git a/harbour/source/compiler/hbgenerr.c b/harbour/source/compiler/hbgenerr.c index 2a83425c3f..e6ea80677e 100644 --- a/harbour/source/compiler/hbgenerr.c +++ b/harbour/source/compiler/hbgenerr.c @@ -111,6 +111,7 @@ char * hb_comp_szWarnings[] = "3Function \'%s\' conflicting with its declaration", "3Variable \'%s\' used but never initialized", "3Incompatible type in assignment to declared array element expected: \'%s\'", + "4Suspicious type in assignment to declared array element 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 2f63ab930f..40676e8caf 100644 --- a/harbour/source/compiler/hbpcode.c +++ b/harbour/source/compiler/hbpcode.c @@ -275,6 +275,9 @@ void hb_compStrongType( int iSize ) case HB_P_FUNCTIONSHORT : wVar = pFunc->pCode[ ulPos + 1 ]; + if ( pFunc->iStackIndex < wVar + 2 ) + break; + if ( hb_comp_iParamCount > -1 ) { if( hb_comp_iParamCount == wVar ) @@ -310,6 +313,9 @@ void hb_compStrongType( int iSize ) /* Removing the NIL */ pFunc->iStackIndex--; + /* Declared result already on stack. */ + //printf( "\nType of Function: \'%c\'\n", pFunc->pStack[ pFunc->iStackIndex - 1 ] ); + /* Resetting */ hb_comp_cParamTypes = NULL; hb_comp_iParamCount = -1; @@ -360,6 +366,27 @@ void hb_compStrongType( int iSize ) hb_comp_iParamCount = -1; break; + case HB_P_MESSAGE : + sprintf( szType1, "%c", pFunc->pStack[ pFunc->iStackIndex - 1 ] ); + + if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == 'O' ) + ; + else if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == ' ' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_SUSPECT, "O", NULL ); + else + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_TYPE, szType1, "O" ); + + /* Allow declaration of Methods */ + + /* Unknown result of method */ + pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' '; + break; + + /* Handles by HB_P_MESSAGE. */ + case HB_P_SENDSHORT : + case HB_P_SEND : + break; + case HB_P_DEC : case HB_P_INC : if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] > 122 ) @@ -978,9 +1005,11 @@ void hb_compStrongType( int iSize ) else pFunc->pStack[ pFunc->iStackIndex++ ] = ' '; + //printf( "\nPushed Local: %s Type: \'%c\'\n", pVar->szName, pVar->cType ); + break; - /* Static Variables */ + /* Static Variables */ case HB_P_PUSHSTATIC : pTmp = hb_comp_functions.pFirst; @@ -1068,28 +1097,16 @@ void hb_compStrongType( int iSize ) /* TODO Error Message after finalizing all possible pcodes. */ break; + /* Removing the dimensions sizes. */ + pFunc->iStackIndex -= wVar; + + /* Push type array. */ if ( wVar ) - cType = pFunc->pStack[ pFunc->iStackIndex - 1 ]; + pFunc->pStack[ pFunc->iStackIndex++ ] = 'A'; else - cType = 'A'; - - while ( --wVar > 0 ) - { - pFunc->iStackIndex--; - - if ( cType == ' ' || cType != pFunc->pStack[ pFunc->iStackIndex - 1 ] ) - { - cType = 'A'; - break; - } - } - - /* Lower Case Indicates array of ...*/ - if ( cType != 'A' ) - cType = tolower( cType ); - - pFunc->pStack[ pFunc->iStackIndex - 1 ] = cType; + pFunc->pStack[ pFunc->iStackIndex++ ] = '-' + 100; + //printf( "\nPushed array at: %i\n", pFunc->iStackIndex - 1 ); break; case HB_P_ARRAYGEN : @@ -1137,13 +1154,31 @@ void hb_compStrongType( int iSize ) /* TODO Error Message after finalizing all possible pcodes. */ break; - if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == ' ' ) - ; - else if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] != 'A' && isupper( pFunc->pStack[ pFunc->iStackIndex - 1 ] ) ) - hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_NOT_ARRAY, NULL, NULL ); + { + BYTE cVarType = pFunc->pStack[ pFunc->iStackIndex - 1 ]; + + if ( cVarType > 122 ) + cVarType -= 100; + + if ( cVarType == ' ' ) + { + /* Type unknown. */ + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_SUSPECT, "A", NULL ); + pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' '; + } + else if ( cVarType == 'A' ) + /* Variant Array Element - Type unknown. */ + pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' '; + else if ( cVarType == 'a' ) + /* Variant Array Element - Type unknown. */ + pFunc->pStack[ pFunc->iStackIndex - 1 ] = ' '; + else if ( islower( cVarType ) ) + /* Now we have the declared array element on the stack.*/ + pFunc->pStack[ pFunc->iStackIndex - 1 ] = toupper( cVarType ); + else + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_NOT_ARRAY, NULL, NULL ); + } - /* Now we have the array elent on the stack.*/ - pFunc->pStack[ pFunc->iStackIndex - 1 ] = toupper( pFunc->pStack[ pFunc->iStackIndex - 1 ] ); break; case HB_P_ARRAYPOP : @@ -1154,15 +1189,39 @@ void hb_compStrongType( int iSize ) /* TODO Error Message after finalizing all possible pcodes. */ break; - if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] == ' ' ) - ; - else if ( pFunc->pStack[ pFunc->iStackIndex - 1 ] != 'A' && isupper( pFunc->pStack[ pFunc->iStackIndex - 1 ] ) ) - hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_NOT_ARRAY, NULL, NULL ); - else if ( toupper( pFunc->pStack[ pFunc->iStackIndex - 1 ] ) != pFunc->pStack[ pFunc->iStackIndex - 2 ] && pFunc->pStack[ pFunc->iStackIndex - 2 ] != '-' ) { - char szType[2]; - sprintf( szType, "%c", toupper( pFunc->pStack[ pFunc->iStackIndex - 1 ] ) ); - hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_TYPE, szType, NULL ); + BYTE cVarType = pFunc->pStack[ pFunc->iStackIndex - 1 ], cElementType = pFunc->pStack[ pFunc->iStackIndex - 2 ]; + + if ( cVarType > 122 ) + cVarType -= 100; + + if ( cElementType > 122 ) + cElementType -= 100; + + if ( cVarType == ' ' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_OPERAND_SUSPECT, "A", NULL ); + else if ( cVarType == 'A' ) + /* Array of variant can hold any value. */ + ; + else if ( cVarType == 'a' ) + /* Array of variant can hold any value. */ + ; + else if ( islower( cVarType ) && cElementType == ' ' ) + { + /* Array Of explicit type. */ + char szType[2]; + sprintf( szType, "%c", toupper( cVarType ) ); + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); + } + else if ( islower( cVarType ) && toupper( cVarType ) != cElementType && cElementType != '-' ) + { + /* Array Of explicit type. */ + char szType[2]; + sprintf( szType, "%c", toupper( cVarType ) ); + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_TYPE, szType, NULL ); + } + else + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_NOT_ARRAY, NULL, NULL ); } /* Poping the Assigned Value. */ @@ -1245,6 +1304,10 @@ void hb_compStrongType( int iSize ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pSym->szName, szType ); else if ( isupper( pSym->cType ) && pSym->cType != pFunc->pStack[ pFunc->iStackIndex ] ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_TYPE, pSym->szName, szType ); + else if ( islower( pSym->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); + else if ( islower( pSym->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == 'A' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); else if ( toupper( pSym->cType ) != pFunc->pStack[ pFunc->iStackIndex ] ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_TYPE, szType, NULL ); } @@ -1298,13 +1361,17 @@ void hb_compStrongType( int iSize ) if ( pFunc->pStack[ pFunc->iStackIndex ] > 122 ) pFunc->pStack[ pFunc->iStackIndex ] -= 100; - if ( pFunc->pStack[ pFunc->iStackIndex ] == '-' ) + if ( pFunc->pStack[ pFunc->iStackIndex ] == '-' ) ; /* NIL allowed into all types */ - else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) + else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pSym->szName, szType ); - else if ( isupper( pSym->cType ) && pSym->cType != pFunc->pStack[ pFunc->iStackIndex ] ) + else if ( isupper( pSym->cType ) && pSym->cType != pFunc->pStack[ pFunc->iStackIndex ] ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_TYPE, pSym->szName, szType ); - else if ( toupper( pSym->cType ) != pFunc->pStack[ pFunc->iStackIndex ] ) + else if ( islower( pSym->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); + else if ( islower( pSym->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == 'A' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); + else if ( toupper( pSym->cType ) != pFunc->pStack[ pFunc->iStackIndex ] ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_TYPE, szType, NULL ); } } @@ -1373,6 +1440,8 @@ void hb_compStrongType( int iSize ) case HB_P_POPLOCALNEAR : pFunc->iStackIndex--; + //printf( "\nIndex: %i Type: %c\n", pFunc->iStackIndex, pFunc->pStack[ pFunc->iStackIndex ] ); + if ( pFunc->iStackIndex < 0 ) /* TODO Error Message after finalizing all possible pcodes. */ break; @@ -1407,6 +1476,8 @@ void hb_compStrongType( int iSize ) pVar->cType = pFunc->pStack[ pFunc->iStackIndex ]; else pVar->cType = pFunc->pStack[ pFunc->iStackIndex ] + 100; + + //printf( "\nAssigned: \'%c\' into Variant: %s from Index: %i Type: %c Asc: %i Chr: %c\n", pVar->cType, pVar->szName, pFunc->iStackIndex, pFunc->pStack[ pFunc->iStackIndex ], pFunc->pStack[ pFunc->iStackIndex ] + 100, pFunc->pStack[ pFunc->iStackIndex ] + 100 ); } else { @@ -1422,8 +1493,16 @@ void hb_compStrongType( int iSize ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pVar->szName, szType ); else if ( isupper( pVar->cType ) && pVar->cType != pFunc->pStack[ pFunc->iStackIndex ] ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_TYPE, pVar->szName, szType ); + else if ( islower( pVar->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); + else if ( islower( pVar->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == 'A' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); else if ( toupper( pVar->cType ) != pFunc->pStack[ pFunc->iStackIndex ] ) + { + //printf( "\nVar Type: %c Assigned Tye: %c\n", pVar->cType, pFunc->pStack[ pFunc->iStackIndex ] ); + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_TYPE, szType, NULL ); + } } } @@ -1470,8 +1549,12 @@ void hb_compStrongType( int iSize ) ; /* NIL allowed into all types */ else if ( pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_SUSPECT, pVar->szName, szType ); - else if ( pVar->cType != pFunc->pStack[ pFunc->iStackIndex ] ) + else if ( isupper( pVar->cType ) && pVar->cType != pFunc->pStack[ pFunc->iStackIndex ] ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ASSIGN_TYPE, pVar->szName, szType ); + else if ( islower( pVar->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == ' ' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); + else if ( islower( pVar->cType ) && pFunc->pStack[ pFunc->iStackIndex ] == 'A' ) + hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_SUSPECT, szType, NULL ); else if ( toupper( pVar->cType ) != pFunc->pStack[ pFunc->iStackIndex ] ) hb_compGenWarning( hb_comp_szWarnings, 'W', HB_COMP_WARN_ARRAY_ASSIGN_TYPE, szType, NULL ); }