1
0
mirror of https://github.com/cc65/cc65.git synced 2025-01-10 19:29:45 +00:00

Merge remote-tracking branch 'upstream/master' into pcenginetarget

This commit is contained in:
mrdudz 2015-07-16 16:46:24 +02:00
commit 21d7729ad1
21 changed files with 614 additions and 193 deletions

View File

@ -2316,21 +2316,25 @@ Here's a list of all control commands and a description, what they do:
</verb></tscreen>
<sect1><tt>.ISMNEM, .ISMNEMONIC</tt><label id=".ISMNEMONIC"><p>
<sect1><tt>.DEFINEDMACRO</tt><label id=".DEFINEDMACRO"><p>
Builtin function. The function expects an identifier as argument in braces.
The argument is evaluated, and the function yields "true" if the identifier
is defined as an instruction mnemonic that is recognized by the assembler.
Example:
The argument is evaluated, and the function yields "true" if the identifier
has already been defined as the name of a macro. Otherwise the function yields
false. Example:
<tscreen><verb>
.if .not .ismnemonic(ina)
.macro ina
clc
adc #$01
.endmacro
.endif
.macro add foo
clc
adc foo
.endmacro
.if .definedmacro(add)
add #$01
.else
clc
adc #$01
.endif
</verb></tscreen>
@ -3158,6 +3162,23 @@ Here's a list of all control commands and a description, what they do:
the feature in more detail.
<sect1><tt>.ISMNEM, .ISMNEMONIC</tt><label id=".ISMNEMONIC"><p>
Builtin function. The function expects an identifier as argument in braces.
The argument is evaluated, and the function yields "true" if the identifier
is defined as an instruction mnemonic that is recognized by the assembler.
Example:
<tscreen><verb>
.if .not .ismnemonic(ina)
.macro ina
clc
adc #$01
.endmacro
.endif
</verb></tscreen>
<sect1><tt>.LINECONT</tt><label id=".LINECONT"><p>
Switch on or off line continuations using the backslash character

View File

