diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index 1806e344..0679a5fb 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -154,6 +154,7 @@ static void inst_binary_name(char *binfname); static int operatorname(char *name); static int reparse_old_decl(declinfo_t *decl, int flags); static int reparse_new_decl(declinfo_t *decl, int flags); +static void check_void_decl(const declinfo_t *decl, int variable); enum { TEST_PLAIN, /* no parentheses */ @@ -1978,6 +1979,8 @@ static void declglb(declinfo_t *decl,int fpublic,int fstatic,int fstock) for (;;) { typeinfo_t *type = &decl->type; + check_void_decl(decl, TRUE); + ispublic=fpublic; if (decl->name[0]==PUBLIC_CHAR) { ispublic=TRUE; /* implicitly public variable */ @@ -3429,7 +3432,23 @@ int parse_decl(declinfo_t *decl, int flags) return parse_new_decl(decl, NULL, flags); } -void define_constructor(methodmap_t *map, methodmap_method_t *method) +static void check_void_decl(const declinfo_t *decl, int variable) +{ + if (decl->type.tag != pc_tag_void) + return; + + if (variable) { + error(144); + return; + } + + if (decl->type.numdim > 0) { + error(145); + return; + } +} + +static void define_constructor(methodmap_t *map, methodmap_method_t *method) { symbol *sym = findglb(map->name, sGLOBAL); @@ -4970,9 +4989,12 @@ static int newfunc(declinfo_t *decl, const int *thistag, int fpublic, int fstati if (symp) *symp = NULL; + check_void_decl(decl, FALSE); + if (decl->opertok) { check_operatortag(decl->opertok, decl->type.tag, decl->name); } /* if */ + /* check whether this is a function or a variable declaration */ if (!matchtoken('(')) return FALSE; @@ -5266,9 +5288,12 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag) if (!matchtoken(')')){ do { /* there are arguments; process them */ declinfo_t decl; + parse_decl(&decl, DECLFLAG_ARGUMENT|DECLFLAG_ENUMROOT); assert(decl.type.numtags > 0); + check_void_decl(&decl, TRUE); + if (decl.type.ident == iVARARGS) { assert(decl.type.numtags > 0); if ((sym->usage & uPROTOTYPED)==0) { diff --git a/sourcepawn/compiler/sc5.scp b/sourcepawn/compiler/sc5.scp index 26997dae..70ea80d7 100644 --- a/sourcepawn/compiler/sc5.scp +++ b/sourcepawn/compiler/sc5.scp @@ -187,6 +187,8 @@ static char *errmsg[] = { /*141*/ "natives, forwards, and public functions cannot return arrays\n", /*142*/ "invalid type declaration\n", /*143*/ "new-style declarations should not have \"new\"\n", +/*144*/ "void cannot be used as a variable type\n", +/*145*/ "invalid type expression\n", #else "\250\261\311\232\271k\214:\234\303bu\201fo\223\204\221\012", "\202l\224\252s\205g\353\350e\233\201(\243\250\327\274\202) \255 f\247low ea\300 \042c\343e\042\012", diff --git a/sourcepawn/compiler/tests/fail-bad-void.sp b/sourcepawn/compiler/tests/fail-bad-void.sp new file mode 100644 index 00000000..4e83660f --- /dev/null +++ b/sourcepawn/compiler/tests/fail-bad-void.sp @@ -0,0 +1,13 @@ +void[] Bad1() +{ +} + +void Bad2; + +stock Bad3(void x) +{ +} + +public main() +{ +} diff --git a/sourcepawn/compiler/tests/fail-bad-void.txt b/sourcepawn/compiler/tests/fail-bad-void.txt new file mode 100644 index 00000000..7d5d07c8 --- /dev/null +++ b/sourcepawn/compiler/tests/fail-bad-void.txt @@ -0,0 +1,3 @@ +(1) : error 145: invalid type expression +(5) : error 144: void cannot be used as a variable type +(7) : error 144: void cannot be used as a variable type