Define post-fix arrays as determinate and pre-fix arrays as indeterminate.
This commit is contained in:
parent
a8796543af
commit
70e095f320
@ -70,7 +70,7 @@ native void WritePackFloat(Handle pack, float val);
|
|||||||
* @noreturn
|
* @noreturn
|
||||||
* @error Invalid handle.
|
* @error Invalid handle.
|
||||||
*/
|
*/
|
||||||
native void WritePackString(Handle pack, const char str[]);
|
native void WritePackString(Handle pack, const char[] str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Packs a function pointer into a data pack.
|
* Packs a function pointer into a data pack.
|
||||||
@ -109,7 +109,7 @@ native float ReadPackFloat(Handle pack);
|
|||||||
* @noreturn
|
* @noreturn
|
||||||
* @error Invalid handle, or bounds error.
|
* @error Invalid handle, or bounds error.
|
||||||
*/
|
*/
|
||||||
native void ReadPackString(Handle pack, char buffer[], maxlen);
|
native void ReadPackString(Handle pack, char[] buffer, maxlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a function pointer from a data pack.
|
* Reads a function pointer from a data pack.
|
||||||
|
@ -614,6 +614,17 @@ static void inst_datetime_defines(void)
|
|||||||
insert_subst("__TIME__", ltime, 8);
|
insert_subst("__TIME__", ltime, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *pc_typename(int tag)
|
||||||
|
{
|
||||||
|
if (tag == 0)
|
||||||
|
return "int";
|
||||||
|
if (tag == sc_rationaltag)
|
||||||
|
return "float";
|
||||||
|
if (tag == pc_tag_string)
|
||||||
|
return "char";
|
||||||
|
return pc_tagname(tag);
|
||||||
|
}
|
||||||
|
|
||||||
const char *pc_tagname(int tag)
|
const char *pc_tagname(int tag)
|
||||||
{
|
{
|
||||||
constvalue *ptr=tagname_tab.next;
|
constvalue *ptr=tagname_tab.next;
|
||||||
@ -1985,6 +1996,11 @@ static void declglb(declinfo_t *decl,int fpublic,int fstatic,int fstock)
|
|||||||
litidx=0; /* global initial data is dumped, so restart at zero */
|
litidx=0; /* global initial data is dumped, so restart at zero */
|
||||||
} /* if */
|
} /* if */
|
||||||
assert(litidx==0); /* literal queue should be empty (again) */
|
assert(litidx==0); /* literal queue should be empty (again) */
|
||||||
|
if (type->ident == iREFARRAY) {
|
||||||
|
// Dynamc array in global scope.
|
||||||
|
assert(type->is_new);
|
||||||
|
error(162);
|
||||||
|
}
|
||||||
initials3(decl);
|
initials3(decl);
|
||||||
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1]) {
|
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1]) {
|
||||||
slength = glbstringread;
|
slength = glbstringread;
|
||||||
@ -2038,6 +2054,25 @@ static void declglb(declinfo_t *decl,int fpublic,int fstatic,int fstock)
|
|||||||
needtoken(tTERM); /* if not comma, must be semicolumn */
|
needtoken(tTERM); /* if not comma, must be semicolumn */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_local_array_initializer(typeinfo_t *type, int *curlit, int *slength)
|
||||||
|
{
|
||||||
|
if (sc_alignnext) {
|
||||||
|
aligndata(sc_dataalign);
|
||||||
|
sc_alignnext=FALSE;
|
||||||
|
} /* if */
|
||||||
|
*curlit = litidx; /* save current index in the literal table */
|
||||||
|
if (type->numdim && !type->dim[type->numdim-1])
|
||||||
|
type->size = 0;
|
||||||
|
initials(type->ident,type->tag,&type->size,type->dim,type->numdim,type->enumroot);
|
||||||
|
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1])
|
||||||
|
*slength = glbstringread;
|
||||||
|
if (type->size == 0)
|
||||||
|
return false;
|
||||||
|
if (type->numdim == 1)
|
||||||
|
type->dim[0] = type->size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* declloc - declare local symbols
|
/* declloc - declare local symbols
|
||||||
*
|
*
|
||||||
* Declare local (automatic) variables. Since these variables are relative
|
* Declare local (automatic) variables. Since these variables are relative
|
||||||
@ -2092,20 +2127,8 @@ static void declloc(int tokid)
|
|||||||
slength = fix_char_size(&decl);
|
slength = fix_char_size(&decl);
|
||||||
|
|
||||||
if (type->ident == iARRAY || fstatic) {
|
if (type->ident == iARRAY || fstatic) {
|
||||||
if (sc_alignnext) {
|
if (!parse_local_array_initializer(type, &cur_lit, &slength))
|
||||||
aligndata(sc_dataalign);
|
|
||||||
sc_alignnext=FALSE;
|
|
||||||
} /* if */
|
|
||||||
cur_lit=litidx; /* save current index in the literal table */
|
|
||||||
if (type->numdim && !type->dim[type->numdim-1])
|
|
||||||
type->size = 0;
|
|
||||||
initials(type->ident,type->tag,&type->size,type->dim,type->numdim,type->enumroot);
|
|
||||||
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1])
|
|
||||||
slength = glbstringread;
|
|
||||||
if (type->size == 0)
|
|
||||||
return;
|
return;
|
||||||
if (type->numdim == 1)
|
|
||||||
type->dim[0] = type->size;
|
|
||||||
}
|
}
|
||||||
/* reserve memory (on the stack) for the variable */
|
/* reserve memory (on the stack) for the variable */
|
||||||
if (fstatic) {
|
if (fstatic) {
|
||||||
@ -2132,6 +2155,17 @@ static void declloc(int tokid)
|
|||||||
if (curfunc->x.stacksize<declared+1)
|
if (curfunc->x.stacksize<declared+1)
|
||||||
curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */
|
curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */
|
||||||
} else if (type->ident == iREFARRAY) {
|
} else if (type->ident == iREFARRAY) {
|
||||||
|
if (matchtoken('=')) {
|
||||||
|
if (lexpeek('{')) {
|
||||||
|
// Dynamic array with fixed initializer.
|
||||||
|
error(160);
|
||||||
|
|
||||||
|
// Parse just to clear the tokens. First give '=' back.
|
||||||
|
lexpush();
|
||||||
|
if (!parse_local_array_initializer(type, &cur_lit, &slength))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
declared+=1; /* one cell for address */
|
declared+=1; /* one cell for address */
|
||||||
sym=addvariable(decl.name,-declared*sizeof(cell),type->ident,sLOCAL,type->tag,type->dim,type->numdim,type->idxtag);
|
sym=addvariable(decl.name,-declared*sizeof(cell),type->ident,sLOCAL,type->tag,type->dim,type->numdim,type->idxtag);
|
||||||
//markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
|
//markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
|
||||||
@ -3035,7 +3069,7 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
|||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
} while (matchtoken('['));
|
} while (matchtoken('['));
|
||||||
type->ident = iARRAY;
|
type->ident = iREFARRAY;
|
||||||
type->size = 0;
|
type->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3146,6 +3180,10 @@ static void parse_old_array_dims(declinfo_t *decl, int flags)
|
|||||||
genarray(type->numdim, autozero);
|
genarray(type->numdim, autozero);
|
||||||
type->ident = iREFARRAY;
|
type->ident = iREFARRAY;
|
||||||
type->size = 0;
|
type->size = 0;
|
||||||
|
if (type->is_new) {
|
||||||
|
// Fixed array with dynamic size.
|
||||||
|
error(161, pc_typename(type->tag));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stgout(staging_index);
|
stgout(staging_index);
|
||||||
@ -3301,6 +3339,8 @@ static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decl->type.is_new = TRUE;
|
||||||
|
|
||||||
if (flags & DECLMASK_NAMED_DECL) {
|
if (flags & DECLMASK_NAMED_DECL) {
|
||||||
if (matchtoken('[')) {
|
if (matchtoken('[')) {
|
||||||
if (decl->type.numdim == 0)
|
if (decl->type.numdim == 0)
|
||||||
@ -3310,7 +3350,6 @@ static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decl->type.is_new = TRUE;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5606,6 +5645,9 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
int slength=0;
|
int slength=0;
|
||||||
typeinfo_t *type = &decl->type;
|
typeinfo_t *type = &decl->type;
|
||||||
|
|
||||||
|
// Otherwise we get very weird line number ranges, anything to the current fline.
|
||||||
|
errorset(sEXPRMARK,0);
|
||||||
|
|
||||||
strcpy(arg->name, decl->name);
|
strcpy(arg->name, decl->name);
|
||||||
arg->hasdefault=FALSE; /* preset (most common case) */
|
arg->hasdefault=FALSE; /* preset (most common case) */
|
||||||
arg->defvalue.val=0; /* clear */
|
arg->defvalue.val=0; /* clear */
|
||||||
@ -5641,6 +5683,10 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (type->is_new && !type->has_postdims && lexpeek('{')) {
|
||||||
|
// Dynamic array with fixed initializer.
|
||||||
|
error(160);
|
||||||
|
}
|
||||||
initials2(type->ident, type->tags[0], &type->size, arg->dim, arg->numdim, type->enumroot, 1, 0);
|
initials2(type->ident, type->tags[0], &type->size, arg->dim, arg->numdim, type->enumroot, 1, 0);
|
||||||
assert(type->size >= litidx);
|
assert(type->size >= litidx);
|
||||||
/* allocate memory to hold the initial values */
|
/* allocate memory to hold the initial values */
|
||||||
@ -5660,7 +5706,17 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
} /* if */
|
} /* if */
|
||||||
litidx=0; /* reset */
|
litidx=0; /* reset */
|
||||||
}
|
}
|
||||||
} /* if */
|
} else {
|
||||||
|
if (type->is_new && type->has_postdims) {
|
||||||
|
for (int i = 0; i < type->numdim; i++) {
|
||||||
|
if (type->dim[i] <= 0) {
|
||||||
|
// Fixed-array with unknown size.
|
||||||
|
error(159);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (matchtoken('=')) {
|
if (matchtoken('=')) {
|
||||||
unsigned char size_tag_token;
|
unsigned char size_tag_token;
|
||||||
@ -5729,6 +5785,8 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
if (type->usage & uCONST)
|
if (type->usage & uCONST)
|
||||||
argsym->usage|=uCONST;
|
argsym->usage|=uCONST;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
|
errorset(sEXPRRELEASE,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int count_referrers(symbol *entry)
|
static int count_referrers(symbol *entry)
|
||||||
|
@ -202,6 +202,10 @@ static const char *errmsg[] = {
|
|||||||
/*156*/ "unused156\n",
|
/*156*/ "unused156\n",
|
||||||
/*157*/ "'%s' is a reserved keyword\n",
|
/*157*/ "'%s' is a reserved keyword\n",
|
||||||
/*158*/ "multi-tags are no longer supported\n",
|
/*158*/ "multi-tags are no longer supported\n",
|
||||||
|
/*159*/ "brackets after variable name indicate a fixed-size array, but size could not be determined - either specify sizes, an array initializer, or use dynamic syntax (such as 'char[] x')\n",
|
||||||
|
/*160*/ "brackets in between type and variable name indicate a dynamic-size array, but a fixed-size initializer was given\n",
|
||||||
|
/*161*/ "brackets after variable name indicate a fixed-size array, but a dynamic size was given - did you mean to use 'new %s[size]' syntax?\n",
|
||||||
|
/*162*/ "cannot create dynamic arrays in global scope - did you mean to create a fixed-length array with brackets after the variable name?\n",
|
||||||
#else
|
#else
|
||||||
"\315e\306\227\266k\217:\235\277bu\201fo\220\204\223\012",
|
"\315e\306\227\266k\217:\235\277bu\201fo\220\204\223\012",
|
||||||
"\202l\224\250s\205g\346\356e\233\201(\243\315\214\267\202) \253 f\255low ea\305 \042c\353e\042\012",
|
"\202l\224\250s\205g\346\356e\233\201(\243\315\214\267\202) \253 f\255low ea\305 \042c\353e\042\012",
|
||||||
|
16
sourcepawn/compiler/tests/fail-bad-array-decls.sp
Normal file
16
sourcepawn/compiler/tests/fail-bad-array-decls.sp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
int[] gInvalid = {1};
|
||||||
|
|
||||||
|
public OnPluginStart()
|
||||||
|
{
|
||||||
|
int v = 10;
|
||||||
|
int invalid1[v];
|
||||||
|
int[] invalid2 = {1};
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalid_arg1(int invalid[])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalid_arg2(int[] invalid = {1, 2, 3})
|
||||||
|
{
|
||||||
|
}
|
6
sourcepawn/compiler/tests/fail-bad-array-decls.txt
Normal file
6
sourcepawn/compiler/tests/fail-bad-array-decls.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
(1) : error 162: cannot create dynamic arrays in global scope - did you mean to create a fixed-length array with brackets after the variable name?
|
||||||
|
(6) : error 161: brackets after variable name indicate a fixed-size array, but a dynamic size was given - did you mean to use 'new int[size]' syntax?
|
||||||
|
(7) : error 160: brackets in between type and variable name indicate a dynamic-size array, but a fixed-size initializer was given
|
||||||
|
(10) : error 159: brackets after variable name indicate a fixed-size array, but size could not be determined - either specify sizes, an array initializer, or use dynamic syntax (such as 'char[] x')
|
||||||
|
(14) : error 160: brackets in between type and variable name indicate a dynamic-size array, but a fixed-size initializer was given
|
||||||
|
|
@ -1,13 +1,15 @@
|
|||||||
native int[] egg6();
|
native int[] egg6();
|
||||||
forward float[] egg7();
|
forward float[] egg7();
|
||||||
new void crab4;
|
new void crab4;
|
||||||
int[] yam1 = {1,2,3}, yam2[] = {3,4,5};
|
|
||||||
|
void bad(int[] yam[] = {1})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
forward void OnPluginStart();
|
forward void OnPluginStart();
|
||||||
|
|
||||||
public int OnPluginStart()
|
public int OnPluginStart()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
(1) : error 141: natives, forwards, and public functions cannot return arrays
|
(1) : error 141: natives, forwards, and public functions cannot return arrays
|
||||||
(2) : error 141: natives, forwards, and public functions cannot return arrays
|
(2) : error 141: natives, forwards, and public functions cannot return arrays
|
||||||
(3) : error 143: new-style declarations should not have "new"
|
(3) : error 143: new-style declarations should not have "new"
|
||||||
(4) : error 121: cannot specify array dimensions on both type and name
|
(5) : error 121: cannot specify array dimensions on both type and name
|
||||||
(6) : error 025: function heading differs from prototype
|
(9) : error 025: function heading differs from prototype
|
||||||
|
@ -2,7 +2,7 @@ stock A(int n)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
stock B(int n[])
|
stock B(int n[10])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,8 @@ new crab2 = 5;
|
|||||||
bool crab3 = true;
|
bool crab3 = true;
|
||||||
int crab4 = 6;
|
int crab4 = 6;
|
||||||
new crab5[] = {1, 2, 3};
|
new crab5[] = {1, 2, 3};
|
||||||
bool[] crab6 = {true, false, false, true}
|
|
||||||
bool crab7[] = {false, true, true}
|
bool crab7[] = {false, true, true}
|
||||||
char crab8[] = "hello"
|
char crab8[] = "hello"
|
||||||
char[] crab9 = "bye"
|
|
||||||
|
|
||||||
native float operator*(float oper1, float oper2) = FloatMul;
|
native float operator*(float oper1, float oper2) = FloatMul;
|
||||||
|
|
||||||
@ -41,7 +39,6 @@ new Float:ham, bool:ham2;
|
|||||||
int cram, cram2, cram3;
|
int cram, cram2, cram3;
|
||||||
new cram4[] = {1, 2}, cram5[] = {3, 4, 7}
|
new cram4[] = {1, 2}, cram5[] = {3, 4, 7}
|
||||||
int cram6[] = {1, 2}, cram7[] = {3, 4, 7}
|
int cram6[] = {1, 2}, cram7[] = {3, 4, 7}
|
||||||
int[] cram8 = {3, 4}, cram9 = {4, 8, 10}
|
|
||||||
|
|
||||||
public OnPluginStart()
|
public OnPluginStart()
|
||||||
{
|
{
|
||||||
@ -50,6 +47,4 @@ public OnPluginStart()
|
|||||||
cram4[0] = 2
|
cram4[0] = 2
|
||||||
cram5[2] = 2
|
cram5[2] = 2
|
||||||
cram7[2] = 2
|
cram7[2] = 2
|
||||||
cram8[1] = 5
|
|
||||||
cram9[2] = 5
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user