@ -418,30 +418,22 @@ static ExprNode* FuncDefined (void)
static ExprNode* FuncIsMnemonic (void)
/* Handle the .ISMNEMONIC, .ISMNEM builtin function */
static ExprNode* FuncDefinedMacro (void)
/* Handle the .DEFINEDMACRO builtin function */
{
int Instr = -1;
Macro* Mac = 0;
/* Check for a macro or an instruction depending on UbiquitousIdents */
/* Check if the identifier is a macro */
if (CurTok.Tok == TOK_IDENT) {
if (UbiquitousIdents) {
/* Macros CAN be instructions, so check for them first */
if (FindMacro (&CurTok.SVal) == 0) {
Instr = FindInstruction (&CurTok.SVal);
}
} else {
/* Macros and symbols may NOT use the names of instructions, so just check for the instruction */
Instr = FindInstruction (&CurTok.SVal);
}
Mac = FindMacro (&CurTok.SVal);
} else {
Error ("Identifier expected.");
}
/* Skip the name */
NextTok ();
return GenLiteralExpr (Instr > 0);
return GenLiteralExpr (Mac != 0);
}
@ -462,6 +454,36 @@ static ExprNode* FuncHiWord (void)
static ExprNode* FuncIsMnemonic (void)
/* Handle the .ISMNEMONIC, .ISMNEM builtin function */
{
int Instr = -1;
/* Check for a macro or an instruction depending on UbiquitousIdents */
if (CurTok.Tok == TOK_IDENT) {
if (UbiquitousIdents) {
/* Macros CAN be instructions, so check for them first */
if (FindMacro (&CurTok.SVal) == 0) {
Instr = FindInstruction (&CurTok.SVal);
}
}
else {
/* Macros and symbols may NOT use the names of instructions, so just check for the instruction */
Instr = FindInstruction (&CurTok.SVal);
}
}
else {
Error ("Identifier expected.");
}
/* Skip the name */
NextTok ();
return GenLiteralExpr (Instr > 0);
}
ExprNode* FuncLoByte (void)
/* Handle the .LOBYTE builtin function */
{
@ -1094,8 +1116,8 @@ static ExprNode* Factor (void)
N = Function (FuncDefined);
break;
case TOK_ISMNEMONIC:
N = Function (FuncIsMnemonic);
case TOK_DEFINEDMACRO:
N = Function (FuncDefinedMacro);
break;
case TOK_HIBYTE:
@ -1106,6 +1128,10 @@ static ExprNode* Factor (void)
N = Function (FuncHiWord);
break;
case TOK_ISMNEMONIC:
N = Function (FuncIsMnemonic);
break;
case TOK_LOBYTE:
N = Function (FuncLoByte);
break;

View File

@ -83,3 +83,4 @@ unsigned char CComments = 0; /* Allow C like comments */
unsigned char ForceRange = 0; /* Force values into expected range */
unsigned char UnderlineInNumbers = 0; /* Allow underlines in numbers */
unsigned char AddrSize = 0; /* Allow .ADDRSIZE function */

View File

@ -1989,6 +1989,7 @@ static CtrlDesc CtrlCmdTab [] = {
{ ccNone, DoDebugInfo },
{ ccNone, DoDefine },
{ ccNone, DoUnexpected }, /* .DEFINED */
{ ccNone, DoUnexpected }, /* .DEFINEDMACRO */
{ ccNone, DoDelMac },
{ ccNone, DoDestructor },
{ ccNone, DoDWord },

View File

@ -132,165 +132,166 @@ struct DotKeyword {
const char* Key; /* MUST be first field */
token_t Tok;
} DotKeywords [] = {
{ ".A16", TOK_A16 },
{ ".A8", TOK_A8 },
{ ".ADDR", TOK_ADDR },
{ ".ADDRSIZE", TOK_ADDRSIZE },
{ ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BOOLAND },
{ ".ASCIIZ", TOK_ASCIIZ },
{ ".ASSERT", TOK_ASSERT },
{ ".AUTOIMPORT", TOK_AUTOIMPORT },
{ ".BANK", TOK_BANK },
{ ".BANKBYTE", TOK_BANKBYTE },
{ ".BANKBYTES", TOK_BANKBYTES },
{ ".BITAND", TOK_AND },
{ ".BITNOT", TOK_NOT },
{ ".BITOR", TOK_OR },
{ ".BITXOR", TOK_XOR },
{ ".BLANK", TOK_BLANK },
{ ".BSS", TOK_BSS },
{ ".BYT", TOK_BYTE },
{ ".BYTE", TOK_BYTE },
{ ".CASE", TOK_CASE },
{ ".CHARMAP", TOK_CHARMAP },
{ ".CODE", TOK_CODE },
{ ".CONCAT", TOK_CONCAT },
{ ".CONDES", TOK_CONDES },
{ ".CONST", TOK_CONST },
{ ".CONSTRUCTOR", TOK_CONSTRUCTOR },
{ ".CPU", TOK_CPU },
{ ".DATA", TOK_DATA },
{ ".DBG", TOK_DBG },
{ ".DBYT", TOK_DBYT },
{ ".DEBUGINFO", TOK_DEBUGINFO },
{ ".DEF", TOK_DEFINED },
{ ".DEFINE", TOK_DEFINE },
{ ".DEFINED", TOK_DEFINED },
{ ".DELMAC", TOK_DELMAC },
{ ".DELMACRO", TOK_DELMAC },
{ ".DESTRUCTOR", TOK_DESTRUCTOR },
{ ".DWORD", TOK_DWORD },
{ ".ELSE", TOK_ELSE },
{ ".ELSEIF", TOK_ELSEIF },
{ ".END", TOK_END },
{ ".ENDENUM", TOK_ENDENUM },
{ ".ENDIF", TOK_ENDIF },
{ ".ENDMAC", TOK_ENDMACRO },
{ ".ENDMACRO", TOK_ENDMACRO },
{ ".ENDPROC", TOK_ENDPROC },
{ ".ENDREP", TOK_ENDREP },
{ ".ENDREPEAT", TOK_ENDREP },
{ ".ENDSCOPE", TOK_ENDSCOPE },
{ ".ENDSTRUCT", TOK_ENDSTRUCT },
{ ".ENDUNION", TOK_ENDUNION },
{ ".ENUM", TOK_ENUM },
{ ".ERROR", TOK_ERROR },
{ ".EXITMAC", TOK_EXITMACRO },
{ ".EXITMACRO", TOK_EXITMACRO },
{ ".EXPORT", TOK_EXPORT },
{ ".EXPORTZP", TOK_EXPORTZP },
{ ".FARADDR", TOK_FARADDR },
{ ".FATAL", TOK_FATAL },
{ ".FEATURE", TOK_FEATURE },
{ ".FILEOPT", TOK_FILEOPT },
{ ".FOPT", TOK_FILEOPT },
{ ".FORCEIMPORT", TOK_FORCEIMPORT },
{ ".FORCEWORD", TOK_FORCEWORD },
{ ".GLOBAL", TOK_GLOBAL },
{ ".GLOBALZP", TOK_GLOBALZP },
{ ".HIBYTE", TOK_HIBYTE },
{ ".HIBYTES", TOK_HIBYTES },
{ ".HIWORD", TOK_HIWORD },
{ ".I16", TOK_I16 },
{ ".I8", TOK_I8 },
{ ".IDENT", TOK_MAKEIDENT },
{ ".IF", TOK_IF },
{ ".IFBLANK", TOK_IFBLANK },
{ ".IFCONST", TOK_IFCONST },
{ ".IFDEF", TOK_IFDEF },
{ ".IFNBLANK", TOK_IFNBLANK },
{ ".IFNCONST", TOK_IFNCONST },
{ ".IFNDEF", TOK_IFNDEF },
{ ".IFNREF", TOK_IFNREF },
{ ".IFP02", TOK_IFP02 },
{ ".IFP816", TOK_IFP816 },
{ ".IFPC02", TOK_IFPC02 },
{ ".IFPSC02", TOK_IFPSC02 },
{ ".IFREF", TOK_IFREF },
{ ".IMPORT", TOK_IMPORT },
{ ".IMPORTZP", TOK_IMPORTZP },
{ ".INCBIN", TOK_INCBIN },
{ ".INCLUDE", TOK_INCLUDE },
{ ".INTERRUPTOR", TOK_INTERRUPTOR },
{ ".ISMNEM", TOK_ISMNEMONIC },
{ ".ISMNEMONIC", TOK_ISMNEMONIC },
{ ".LEFT", TOK_LEFT },
{ ".LINECONT", TOK_LINECONT },
{ ".LIST", TOK_LIST },
{ ".LISTBYTES", TOK_LISTBYTES },
{ ".LOBYTE", TOK_LOBYTE },
{ ".LOBYTES", TOK_LOBYTES },
{ ".LOCAL", TOK_LOCAL },
{ ".LOCALCHAR", TOK_LOCALCHAR },
{ ".LOWORD", TOK_LOWORD },
{ ".MAC", TOK_MACRO },
{ ".MACPACK", TOK_MACPACK },
{ ".MACRO", TOK_MACRO },
{ ".MATCH", TOK_MATCH },
{ ".MAX", TOK_MAX },
{ ".MID", TOK_MID },
{ ".MIN", TOK_MIN },
{ ".MOD", TOK_MOD },
{ ".NOT", TOK_BOOLNOT },
{ ".NULL", TOK_NULL },
{ ".OR", TOK_BOOLOR },
{ ".ORG", TOK_ORG },
{ ".OUT", TOK_OUT },
{ ".P02", TOK_P02 },
{ ".P816", TOK_P816 },
{ ".PAGELEN", TOK_PAGELENGTH },
{ ".PAGELENGTH", TOK_PAGELENGTH },
{ ".PARAMCOUNT", TOK_PARAMCOUNT },
{ ".PC02", TOK_PC02 },
{ ".POPCPU", TOK_POPCPU },
{ ".POPSEG", TOK_POPSEG },
{ ".PROC", TOK_PROC },
{ ".PSC02", TOK_PSC02 },
{ ".PUSHCPU", TOK_PUSHCPU },
{ ".PUSHSEG", TOK_PUSHSEG },
{ ".REF", TOK_REFERENCED },
{ ".REFERENCED", TOK_REFERENCED },
{ ".RELOC", TOK_RELOC },
{ ".REPEAT", TOK_REPEAT },
{ ".RES", TOK_RES },
{ ".RIGHT", TOK_RIGHT },
{ ".RODATA", TOK_RODATA },
{ ".SCOPE", TOK_SCOPE },
{ ".SEGMENT", TOK_SEGMENT },
{ ".SET", TOK_SET },
{ ".SETCPU", TOK_SETCPU },
{ ".SHL", TOK_SHL },
{ ".SHR", TOK_SHR },
{ ".SIZEOF", TOK_SIZEOF },
{ ".SMART", TOK_SMART },
{ ".SPRINTF", TOK_SPRINTF },
{ ".STRAT", TOK_STRAT },
{ ".STRING", TOK_STRING },
{ ".STRLEN", TOK_STRLEN },
{ ".STRUCT", TOK_STRUCT },
{ ".TAG", TOK_TAG },
{ ".TCOUNT", TOK_TCOUNT },
{ ".TIME", TOK_TIME },
{ ".UNDEF", TOK_UNDEF },
{ ".UNDEFINE", TOK_UNDEF },
{ ".UNION", TOK_UNION },
{ ".VERSION", TOK_VERSION },
{ ".WARNING", TOK_WARNING },
{ ".WORD", TOK_WORD },
{ ".XMATCH", TOK_XMATCH },
{ ".XOR", TOK_BOOLXOR },
{ ".ZEROPAGE", TOK_ZEROPAGE },
{ ".A16", TOK_A16 },
{ ".A8", TOK_A8 },
{ ".ADDR", TOK_ADDR },
{ ".ADDRSIZE", TOK_ADDRSIZE },
{ ".ALIGN", TOK_ALIGN },
{ ".AND", TOK_BOOLAND },
{ ".ASCIIZ", TOK_ASCIIZ },
{ ".ASSERT", TOK_ASSERT },
{ ".AUTOIMPORT", TOK_AUTOIMPORT },
{ ".BANK", TOK_BANK },
{ ".BANKBYTE", TOK_BANKBYTE },
{ ".BANKBYTES", TOK_BANKBYTES },
{ ".BITAND", TOK_AND },
{ ".BITNOT", TOK_NOT },
{ ".BITOR", TOK_OR },
{ ".BITXOR", TOK_XOR },
{ ".BLANK", TOK_BLANK },
{ ".BSS", TOK_BSS },
{ ".BYT", TOK_BYTE },
{ ".BYTE", TOK_BYTE },
{ ".CASE", TOK_CASE },
{ ".CHARMAP", TOK_CHARMAP },
{ ".CODE", TOK_CODE },
{ ".CONCAT", TOK_CONCAT },
{ ".CONDES", TOK_CONDES },
{ ".CONST", TOK_CONST },
{ ".CONSTRUCTOR", TOK_CONSTRUCTOR },
{ ".CPU", TOK_CPU },
{ ".DATA", TOK_DATA },
{ ".DBG", TOK_DBG },
{ ".DBYT", TOK_DBYT },
{ ".DEBUGINFO", TOK_DEBUGINFO },
{ ".DEF", TOK_DEFINED },
{ ".DEFINE", TOK_DEFINE },
{ ".DEFINED", TOK_DEFINED },
{ ".DEFINEDMACRO", TOK_DEFINEDMACRO },
{ ".DELMAC", TOK_DELMAC },
{ ".DELMACRO", TOK_DELMAC },
{ ".DESTRUCTOR", TOK_DESTRUCTOR },
{ ".DWORD", TOK_DWORD },
{ ".ELSE", TOK_ELSE },
{ ".ELSEIF", TOK_ELSEIF },
{ ".END", TOK_END },
{ ".ENDENUM", TOK_ENDENUM },
{ ".ENDIF", TOK_ENDIF },
{ ".ENDMAC", TOK_ENDMACRO },
{ ".ENDMACRO", TOK_ENDMACRO },
{ ".ENDPROC", TOK_ENDPROC },
{ ".ENDREP", TOK_ENDREP },
{ ".ENDREPEAT", TOK_ENDREP },
{ ".ENDSCOPE", TOK_ENDSCOPE },
{ ".ENDSTRUCT", TOK_ENDSTRUCT },
{ ".ENDUNION", TOK_ENDUNION },
{ ".ENUM", TOK_ENUM },
{ ".ERROR", TOK_ERROR },
{ ".EXITMAC", TOK_EXITMACRO },
{ ".EXITMACRO", TOK_EXITMACRO },
{ ".EXPORT", TOK_EXPORT },
{ ".EXPORTZP", TOK_EXPORTZP },
{ ".FARADDR", TOK_FARADDR },
{ ".FATAL", TOK_FATAL },
{ ".FEATURE", TOK_FEATURE },
{ ".FILEOPT", TOK_FILEOPT },
{ ".FOPT", TOK_FILEOPT },
{ ".FORCEIMPORT", TOK_FORCEIMPORT },
{ ".FORCEWORD", TOK_FORCEWORD },
{ ".GLOBAL", TOK_GLOBAL },
{ ".GLOBALZP", TOK_GLOBALZP },
{ ".HIBYTE", TOK_HIBYTE },
{ ".HIBYTES", TOK_HIBYTES },
{ ".HIWORD", TOK_HIWORD },
{ ".I16", TOK_I16 },
{ ".I8", TOK_I8 },
{ ".IDENT", TOK_MAKEIDENT },
{ ".IF", TOK_IF },
{ ".IFBLANK", TOK_IFBLANK },
{ ".IFCONST", TOK_IFCONST },
{ ".IFDEF", TOK_IFDEF },
{ ".IFNBLANK", TOK_IFNBLANK },
{ ".IFNCONST", TOK_IFNCONST },
{ ".IFNDEF", TOK_IFNDEF },
{ ".IFNREF", TOK_IFNREF },
{ ".IFP02", TOK_IFP02 },
{ ".IFP816", TOK_IFP816 },
{ ".IFPC02", TOK_IFPC02 },
{ ".IFPSC02", TOK_IFPSC02 },
{ ".IFREF", TOK_IFREF },
{ ".IMPORT", TOK_IMPORT },
{ ".IMPORTZP", TOK_IMPORTZP },
{ ".INCBIN", TOK_INCBIN },
{ ".INCLUDE", TOK_INCLUDE },
{ ".INTERRUPTOR", TOK_INTERRUPTOR },
{ ".ISMNEM", TOK_ISMNEMONIC },
{ ".ISMNEMONIC", TOK_ISMNEMONIC },
{ ".LEFT", TOK_LEFT },
{ ".LINECONT", TOK_LINECONT },
{ ".LIST", TOK_LIST },
{ ".LISTBYTES", TOK_LISTBYTES },
{ ".LOBYTE", TOK_LOBYTE },
{ ".LOBYTES", TOK_LOBYTES },
{ ".LOCAL", TOK_LOCAL },
{ ".LOCALCHAR", TOK_LOCALCHAR },
{ ".LOWORD", TOK_LOWORD },
{ ".MAC", TOK_MACRO },
{ ".MACPACK", TOK_MACPACK },
{ ".MACRO", TOK_MACRO },
{ ".MATCH", TOK_MATCH },
{ ".MAX", TOK_MAX },
{ ".MID", TOK_MID },
{ ".MIN", TOK_MIN },
{ ".MOD", TOK_MOD },
{ ".NOT", TOK_BOOLNOT },
{ ".NULL", TOK_NULL },
{ ".OR", TOK_BOOLOR },
{ ".ORG", TOK_ORG },
{ ".OUT", TOK_OUT },
{ ".P02", TOK_P02 },
{ ".P816", TOK_P816 },
{ ".PAGELEN", TOK_PAGELENGTH },
{ ".PAGELENGTH", TOK_PAGELENGTH },
{ ".PARAMCOUNT", TOK_PARAMCOUNT },
{ ".PC02", TOK_PC02 },
{ ".POPCPU", TOK_POPCPU },
{ ".POPSEG", TOK_POPSEG },
{ ".PROC", TOK_PROC },
{ ".PSC02", TOK_PSC02 },
{ ".PUSHCPU", TOK_PUSHCPU },
{ ".PUSHSEG", TOK_PUSHSEG },
{ ".REF", TOK_REFERENCED },
{ ".REFERENCED", TOK_REFERENCED },
{ ".RELOC", TOK_RELOC },
{ ".REPEAT", TOK_REPEAT },
{ ".RES", TOK_RES },
{ ".RIGHT", TOK_RIGHT },
{ ".RODATA", TOK_RODATA },
{ ".SCOPE", TOK_SCOPE },
{ ".SEGMENT", TOK_SEGMENT },
{ ".SET", TOK_SET },
{ ".SETCPU", TOK_SETCPU },
{ ".SHL", TOK_SHL },
{ ".SHR", TOK_SHR },
{ ".SIZEOF", TOK_SIZEOF },
{ ".SMART", TOK_SMART },
{ ".SPRINTF", TOK_SPRINTF },
{ ".STRAT", TOK_STRAT },
{ ".STRING", TOK_STRING },
{ ".STRLEN", TOK_STRLEN },
{ ".STRUCT", TOK_STRUCT },
{ ".TAG", TOK_TAG },
{ ".TCOUNT", TOK_TCOUNT },
{ ".TIME", TOK_TIME },
{ ".UNDEF", TOK_UNDEF },
{ ".UNDEFINE", TOK_UNDEF },
{ ".UNION", TOK_UNION },
{ ".VERSION", TOK_VERSION },
{ ".WARNING", TOK_WARNING },
{ ".WORD", TOK_WORD },
{ ".XMATCH", TOK_XMATCH },
{ ".XOR", TOK_BOOLXOR },
{ ".ZEROPAGE", TOK_ZEROPAGE },
};

View File

@ -148,6 +148,7 @@ typedef enum token_t {
TOK_DEBUGINFO,
TOK_DEFINE,
TOK_DEFINED,
TOK_DEFINEDMACRO,
TOK_DELMAC,
TOK_DESTRUCTOR,
TOK_DWORD,

View File

@ -391,6 +391,12 @@ unsigned SizeOf (const Type* T)
case T_VOID:
return 0; /* Assume voids have size zero */
/* Beware: There's a chance that this triggers problems in other parts
of the compiler. The solution is to fix the callers, because calling
SizeOf() with a function type as argument is bad. */
case T_FUNC:
return 0; /* Size of function is unknown */
case T_SCHAR:
case T_UCHAR:
return SIZEOF_CHAR;
@ -404,7 +410,6 @@ unsigned SizeOf (const Type* T)
return SIZEOF_INT;
case T_PTR:
case T_FUNC: /* Maybe pointer to function */
return SIZEOF_PTR;
case T_LONG:

View File

@ -50,6 +50,7 @@
/* Generator attributes */
#define GEN_NOPUSH 0x01 /* Don't push lhs */
#define GEN_COMM 0x02 /* Operator is commutative */
#define GEN_NOFUNC 0x04 /* Not allowed for function pointers */
/* Map a generator function and its attributes to a token */
typedef struct {
@ -2042,6 +2043,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
Tok = CurTok.Tok;
NextToken ();
/* If lhs is a function, convert it to pointer to function */
if (IsTypeFunc (Expr->Type)) {
Expr->Type = PointerTo (Expr->Type);
}
/* Get the lhs on stack */
GetCodePos (&Mark1);
ltype = TypeOf (Expr->Type);
@ -2059,6 +2065,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
/* Get the right hand side */
MarkedExprWithCheck (hienext, &Expr2);
/* If rhs is a function, convert it to pointer to function */
if (IsTypeFunc (Expr2.Type)) {
Expr2.Type = PointerTo (Expr2.Type);
}
/* Check for a constant expression */
rconst = (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2));
if (!rconst) {
@ -2066,6 +2077,22 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
LoadExpr (CF_NONE, &Expr2);
}
/* Some operations aren't allowed on function pointers */
if ((Gen->Flags & GEN_NOFUNC) != 0) {
/* Output only one message even if both sides are wrong */
if (IsTypeFuncPtr (Expr->Type)) {
Error ("Invalid left operand for relational operator");
/* Avoid further errors */
ED_MakeConstAbsInt (Expr, 0);
ED_MakeConstAbsInt (&Expr2, 0);
} else if (IsTypeFuncPtr (Expr2.Type)) {
Error ("Invalid right operand for relational operator");
/* Avoid further errors */
ED_MakeConstAbsInt (Expr, 0);
ED_MakeConstAbsInt (&Expr2, 0);
}
}
/* Make sure, the types are compatible */
if (IsClassInt (Expr->Type)) {
if (!IsClassInt (Expr2.Type) && !(IsClassPtr(Expr2.Type) && ED_IsNullPtr(Expr))) {
@ -2600,6 +2627,13 @@ static void parsesub (ExprDesc* Expr)
int rscale; /* Scale factor for the result */
/* lhs cannot be function or pointer to function */
if (IsTypeFunc (Expr->Type) || IsTypeFuncPtr (Expr->Type)) {
Error ("Invalid left operand for binary operator `-'");
/* Make it pointer to char to avoid further errors */
Expr->Type = type_uchar;
}
/* Skip the MINUS token */
NextToken ();
@ -2616,6 +2650,13 @@ static void parsesub (ExprDesc* Expr)
/* Parse the right hand side */
MarkedExprWithCheck (hie9, &Expr2);
/* rhs cannot be function or pointer to function */
if (IsTypeFunc (Expr2.Type) || IsTypeFuncPtr (Expr2.Type)) {
Error ("Invalid right operand for binary operator `-'");
/* Make it pointer to char to avoid further errors */
Expr2.Type = type_uchar;
}
/* Check for a constant rhs expression */
if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
@ -2775,11 +2816,11 @@ static void hie6 (ExprDesc* Expr)
/* Handle greater-than type comparators */
{
static const GenDesc hie6_ops [] = {
{ TOK_LT, GEN_NOPUSH, g_lt },
{ TOK_LE, GEN_NOPUSH, g_le },
{ TOK_GE, GEN_NOPUSH, g_ge },
{ TOK_GT, GEN_NOPUSH, g_gt },
{ TOK_INVALID, 0, 0 }
{ TOK_LT, GEN_NOPUSH | GEN_NOFUNC, g_lt },
{ TOK_LE, GEN_NOPUSH | GEN_NOFUNC, g_le },
{ TOK_GE, GEN_NOPUSH | GEN_NOFUNC, g_ge },
{ TOK_GT, GEN_NOPUSH | GEN_NOFUNC, g_gt },
{ TOK_INVALID, 0, 0 }
};
hie_compare (hie6_ops, Expr, ShiftExpr);
}

View File

@ -18,7 +18,7 @@ else
EXE :=
DEL = $(RM) $1
MKDIR = mkdir $1
RMDIR = rmdir $1
RMDIR = $(RM) -r $1
endif
WORKDIR := ../testwrk

26
test/err/cc65150311-1.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
++p; /* invalid C */
return 0;
}

26
test/err/cc65150311-10.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = &func - p; /* invalid C */
return 0;
}

26
test/err/cc65150311-11.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = func - p; /* invalid C */
return 0;
}

26
test/err/cc65150311-2.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = (p > &func); /* invalid C */
return 0;
}

26
test/err/cc65150311-3.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = (p > func); /* invalid C */
return 0;
}

