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
|
||||
* @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.
|
||||
@ -109,7 +109,7 @@ native float ReadPackFloat(Handle pack);
|
||||
* @noreturn
|
||||
* @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.
|
||||
|
@ -614,6 +614,17 @@ static void inst_datetime_defines(void)
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
} /* if */
|
||||
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);
|
||||
if (type->tag == pc_tag_string && type->numdim == 1 && !type->dim[type->numdim - 1]) {
|
||||
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 */
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
* Declare local (automatic) variables. Since these variables are relative
|
||||
@ -2092,20 +2127,8 @@ static void declloc(int tokid)
|
||||
slength = fix_char_size(&decl);
|
||||
|
||||
if (type->ident == iARRAY || fstatic) {
|
||||
if (sc_alignnext) {
|
||||
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)
|
||||
if (!parse_local_array_initializer(type, &cur_lit, &slength))
|
||||
return;
|
||||
if (type->numdim == 1)
|
||||
type->dim[0] = type->size;
|
||||
}
|
||||
/* reserve memory (on the stack) for the variable */
|
||||
if (fstatic) {
|
||||
@ -2132,6 +2155,17 @@ static void declloc(int tokid)
|
||||
if (curfunc->x.stacksize<declared+1)
|
||||
curfunc->x.stacksize=declared+1; /* +1 for PROC opcode */
|
||||
} 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 */
|
||||
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 */
|
||||
@ -3035,7 +3069,7 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
||||
goto err_out;
|
||||
}
|
||||
} while (matchtoken('['));
|
||||
type->ident = iARRAY;
|
||||
type->ident = iREFARRAY;
|
||||
type->size = 0;
|
||||
}
|
||||
|
||||
@ -3146,6 +3180,10 @@ static void parse_old_array_dims(declinfo_t *decl, int flags)
|
||||
genarray(type->numdim, autozero);
|
||||
type->ident = iREFARRAY;
|
||||
type->size = 0;
|
||||
if (type->is_new) {
|
||||
// Fixed array with dynamic size.
|
||||
error(161, pc_typename(type->tag));
|
||||
}
|
||||
}
|
||||
|
||||
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 (matchtoken('[')) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -5606,6 +5645,9 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
||||
int slength=0;
|
||||
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);
|
||||
arg->hasdefault=FALSE; /* preset (most common case) */
|
||||
arg->defvalue.val=0; /* clear */
|
||||
@ -5641,6 +5683,10 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
assert(type->size >= litidx);
|
||||
/* 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 */
|
||||
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 {
|
||||
if (matchtoken('=')) {
|
||||
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)
|
||||
argsym->usage|=uCONST;
|
||||
} /* if */
|
||||
|
||||
errorset(sEXPRRELEASE,0);
|
||||
}
|
||||
|
||||
static int count_referrers(symbol *entry)
|
||||
|
@ -202,6 +202,10 @@ static const char *errmsg[] = {
|
||||
/*156*/ "unused156\n",
|
||||
/*157*/ "'%s' is a reserved keyword\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
|
||||
"\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",
|
||||
|
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();
|
||||
forward float[] egg7();
|
||||
new void crab4;
|
||||
int[] yam1 = {1,2,3}, yam2[] = {3,4,5};
|
||||
|
||||
void bad(int[] yam[] = {1})
|
||||
{
|
||||
}
|
||||
|
||||
forward void OnPluginStart();
|
||||
|
||||
public int OnPluginStart()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
(1) : 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"
|
||||
(4) : error 121: cannot specify array dimensions on both type and name
|
||||
(6) : error 025: function heading differs from prototype
|
||||
(5) : error 121: cannot specify array dimensions on both type and name
|
||||
(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;
|
||||
int crab4 = 6;
|
||||
new crab5[] = {1, 2, 3};
|
||||
bool[] crab6 = {true, false, false, true}
|
||||
bool crab7[] = {false, true, true}
|
||||
char crab8[] = "hello"
|
||||
char[] crab9 = "bye"
|
||||
|
||||
native float operator*(float oper1, float oper2) = FloatMul;
|
||||
|
||||
@ -41,7 +39,6 @@ new Float:ham, bool:ham2;
|
||||
int cram, cram2, cram3;
|
||||
new cram4[] = {1, 2}, cram5[] = {3, 4, 7}
|
||||
int cram6[] = {1, 2}, cram7[] = {3, 4, 7}
|
||||
int[] cram8 = {3, 4}, cram9 = {4, 8, 10}
|
||||
|
||||
public OnPluginStart()
|
||||
{
|
||||
@ -50,6 +47,4 @@ public OnPluginStart()
|
||||
cram4[0] = 2
|
||||
cram5[2] = 2
|
||||
cram7[2] = 2
|
||||
cram8[1] = 5
|
||||
cram9[2] = 5
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user