26
test/err/cc65150311-4.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = func - func; /* invalid C */
return 0;
}

26
test/err/cc65150311-5.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = func - &func; /* invalid C */
return 0;
}

26
test/err/cc65150311-6.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = &func - func; /* invalid C */
return 0;
}

26
test/err/cc65150311-7.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = &func - &func; /* invalid C */
return 0;
}

26
test/err/cc65150311-8.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = p - &func; /* invalid C */
return 0;
}

26
test/err/cc65150311-9.c Normal file
View File

@ -0,0 +1,26 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
n = p - func; /* invalid C */
return 0;
}

38
test/val/cc65150311.c Normal file
View File

@ -0,0 +1,38 @@
/*
!!DESCRIPTION!! function pointer bugs
!!ORIGIN!! testsuite
!!LICENCE!! Public Domain
!!AUTHOR!! Greg
*/
/*
see: http://www.cc65.org/mailarchive/2015-03/11726.html
and: http://www.cc65.org/mailarchive/2015-03/11734.html
*/
static int func(void) {return 0;}
static int (*p)(void);
static int n;
int main(void) {
p = func;
n = (p == &func);
n = (p == func);
/* the following are not valid C and should go into seperate tests that MUST fail */
/*
++p;
n = (p > &func);
n = (p > func);
n = func - func;
n = func - &func;
n = &func - func;
n = &func - &func;
n = p - &func;
n = p - func;
n = &func - p;
n = func - p;
*/
return 0;
}