Merge pull request #186 from alliedmodders/fix-arrays
Define post-fix arrays as determinate and pre-fix arrays as indeterminate.
This commit is contained in:
commit
3c13c87f1c
@ -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.
|
||||||
|
@ -74,7 +74,7 @@ static const char *prefix[3]={ "error", "fatal error", "warning" };
|
|||||||
if (number!=0) {
|
if (number!=0) {
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
if (number < 160 || (number >= 200 && sc_warnings_are_errors))
|
if (number < FIRST_FATAL_ERROR || (number >= 200 && sc_warnings_are_errors))
|
||||||
idx = 0;
|
idx = 0;
|
||||||
else if (number < 200)
|
else if (number < 200)
|
||||||
idx = 1;
|
idx = 1;
|
||||||
|
@ -287,14 +287,16 @@ typedef struct {
|
|||||||
int numtags; // Number of tags found.
|
int numtags; // Number of tags found.
|
||||||
int ident; // Either iREFERENCE, iARRAY, or iVARIABLE.
|
int ident; // Either iREFERENCE, iARRAY, or iVARIABLE.
|
||||||
char usage; // Usage flags.
|
char usage; // Usage flags.
|
||||||
|
bool is_new; // New-style declaration.
|
||||||
|
bool has_postdims; // Dimensions, if present, were in postfix position.
|
||||||
|
|
||||||
|
bool isCharArray() const;
|
||||||
} typeinfo_t;
|
} typeinfo_t;
|
||||||
|
|
||||||
/* For parsing declarations. */
|
/* For parsing declarations. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[sNAMEMAX + 1];
|
char name[sNAMEMAX + 1];
|
||||||
typeinfo_t type;
|
typeinfo_t type;
|
||||||
int is_new; // New-style declaration.
|
|
||||||
int has_postdims; // Dimensions, if present, were in postfix position.
|
|
||||||
int opertok; // Operator token, if applicable.
|
int opertok; // Operator token, if applicable.
|
||||||
} declinfo_t;
|
} declinfo_t;
|
||||||
|
|
||||||
@ -938,4 +940,23 @@ typedef struct array_info_s
|
|||||||
cell *base; /* &litq[startlit] */
|
cell *base; /* &litq[startlit] */
|
||||||
} array_info_t;
|
} array_info_t;
|
||||||
|
|
||||||
|
enum FatalError {
|
||||||
|
FIRST_FATAL_ERROR = 180,
|
||||||
|
|
||||||
|
FATAL_ERROR_READ = FIRST_FATAL_ERROR,
|
||||||
|
FATAL_ERROR_WRITE,
|
||||||
|
FATAL_ERROR_ALLOC_OVERFLOW,
|
||||||
|
FATAL_ERROR_OOM,
|
||||||
|
FATAL_ERROR_INVALID_INSN,
|
||||||
|
FATAL_ERROR_INT_OVERFLOW,
|
||||||
|
FATAL_ERROR_SCRIPT_OVERFLOW,
|
||||||
|
FATAL_ERROR_OVERWHELMED_BY_BAD,
|
||||||
|
FATAL_ERROR_NO_CODEPAGE,
|
||||||
|
FATAL_ERROR_INVALID_PATH,
|
||||||
|
FATAL_ERROR_ASSERTION_FAILED,
|
||||||
|
FATAL_ERROR_USER_ERROR,
|
||||||
|
|
||||||
|
FATAL_ERRORS_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* SC_H_INCLUDED */
|
#endif /* SC_H_INCLUDED */
|
||||||
|
@ -157,6 +157,7 @@ static void inst_datetime_defines(void);
|
|||||||
static void inst_binary_name(char *binfname);
|
static void inst_binary_name(char *binfname);
|
||||||
static int operatorname(char *name);
|
static int operatorname(char *name);
|
||||||
static int parse_new_typename(const token_t *tok);
|
static int parse_new_typename(const token_t *tok);
|
||||||
|
static bool parse_new_typename(const token_t *tok, int *outp);
|
||||||
static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags);
|
static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags);
|
||||||
static int reparse_old_decl(declinfo_t *decl, int flags);
|
static int reparse_old_decl(declinfo_t *decl, int flags);
|
||||||
static int reparse_new_decl(declinfo_t *decl, int flags);
|
static int reparse_new_decl(declinfo_t *decl, int flags);
|
||||||
@ -218,17 +219,17 @@ int pc_compile(int argc, char *argv[])
|
|||||||
|
|
||||||
sp_Globals = NewHashTable();
|
sp_Globals = NewHashTable();
|
||||||
if (!sp_Globals)
|
if (!sp_Globals)
|
||||||
error(163);
|
error(FATAL_ERROR_OOM);
|
||||||
|
|
||||||
/* allocate memory for fixed tables */
|
/* allocate memory for fixed tables */
|
||||||
inpfname=(char*)malloc(_MAX_PATH);
|
inpfname=(char*)malloc(_MAX_PATH);
|
||||||
if (inpfname==NULL)
|
if (inpfname==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
litq=(cell*)malloc(litmax*sizeof(cell));
|
litq=(cell*)malloc(litmax*sizeof(cell));
|
||||||
if (litq==NULL)
|
if (litq==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
if (!phopt_init())
|
if (!phopt_init())
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
|
|
||||||
setopt(argc,argv,outfname,errfname,incfname,reportname,codepage);
|
setopt(argc,argv,outfname,errfname,incfname,reportname,codepage);
|
||||||
strcpy(binfname,outfname);
|
strcpy(binfname,outfname);
|
||||||
@ -254,7 +255,7 @@ int pc_compile(int argc, char *argv[])
|
|||||||
lcl_tabsize=sc_tabsize;
|
lcl_tabsize=sc_tabsize;
|
||||||
#if !defined NO_CODEPAGE
|
#if !defined NO_CODEPAGE
|
||||||
if (!cp_set(codepage)) /* set codepage */
|
if (!cp_set(codepage)) /* set codepage */
|
||||||
error(168); /* codepage mapping file not found */
|
error(FATAL_ERROR_NO_CODEPAGE);
|
||||||
#endif
|
#endif
|
||||||
/* optionally create a temporary input file that is a collection of all
|
/* optionally create a temporary input file that is a collection of all
|
||||||
* input files
|
* input files
|
||||||
@ -271,7 +272,7 @@ int pc_compile(int argc, char *argv[])
|
|||||||
tname=tempnam(NULL,"pawn");
|
tname=tempnam(NULL,"pawn");
|
||||||
#elif defined(MACOS) && !defined(__MACH__)
|
#elif defined(MACOS) && !defined(__MACH__)
|
||||||
/* tempnam is not supported for the Macintosh CFM build. */
|
/* tempnam is not supported for the Macintosh CFM build. */
|
||||||
error(164,get_sourcefile(1));
|
error(FATAL_ERROR_INVALID_INSN,get_sourcefile(1));
|
||||||
tname=NULL;
|
tname=NULL;
|
||||||
sname=NULL;
|
sname=NULL;
|
||||||
#else
|
#else
|
||||||
@ -287,7 +288,7 @@ int pc_compile(int argc, char *argv[])
|
|||||||
pc_closesrc(ftmp);
|
pc_closesrc(ftmp);
|
||||||
remove(tname);
|
remove(tname);
|
||||||
strcpy(inpfname,sname); /* avoid invalid filename */
|
strcpy(inpfname,sname); /* avoid invalid filename */
|
||||||
error(160,sname);
|
error(FATAL_ERROR_READ,sname);
|
||||||
} /* if */
|
} /* if */
|
||||||
pc_writesrc(ftmp,(unsigned char*)"#file \"");
|
pc_writesrc(ftmp,(unsigned char*)"#file \"");
|
||||||
pc_writesrc(ftmp,(unsigned char*)sname);
|
pc_writesrc(ftmp,(unsigned char*)sname);
|
||||||
@ -306,11 +307,11 @@ int pc_compile(int argc, char *argv[])
|
|||||||
} /* if */
|
} /* if */
|
||||||
inpf_org=pc_opensrc(inpfname);
|
inpf_org=pc_opensrc(inpfname);
|
||||||
if (inpf_org==NULL)
|
if (inpf_org==NULL)
|
||||||
error(160,inpfname);
|
error(FATAL_ERROR_READ,inpfname);
|
||||||
freading=TRUE;
|
freading=TRUE;
|
||||||
outf=(FILE*)pc_openasm(outfname); /* first write to assembler file (may be temporary) */
|
outf=(FILE*)pc_openasm(outfname); /* first write to assembler file (may be temporary) */
|
||||||
if (outf==NULL)
|
if (outf==NULL)
|
||||||
error(161,outfname);
|
error(FATAL_ERROR_WRITE,outfname);
|
||||||
setconstants(); /* set predefined constants and tagnames */
|
setconstants(); /* set predefined constants and tagnames */
|
||||||
for (i=0; i<skipinput; i++) /* skip lines in the input file */
|
for (i=0; i<skipinput; i++) /* skip lines in the input file */
|
||||||
if (pc_readsrc(inpf_org,pline,sLINEMAX)!=NULL)
|
if (pc_readsrc(inpf_org,pline,sLINEMAX)!=NULL)
|
||||||
@ -366,7 +367,7 @@ int pc_compile(int argc, char *argv[])
|
|||||||
plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
|
plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
|
||||||
} else {
|
} else {
|
||||||
if (!plungequalifiedfile(incfname)) /* parse "prefix" include file */
|
if (!plungequalifiedfile(incfname)) /* parse "prefix" include file */
|
||||||
error(160,incfname); /* cannot read from ... (fatal error) */
|
error(FATAL_ERROR_READ,incfname);
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
preprocess(); /* fetch first line */
|
preprocess(); /* fetch first line */
|
||||||
@ -486,7 +487,7 @@ cleanup:
|
|||||||
pc_printf("Total requirements:%8ld bytes\n", (long)code_idx+(long)glb_declared*sizeof(cell)+(long)pc_stksize*sizeof(cell));
|
pc_printf("Total requirements:%8ld bytes\n", (long)code_idx+(long)glb_declared*sizeof(cell)+(long)pc_stksize*sizeof(cell));
|
||||||
} /* if */
|
} /* if */
|
||||||
if (flag_exceed)
|
if (flag_exceed)
|
||||||
error(166,pc_amxlimit+pc_amxram); /* this causes a jump back to label "cleanup" */
|
error(FATAL_ERROR_INT_OVERFLOW,pc_amxlimit+pc_amxram); /* this causes a jump back to label "cleanup" */
|
||||||
} /* if */
|
} /* if */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -614,6 +615,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;
|
||||||
@ -1086,14 +1098,14 @@ static void parserespf(char *filename,char *oname,char *ename,char *pname,
|
|||||||
long size;
|
long size;
|
||||||
|
|
||||||
if ((fp=fopen(filename,"r"))==NULL)
|
if ((fp=fopen(filename,"r"))==NULL)
|
||||||
error(160,filename); /* error reading input file */
|
error(FATAL_ERROR_READ,filename);
|
||||||
/* load the complete file into memory */
|
/* load the complete file into memory */
|
||||||
fseek(fp,0L,SEEK_END);
|
fseek(fp,0L,SEEK_END);
|
||||||
size=ftell(fp);
|
size=ftell(fp);
|
||||||
fseek(fp,0L,SEEK_SET);
|
fseek(fp,0L,SEEK_SET);
|
||||||
assert(size<INT_MAX);
|
assert(size<INT_MAX);
|
||||||
if ((string=(char *)malloc((int)size+1))==NULL)
|
if ((string=(char *)malloc((int)size+1))==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
/* fill with zeros; in MS-DOS, fread() may collapse CR/LF pairs to
|
/* fill with zeros; in MS-DOS, fread() may collapse CR/LF pairs to
|
||||||
* a single '\n', so the string size may be smaller than the file
|
* a single '\n', so the string size may be smaller than the file
|
||||||
* size. */
|
* size. */
|
||||||
@ -1102,7 +1114,7 @@ static void parserespf(char *filename,char *oname,char *ename,char *pname,
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
/* allocate table for option pointers */
|
/* allocate table for option pointers */
|
||||||
if ((argv=(char **)malloc(MAX_OPTIONS*sizeof(char*)))==NULL)
|
if ((argv=(char **)malloc(MAX_OPTIONS*sizeof(char*)))==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
/* fill the options table */
|
/* fill the options table */
|
||||||
ptr=strtok(string," \t\r\n");
|
ptr=strtok(string," \t\r\n");
|
||||||
for (argc=1; argc<MAX_OPTIONS && ptr!=NULL; argc++) {
|
for (argc=1; argc<MAX_OPTIONS && ptr!=NULL; argc++) {
|
||||||
@ -1111,7 +1123,7 @@ static void parserespf(char *filename,char *oname,char *ename,char *pname,
|
|||||||
ptr=strtok(NULL," \t\r\n");
|
ptr=strtok(NULL," \t\r\n");
|
||||||
} /* for */
|
} /* for */
|
||||||
if (ptr!=NULL)
|
if (ptr!=NULL)
|
||||||
error(162,"option table"); /* table overflow */
|
error(FATAL_ERROR_ALLOC_OVERFLOW,"option table");
|
||||||
/* parse the option table */
|
/* parse the option table */
|
||||||
parseoptions(argc,argv,oname,ename,pname,rname,codepage);
|
parseoptions(argc,argv,oname,ename,pname,rname,codepage);
|
||||||
/* free allocated memory */
|
/* free allocated memory */
|
||||||
@ -1221,7 +1233,7 @@ static void setconfig(char *root)
|
|||||||
# if !defined NO_CODEPAGE
|
# if !defined NO_CODEPAGE
|
||||||
*ptr='\0';
|
*ptr='\0';
|
||||||
if (!cp_path(path,"codepage"))
|
if (!cp_path(path,"codepage"))
|
||||||
error(169,path); /* codepage path */
|
error(FATAL_ERROR_INVALID_PATH,path);
|
||||||
# endif /* !NO_CODEPAGE */
|
# endif /* !NO_CODEPAGE */
|
||||||
|
|
||||||
/* also copy the root path (for the XML documentation) */
|
/* also copy the root path (for the XML documentation) */
|
||||||
@ -1451,8 +1463,8 @@ static void dodecl(const token_t *tok)
|
|||||||
decl.type.tag = 0;
|
decl.type.tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!decl.opertok && (tok->id == tNEW || decl.has_postdims || !lexpeek('('))) {
|
if (!decl.opertok && (tok->id == tNEW || decl.type.has_postdims || !lexpeek('('))) {
|
||||||
if (tok->id == tNEW && decl.is_new)
|
if (tok->id == tNEW && decl.type.is_new)
|
||||||
error(143);
|
error(143);
|
||||||
if (decl.type.tag & STRUCTTAG) {
|
if (decl.type.tag & STRUCTTAG) {
|
||||||
pstruct_t *pstruct = pstructs_find(pc_tagname(decl.type.tag));
|
pstruct_t *pstruct = pstructs_find(pc_tagname(decl.type.tag));
|
||||||
@ -1985,6 +1997,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;
|
||||||
@ -2030,7 +2047,7 @@ static void declglb(declinfo_t *decl,int fpublic,int fstatic,int fstock)
|
|||||||
if (!matchtoken(','))
|
if (!matchtoken(','))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (decl->is_new)
|
if (decl->type.is_new)
|
||||||
reparse_new_decl(decl, DECLFLAG_VARIABLE|DECLFLAG_ENUMROOT);
|
reparse_new_decl(decl, DECLFLAG_VARIABLE|DECLFLAG_ENUMROOT);
|
||||||
else
|
else
|
||||||
reparse_old_decl(decl, DECLFLAG_VARIABLE|DECLFLAG_ENUMROOT);
|
reparse_old_decl(decl, DECLFLAG_VARIABLE|DECLFLAG_ENUMROOT);
|
||||||
@ -2038,6 +2055,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
|
||||||
@ -2091,21 +2127,12 @@ static void declloc(int tokid)
|
|||||||
|
|
||||||
slength = fix_char_size(&decl);
|
slength = fix_char_size(&decl);
|
||||||
|
|
||||||
|
if (fstatic && type->ident == iREFARRAY)
|
||||||
|
error(165);
|
||||||
|
|
||||||
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,9 +2159,84 @@ 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) {
|
||||||
|
// Generate the symbol so we can access its stack address during initialization.
|
||||||
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 */
|
|
||||||
|
// If we're new-style, a REFARRAY indicates prefix brackets. We need to
|
||||||
|
// be initialized since we don't support fully dynamic arrays yet; i.e.,
|
||||||
|
// "int[] x;" doesn't have any sensible semantics. There are two
|
||||||
|
// acceptable initialization sequences: "new <type>" and a string
|
||||||
|
// literal. In other cases (such as a fixed-array literal), we error.
|
||||||
|
//
|
||||||
|
// For now, we only implement the string literal initializer.
|
||||||
|
if (type->is_new && needtoken('=')) {
|
||||||
|
if (type->isCharArray()) {
|
||||||
|
// Error if we're assigning something other than a string literal.
|
||||||
|
needtoken(tSTRING);
|
||||||
|
|
||||||
|
// Note: the genarray call pushes the result array into the stack
|
||||||
|
// slot of our local variable - we can access |sym| after.
|
||||||
|
//
|
||||||
|
// push.c N
|
||||||
|
// genarray 1
|
||||||
|
// const.pri DAT + offset
|
||||||
|
// load.s.alt sym->addr
|
||||||
|
// movs N * sizeof(cell)
|
||||||
|
int cells = litidx - cur_lit;
|
||||||
|
pushval(cells);
|
||||||
|
genarray(1, false);
|
||||||
|
ldconst((cur_lit + glb_declared) * sizeof(cell), sPRI);
|
||||||
|
copyarray(sym, cells * sizeof(cell));
|
||||||
|
} else if (matchtoken(tNEW)) {
|
||||||
|
int tag = 0;
|
||||||
|
if (parse_new_typename(NULL, &tag)) {
|
||||||
|
if (tag != type->tag)
|
||||||
|
error(164, pc_typename(tag), pc_typename(type->tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < type->numdim; i++) {
|
||||||
|
if (!needtoken('['))
|
||||||
|
break;
|
||||||
|
|
||||||
|
value val;
|
||||||
|
symbol *child;
|
||||||
|
int ident = doexpr2(
|
||||||
|
TRUE, FALSE, TRUE, FALSE,
|
||||||
|
&type->idxtag[i],
|
||||||
|
&child, 0, &val);
|
||||||
|
pushreg(sPRI);
|
||||||
|
|
||||||
|
switch (ident) {
|
||||||
|
case iVARIABLE:
|
||||||
|
case iEXPRESSION:
|
||||||
|
case iARRAYCELL:
|
||||||
|
case iCONSTEXPR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error(29);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!needtoken(']'))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
genarray(type->numdim, true);
|
||||||
|
} else 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;
|
||||||
|
} else {
|
||||||
|
// Give the '=' back so we error later.
|
||||||
|
lexpush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* genarray() pushes the address onto the stack, so we don't need to call modstk() here! */
|
/* genarray() pushes the address onto the stack, so we don't need to call modstk() here! */
|
||||||
markheap(MEMUSE_DYNAMIC, 0);
|
markheap(MEMUSE_DYNAMIC, 0);
|
||||||
markstack(MEMUSE_STATIC, 1);
|
markstack(MEMUSE_STATIC, 1);
|
||||||
@ -2221,7 +2323,7 @@ static void declloc(int tokid)
|
|||||||
if (!matchtoken(','))
|
if (!matchtoken(','))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (decl.is_new)
|
if (decl.type.is_new)
|
||||||
reparse_new_decl(&decl, declflags);
|
reparse_new_decl(&decl, declflags);
|
||||||
else
|
else
|
||||||
reparse_old_decl(&decl, declflags);
|
reparse_old_decl(&decl, declflags);
|
||||||
@ -3001,6 +3103,16 @@ static int parse_new_typename(const token_t *tok)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_new_typename(const token_t *tok, int *tagp)
|
||||||
|
{
|
||||||
|
int tag = parse_new_typename(tok);
|
||||||
|
if (tag >= 0)
|
||||||
|
*tagp = tag;
|
||||||
|
else
|
||||||
|
*tagp = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
||||||
{
|
{
|
||||||
token_t tok;
|
token_t tok;
|
||||||
@ -3017,8 +3129,7 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
|||||||
lextok(&tok);
|
lextok(&tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
type->tag = parse_new_typename(&tok);
|
if (!parse_new_typename(&tok, &type->tag))
|
||||||
if (type->tag == -1)
|
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
// Note: we could have already filled in the prefix array bits, so we check
|
// Note: we could have already filled in the prefix array bits, so we check
|
||||||
@ -3035,7 +3146,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 +3257,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);
|
||||||
@ -3160,7 +3275,7 @@ static void parse_old_array_dims(declinfo_t *decl, int flags)
|
|||||||
|
|
||||||
type->size = needsub(&type->idxtag[type->numdim], enumrootp);
|
type->size = needsub(&type->idxtag[type->numdim], enumrootp);
|
||||||
if (type->size > INT_MAX)
|
if (type->size > INT_MAX)
|
||||||
error(165);
|
error(FATAL_ERROR_INT_OVERFLOW);
|
||||||
|
|
||||||
type->dim[type->numdim++] = type->size;
|
type->dim[type->numdim++] = type->size;
|
||||||
} while (matchtoken('['));
|
} while (matchtoken('['));
|
||||||
@ -3168,7 +3283,7 @@ static void parse_old_array_dims(declinfo_t *decl, int flags)
|
|||||||
type->ident = iARRAY;
|
type->ident = iARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
decl->has_postdims = TRUE;
|
decl->type.has_postdims = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_old_decl(declinfo_t *decl, int flags)
|
static int parse_old_decl(declinfo_t *decl, int flags)
|
||||||
@ -3301,6 +3416,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 +3427,6 @@ static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decl->is_new = TRUE;
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3320,7 +3436,7 @@ static int reparse_new_decl(declinfo_t *decl, int flags)
|
|||||||
if (expecttoken(tSYMBOL, &tok))
|
if (expecttoken(tSYMBOL, &tok))
|
||||||
strcpy(decl->name, tok.str);
|
strcpy(decl->name, tok.str);
|
||||||
|
|
||||||
if (decl->has_postdims) {
|
if (decl->type.has_postdims) {
|
||||||
// We have something like:
|
// We have something like:
|
||||||
// int x[], y...
|
// int x[], y...
|
||||||
//
|
//
|
||||||
@ -3330,7 +3446,7 @@ static int reparse_new_decl(declinfo_t *decl, int flags)
|
|||||||
decl->type.enumroot = NULL;
|
decl->type.enumroot = NULL;
|
||||||
decl->type.ident = iVARIABLE;
|
decl->type.ident = iVARIABLE;
|
||||||
decl->type.size = 0;
|
decl->type.size = 0;
|
||||||
decl->has_postdims = FALSE;
|
decl->type.has_postdims = false;
|
||||||
if (matchtoken('['))
|
if (matchtoken('['))
|
||||||
parse_old_array_dims(decl, flags);
|
parse_old_array_dims(decl, flags);
|
||||||
} else {
|
} else {
|
||||||
@ -3403,7 +3519,7 @@ int parse_decl(declinfo_t *decl, int flags)
|
|||||||
// This must be a newdecl, "x[] y" or "x[] &y", the latter of which
|
// This must be a newdecl, "x[] y" or "x[] &y", the latter of which
|
||||||
// is illegal, but we flow it through the right path anyway.
|
// is illegal, but we flow it through the right path anyway.
|
||||||
lexpush();
|
lexpush();
|
||||||
decl->has_postdims = FALSE;
|
decl->type.has_postdims = false;
|
||||||
return parse_new_decl(decl, &ident.tok, flags);
|
return parse_new_decl(decl, &ident.tok, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3532,7 +3648,7 @@ symbol *parse_inline_function(methodmap_t *map, const typeinfo_t *type, const ch
|
|||||||
} else {
|
} else {
|
||||||
decl.type = *type;
|
decl.type = *type;
|
||||||
}
|
}
|
||||||
decl.is_new = TRUE;
|
decl.type.is_new = TRUE;
|
||||||
|
|
||||||
const int *thistag = NULL;
|
const int *thistag = NULL;
|
||||||
if (!is_ctor)
|
if (!is_ctor)
|
||||||
@ -3994,7 +4110,7 @@ static void domethodmap(LayoutSpec spec)
|
|||||||
|
|
||||||
methods = (methodmap_method_t **)realloc(map->methods, sizeof(methodmap_method_t *) * (map->nummethods + 1));
|
methods = (methodmap_method_t **)realloc(map->methods, sizeof(methodmap_method_t *) * (map->nummethods + 1));
|
||||||
if (!methods) {
|
if (!methods) {
|
||||||
error(163);
|
error(FATAL_ERROR_OOM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
map->methods = methods;
|
map->methods = methods;
|
||||||
@ -4156,7 +4272,7 @@ static void parse_function_type(functag_t *type)
|
|||||||
int lparen = matchtoken('(');
|
int lparen = matchtoken('(');
|
||||||
needtoken(tFUNCTION);
|
needtoken(tFUNCTION);
|
||||||
|
|
||||||
type->ret_tag = parse_new_typename(NULL);
|
parse_new_typename(NULL, &type->ret_tag);
|
||||||
type->usage = uPUBLIC;
|
type->usage = uPUBLIC;
|
||||||
|
|
||||||
needtoken('(');
|
needtoken('(');
|
||||||
@ -4521,7 +4637,7 @@ static void decl_enum(int vclass)
|
|||||||
enumsym->usage |= uENUMROOT;
|
enumsym->usage |= uENUMROOT;
|
||||||
/* start a new list for the element names */
|
/* start a new list for the element names */
|
||||||
if ((enumroot=(constvalue*)malloc(sizeof(constvalue)))==NULL)
|
if ((enumroot=(constvalue*)malloc(sizeof(constvalue)))==NULL)
|
||||||
error(163); /* insufficient memory (fatal error) */
|
error(FATAL_ERROR_OOM); /* insufficient memory (fatal error) */
|
||||||
memset(enumroot,0,sizeof(constvalue));
|
memset(enumroot,0,sizeof(constvalue));
|
||||||
} else {
|
} else {
|
||||||
enumsym=NULL;
|
enumsym=NULL;
|
||||||
@ -4671,7 +4787,7 @@ static void attachstatelist(symbol *sym, int state_id)
|
|||||||
constvalue *stateptr;
|
constvalue *stateptr;
|
||||||
if (sym->states==NULL) {
|
if (sym->states==NULL) {
|
||||||
if ((sym->states=(constvalue*)malloc(sizeof(constvalue)))==NULL)
|
if ((sym->states=(constvalue*)malloc(sizeof(constvalue)))==NULL)
|
||||||
error(163); /* insufficient memory (fatal error) */
|
error(FATAL_ERROR_OOM); /* insufficient memory (fatal error) */
|
||||||
memset(sym->states,0,sizeof(constvalue));
|
memset(sym->states,0,sizeof(constvalue));
|
||||||
} /* if */
|
} /* if */
|
||||||
/* see whether the id already exists (add new state only if it does not
|
/* see whether the id already exists (add new state only if it does not
|
||||||
@ -5281,7 +5397,7 @@ static int newfunc(declinfo_t *decl, const int *thistag, int fpublic, int fstati
|
|||||||
lexpush();
|
lexpush();
|
||||||
} else {
|
} else {
|
||||||
// We require '{' for new methods.
|
// We require '{' for new methods.
|
||||||
if (decl->is_new)
|
if (decl->type.is_new)
|
||||||
needtoken('{');
|
needtoken('{');
|
||||||
|
|
||||||
/* Insert a separator so that comments following the statement will not
|
/* Insert a separator so that comments following the statement will not
|
||||||
@ -5302,7 +5418,7 @@ static int newfunc(declinfo_t *decl, const int *thistag, int fpublic, int fstati
|
|||||||
if (sym->tag == pc_tag_void &&
|
if (sym->tag == pc_tag_void &&
|
||||||
(sym->usage & uFORWARD) &&
|
(sym->usage & uFORWARD) &&
|
||||||
!decl->type.tag &&
|
!decl->type.tag &&
|
||||||
!decl->is_new)
|
!decl->type.is_new)
|
||||||
{
|
{
|
||||||
// We got something like:
|
// We got something like:
|
||||||
// forward void X();
|
// forward void X();
|
||||||
@ -5483,7 +5599,7 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
|||||||
/* redimension the argument list, add the entry iVARARGS */
|
/* redimension the argument list, add the entry iVARARGS */
|
||||||
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
|
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
|
||||||
if (sym->dim.arglist==0)
|
if (sym->dim.arglist==0)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
|
memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
|
||||||
sym->dim.arglist[argcnt].ident=iVARARGS;
|
sym->dim.arglist[argcnt].ident=iVARARGS;
|
||||||
sym->dim.arglist[argcnt].hasdefault=FALSE;
|
sym->dim.arglist[argcnt].hasdefault=FALSE;
|
||||||
@ -5492,7 +5608,7 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
|||||||
sym->dim.arglist[argcnt].numtags=decl.type.numtags;
|
sym->dim.arglist[argcnt].numtags=decl.type.numtags;
|
||||||
sym->dim.arglist[argcnt].tags=(int*)malloc(decl.type.numtags*sizeof decl.type.tags[0]);
|
sym->dim.arglist[argcnt].tags=(int*)malloc(decl.type.numtags*sizeof decl.type.tags[0]);
|
||||||
if (sym->dim.arglist[argcnt].tags==NULL)
|
if (sym->dim.arglist[argcnt].tags==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
memcpy(sym->dim.arglist[argcnt].tags,decl.type.tags,decl.type.numtags*sizeof decl.type.tags[0]);
|
memcpy(sym->dim.arglist[argcnt].tags,decl.type.tags,decl.type.numtags*sizeof decl.type.tags[0]);
|
||||||
} else {
|
} else {
|
||||||
if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
|
if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
|
||||||
@ -5525,7 +5641,7 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
|||||||
/* redimension the argument list, add the entry */
|
/* redimension the argument list, add the entry */
|
||||||
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
|
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
|
||||||
if (sym->dim.arglist==0)
|
if (sym->dim.arglist==0)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
|
memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
|
||||||
sym->dim.arglist[argcnt]=arg;
|
sym->dim.arglist[argcnt]=arg;
|
||||||
} else {
|
} else {
|
||||||
@ -5606,6 +5722,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 +5760,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 +5783,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;
|
||||||
@ -5684,7 +5817,7 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
cell val;
|
cell val;
|
||||||
tokeninfo(&val,&name);
|
tokeninfo(&val,&name);
|
||||||
if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
|
if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
arg->defvalue.size.level=0;
|
arg->defvalue.size.level=0;
|
||||||
if (size_tag_token==uSIZEOF || size_tag_token==uCOUNTOF) {
|
if (size_tag_token==uSIZEOF || size_tag_token==uCOUNTOF) {
|
||||||
while (matchtoken('[')) {
|
while (matchtoken('[')) {
|
||||||
@ -5709,7 +5842,7 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
|
|||||||
arg->numtags=type->numtags;
|
arg->numtags=type->numtags;
|
||||||
arg->tags=(int*)malloc(type->numtags * sizeof(type->tags[0]));
|
arg->tags=(int*)malloc(type->numtags * sizeof(type->tags[0]));
|
||||||
if (arg->tags==NULL)
|
if (arg->tags==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM); /* insufficient memory */
|
||||||
memcpy(arg->tags, type->tags, type->numtags * sizeof(type->tags[0]));
|
memcpy(arg->tags, type->tags, type->numtags * sizeof(type->tags[0]));
|
||||||
argsym=findloc(decl->name);
|
argsym=findloc(decl->name);
|
||||||
if (argsym!=NULL) {
|
if (argsym!=NULL) {
|
||||||
@ -5729,6 +5862,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)
|
||||||
@ -6458,7 +6593,7 @@ static constvalue *insert_constval(constvalue *prev,constvalue *next,const char
|
|||||||
constvalue *cur;
|
constvalue *cur;
|
||||||
|
|
||||||
if ((cur=(constvalue*)malloc(sizeof(constvalue)))==NULL)
|
if ((cur=(constvalue*)malloc(sizeof(constvalue)))==NULL)
|
||||||
error(163); /* insufficient memory (fatal error) */
|
error(FATAL_ERROR_OOM); /* insufficient memory (fatal error) */
|
||||||
memset(cur,0,sizeof(constvalue));
|
memset(cur,0,sizeof(constvalue));
|
||||||
if (name!=NULL) {
|
if (name!=NULL) {
|
||||||
assert(strlen(name)<=sNAMEMAX);
|
assert(strlen(name)<=sNAMEMAX);
|
||||||
@ -7758,7 +7893,7 @@ static void addwhile(int *ptr)
|
|||||||
ptr[wqLOOP]=getlabel();
|
ptr[wqLOOP]=getlabel();
|
||||||
ptr[wqEXIT]=getlabel();
|
ptr[wqEXIT]=getlabel();
|
||||||
if (wqptr>=(wq+wqTABSZ-wqSIZE))
|
if (wqptr>=(wq+wqTABSZ-wqSIZE))
|
||||||
error(162,"loop table"); /* loop table overflow (too many active loops)*/
|
error(FATAL_ERROR_ALLOC_OVERFLOW,"loop table"); /* loop table overflow (too many active loops)*/
|
||||||
k=0;
|
k=0;
|
||||||
while (k<wqSIZE){ /* copy "ptr" to while queue table */
|
while (k<wqSIZE){ /* copy "ptr" to while queue table */
|
||||||
*wqptr=*ptr;
|
*wqptr=*ptr;
|
||||||
@ -7784,3 +7919,7 @@ static int *readwhile(void)
|
|||||||
} /* if */
|
} /* if */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool typeinfo_t::isCharArray() const
|
||||||
|
{
|
||||||
|
return numdim == 1 && tag == pc_tag_string;
|
||||||
|
}
|
||||||
|
@ -96,7 +96,7 @@ void pushstk(stkitem val)
|
|||||||
assert(newsize>stktop);
|
assert(newsize>stktop);
|
||||||
newstack=(stkitem*)malloc(newsize*sizeof(stkitem));
|
newstack=(stkitem*)malloc(newsize*sizeof(stkitem));
|
||||||
if (newstack==NULL)
|
if (newstack==NULL)
|
||||||
error(162,"parser stack"); /* stack overflow (recursive include?) */
|
error(FATAL_ERROR_ALLOC_OVERFLOW,"parser stack");
|
||||||
/* swap the stacks */
|
/* swap the stacks */
|
||||||
memcpy(newstack,stack,stkidx*sizeof(stkitem));
|
memcpy(newstack,stack,stkidx*sizeof(stkitem));
|
||||||
if (stack!=NULL)
|
if (stack!=NULL)
|
||||||
@ -172,7 +172,7 @@ int plungequalifiedfile(char *name)
|
|||||||
PUSHSTK_I(fline);
|
PUSHSTK_I(fline);
|
||||||
inpfname=duplicatestring(name);/* set name of include file */
|
inpfname=duplicatestring(name);/* set name of include file */
|
||||||
if (inpfname==NULL)
|
if (inpfname==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
inpf=fp; /* set input file pointer to include file */
|
inpf=fp; /* set input file pointer to include file */
|
||||||
fnumber++;
|
fnumber++;
|
||||||
fline=0; /* set current line number to 0 */
|
fline=0; /* set current line number to 0 */
|
||||||
@ -276,7 +276,7 @@ static void doinclude(int silent)
|
|||||||
|
|
||||||
result=plungefile(name,(c!='>'),TRUE);
|
result=plungefile(name,(c!='>'),TRUE);
|
||||||
if (!result && !silent)
|
if (!result && !silent)
|
||||||
error(160,name); /* cannot read from ... (fatal error) */
|
error(FATAL_ERROR_READ,name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* readline
|
/* readline
|
||||||
@ -890,7 +890,7 @@ static int command(void)
|
|||||||
ret=CMD_IF;
|
ret=CMD_IF;
|
||||||
assert(iflevel>=0);
|
assert(iflevel>=0);
|
||||||
if (iflevel>=sCOMP_STACK)
|
if (iflevel>=sCOMP_STACK)
|
||||||
error(162,"Conditional compilation stack"); /* table overflow */
|
error(FATAL_ERROR_ALLOC_OVERFLOW,"Conditional compilation stack");
|
||||||
iflevel++;
|
iflevel++;
|
||||||
if (SKIPPING)
|
if (SKIPPING)
|
||||||
break; /* break out of switch */
|
break; /* break out of switch */
|
||||||
@ -979,7 +979,7 @@ static int command(void)
|
|||||||
free(inpfname);
|
free(inpfname);
|
||||||
inpfname=duplicatestring(pathname);
|
inpfname=duplicatestring(pathname);
|
||||||
if (inpfname==NULL)
|
if (inpfname==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
fline=0;
|
fline=0;
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
@ -1023,7 +1023,7 @@ static int command(void)
|
|||||||
name[i]='\0';
|
name[i]='\0';
|
||||||
} /* if */
|
} /* if */
|
||||||
if (!cp_set(name))
|
if (!cp_set(name))
|
||||||
error(168); /* codepage mapping file not found */
|
error(FATAL_ERROR_NO_CODEPAGE);
|
||||||
} else if (strcmp(str,"compress")==0) {
|
} else if (strcmp(str,"compress")==0) {
|
||||||
cell val;
|
cell val;
|
||||||
preproc_expr(&val,NULL);
|
preproc_expr(&val,NULL);
|
||||||
@ -1292,7 +1292,7 @@ static int command(void)
|
|||||||
/* store matched pattern */
|
/* store matched pattern */
|
||||||
pattern=(char*)malloc(count+1);
|
pattern=(char*)malloc(count+1);
|
||||||
if (pattern==NULL)
|
if (pattern==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
lptr=start;
|
lptr=start;
|
||||||
count=0;
|
count=0;
|
||||||
while (lptr!=end) {
|
while (lptr!=end) {
|
||||||
@ -1326,7 +1326,7 @@ static int command(void)
|
|||||||
/* store matched substitution */
|
/* store matched substitution */
|
||||||
substitution=(char*)malloc(count+1); /* +1 for '\0' */
|
substitution=(char*)malloc(count+1); /* +1 for '\0' */
|
||||||
if (substitution==NULL)
|
if (substitution==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
lptr=start;
|
lptr=start;
|
||||||
count=0;
|
count=0;
|
||||||
while (lptr!=end) {
|
while (lptr!=end) {
|
||||||
@ -1542,7 +1542,7 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
|
|||||||
len=(int)(e-s);
|
len=(int)(e-s);
|
||||||
args[arg]=(unsigned char*)malloc(len+1);
|
args[arg]=(unsigned char*)malloc(len+1);
|
||||||
if (args[arg]==NULL)
|
if (args[arg]==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
strlcpy((char*)args[arg],(char*)s,len+1);
|
strlcpy((char*)args[arg],(char*)s,len+1);
|
||||||
/* character behind the pattern was matched too */
|
/* character behind the pattern was matched too */
|
||||||
if (*e==*p) {
|
if (*e==*p) {
|
||||||
@ -2469,7 +2469,7 @@ static void chk_grow_litq(void)
|
|||||||
litmax+=sDEF_LITMAX;
|
litmax+=sDEF_LITMAX;
|
||||||
p=(cell *)realloc(litq,litmax*sizeof(cell));
|
p=(cell *)realloc(litq,litmax*sizeof(cell));
|
||||||
if (p==NULL)
|
if (p==NULL)
|
||||||
error(162,"literal table"); /* literal table overflow (fatal error) */
|
error(FATAL_ERROR_ALLOC_OVERFLOW,"literal table");
|
||||||
litq=p;
|
litq=p;
|
||||||
} /* if */
|
} /* if */
|
||||||
}
|
}
|
||||||
@ -2662,7 +2662,7 @@ static symbol *add_symbol(symbol *root,symbol *entry,int sort)
|
|||||||
root=root->next;
|
root=root->next;
|
||||||
|
|
||||||
if ((newsym=(symbol *)malloc(sizeof(symbol)))==NULL) {
|
if ((newsym=(symbol *)malloc(sizeof(symbol)))==NULL) {
|
||||||
error(163);
|
error(FATAL_ERROR_OOM);
|
||||||
return NULL;
|
return NULL;
|
||||||
} /* if */
|
} /* if */
|
||||||
memcpy(newsym,entry,sizeof(symbol));
|
memcpy(newsym,entry,sizeof(symbol));
|
||||||
@ -3057,7 +3057,7 @@ symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,int usage
|
|||||||
|
|
||||||
/* create an empty referrer list */
|
/* create an empty referrer list */
|
||||||
if ((refer=(symbol**)malloc(sizeof(symbol*)))==NULL) {
|
if ((refer=(symbol**)malloc(sizeof(symbol*)))==NULL) {
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
return NULL;
|
return NULL;
|
||||||
} /* if */
|
} /* if */
|
||||||
*refer=NULL;
|
*refer=NULL;
|
||||||
|
@ -1702,7 +1702,7 @@ static int hier2(value *lval)
|
|||||||
lval->constval=array_levelsize(sym,level);
|
lval->constval=array_levelsize(sym,level);
|
||||||
}
|
}
|
||||||
if (lval->constval==0 && strchr((char *)lptr,PREPROC_TERM)==NULL)
|
if (lval->constval==0 && strchr((char *)lptr,PREPROC_TERM)==NULL)
|
||||||
error(224,st); /* indeterminate array size in "sizeof" expression */
|
error(163,st); /* indeterminate array size in "sizeof" expression */
|
||||||
} /* if */
|
} /* if */
|
||||||
ldconst(lval->constval,sPRI);
|
ldconst(lval->constval,sPRI);
|
||||||
while (paranthese--)
|
while (paranthese--)
|
||||||
@ -1756,7 +1756,7 @@ static int hier2(value *lval)
|
|||||||
lval->constval=array_levelsize(sym,level);
|
lval->constval=array_levelsize(sym,level);
|
||||||
}
|
}
|
||||||
if (lval->constval==0 && strchr((char *)lptr,PREPROC_TERM)==NULL)
|
if (lval->constval==0 && strchr((char *)lptr,PREPROC_TERM)==NULL)
|
||||||
error(224,st); /* indeterminate array size in "sizeof" expression */
|
error(163,st); /* indeterminate array size in "sizeof" expression */
|
||||||
} /* if */
|
} /* if */
|
||||||
ldconst(lval->constval,sPRI);
|
ldconst(lval->constval,sPRI);
|
||||||
while (paranthese--)
|
while (paranthese--)
|
||||||
@ -2212,7 +2212,7 @@ restart:
|
|||||||
*/
|
*/
|
||||||
sym=fetchfunc(lastsymbol);
|
sym=fetchfunc(lastsymbol);
|
||||||
if (sym==NULL)
|
if (sym==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
markusage(sym,uREAD);
|
markusage(sym,uREAD);
|
||||||
} else {
|
} else {
|
||||||
return error(12); /* invalid function call */
|
return error(12); /* invalid function call */
|
||||||
@ -2358,7 +2358,7 @@ static int primary(value *lval)
|
|||||||
assert(sc_status==statFIRST);
|
assert(sc_status==statFIRST);
|
||||||
sym=fetchfunc(st);
|
sym=fetchfunc(st);
|
||||||
if (sym==NULL)
|
if (sym==NULL)
|
||||||
error(163); /* insufficient memory */
|
error(FATAL_ERROR_OOM);
|
||||||
} /* if */
|
} /* if */
|
||||||
assert(sym!=NULL);
|
assert(sym!=NULL);
|
||||||
assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
|
assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
|
||||||
@ -2890,7 +2890,7 @@ static int nesting=0;
|
|||||||
if (asz!=NULL) {
|
if (asz!=NULL) {
|
||||||
array_sz=asz->value;
|
array_sz=asz->value;
|
||||||
if (array_sz==0)
|
if (array_sz==0)
|
||||||
error(224,arg[argidx].name); /* indeterminate array size in "sizeof" expression */
|
error(163,arg[argidx].name); /* indeterminate array size in "sizeof" expression */
|
||||||
} else {
|
} else {
|
||||||
array_sz=1;
|
array_sz=1;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
@ -754,6 +754,10 @@ void popreg(regid reg)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate an array
|
* Generate an array
|
||||||
|
* stk -= dims
|
||||||
|
* [stk] = hea
|
||||||
|
* stk += 1
|
||||||
|
* hea += 1 + (# cells in array)
|
||||||
*/
|
*/
|
||||||
void genarray(int dims, int _autozero)
|
void genarray(int dims, int _autozero)
|
||||||
{
|
{
|
||||||
|
@ -202,6 +202,13 @@ 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",
|
||||||
|
/*163*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n",
|
||||||
|
/*164*/ "allocated array type '%s' doesn't match original type '%s'\n",
|
||||||
|
/*165*/ "cannot create dynamic arrays in static 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",
|
||||||
@ -365,24 +372,24 @@ static const char *errmsg[] = {
|
|||||||
|
|
||||||
static const char *fatalmsg[] = {
|
static const char *fatalmsg[] = {
|
||||||
#ifdef SCPACK
|
#ifdef SCPACK
|
||||||
/*160*/ "cannot read from file: \"%s\"\n",
|
/*180*/ "cannot read from file: \"%s\"\n",
|
||||||
/*161*/ "cannot write to file: \"%s\"\n",
|
/*181*/ "cannot write to file: \"%s\"\n",
|
||||||
/*162*/ "table overflow: \"%s\"\n",
|
/*182*/ "table overflow: \"%s\"\n",
|
||||||
/* table can be: loop table
|
/* table can be: loop table
|
||||||
* literal table
|
* literal table
|
||||||
* staging buffer
|
* staging buffer
|
||||||
* option table (response file)
|
* option table (response file)
|
||||||
* peephole optimizer table
|
* peephole optimizer table
|
||||||
*/
|
*/
|
||||||
/*163*/ "insufficient memory\n",
|
/*183*/ "insufficient memory\n",
|
||||||
/*164*/ "invalid assembler instruction \"%s\"\n",
|
/*184*/ "invalid assembler instruction \"%s\"\n",
|
||||||
/*165*/ "numeric overflow, exceeding capacity\n",
|
/*185*/ "numeric overflow, exceeding capacity\n",
|
||||||
/*166*/ "compiled script exceeds the maximum memory size (%ld bytes)\n",
|
/*186*/ "compiled script exceeds the maximum memory size (%ld bytes)\n",
|
||||||
/*167*/ "too many error messages on one line\n",
|
/*187*/ "too many error messages on one line\n",
|
||||||
/*168*/ "codepage mapping file not found\n",
|
/*188*/ "codepage mapping file not found\n",
|
||||||
/*169*/ "invalid path: \"%s\"\n",
|
/*189*/ "invalid path: \"%s\"\n",
|
||||||
/*170*/ "assertion failed: %s\n",
|
/*190*/ "assertion failed: %s\n",
|
||||||
/*171*/ "user error: %s\n",
|
/*191*/ "user error: %s\n",
|
||||||
#else
|
#else
|
||||||
"\256\214a\204from \344le:\354",
|
"\256\214a\204from \344le:\354",
|
||||||
"\256writ\200\266 \344le:\354",
|
"\256writ\200\266 \344le:\354",
|
||||||
@ -425,7 +432,7 @@ static const char *warnmsg[] = {
|
|||||||
/*221*/ "label name \"%s\" shadows tag name\n",
|
/*221*/ "label name \"%s\" shadows tag name\n",
|
||||||
/*222*/ "number of digits exceeds rational number precision\n",
|
/*222*/ "number of digits exceeds rational number precision\n",
|
||||||
/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n",
|
/*223*/ "redundant \"sizeof\": argument size is always 1 (symbol \"%s\")\n",
|
||||||
/*224*/ "indeterminate array size in \"sizeof\" expression (symbol \"%s\")\n",
|
/*224*/ "unused\n",
|
||||||
/*225*/ "unreachable code\n",
|
/*225*/ "unreachable code\n",
|
||||||
/*226*/ "a variable is assigned to itself (symbol \"%s\")\n",
|
/*226*/ "a variable is assigned to itself (symbol \"%s\")\n",
|
||||||
/*227*/ "more initializers than enum fields\n",
|
/*227*/ "more initializers than enum fields\n",
|
||||||
|
@ -89,7 +89,7 @@ static short lastfile;
|
|||||||
* the error reporting is enabled only in the second pass (and only when
|
* the error reporting is enabled only in the second pass (and only when
|
||||||
* actually producing output). Fatal errors may never be ignored.
|
* actually producing output). Fatal errors may never be ignored.
|
||||||
*/
|
*/
|
||||||
int not_fatal = (number < 160 || number >= 200);
|
int not_fatal = (number < FIRST_FATAL_ERROR || number >= 200);
|
||||||
if (errflag && not_fatal)
|
if (errflag && not_fatal)
|
||||||
return 0;
|
return 0;
|
||||||
if (sc_status != statWRITE && not_fatal) {
|
if (sc_status != statWRITE && not_fatal) {
|
||||||
@ -105,13 +105,13 @@ static short lastfile;
|
|||||||
return 0;
|
return 0;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (number<160){
|
if (number<FIRST_FATAL_ERROR) {
|
||||||
msg=errmsg[number-1];
|
msg=errmsg[number-1];
|
||||||
pre=prefix[0];
|
pre=prefix[0];
|
||||||
errflag=TRUE; /* set errflag (skip rest of erroneous expression) */
|
errflag=TRUE; /* set errflag (skip rest of erroneous expression) */
|
||||||
errnum++;
|
errnum++;
|
||||||
} else if (number<200){
|
} else if (number<200){
|
||||||
msg=fatalmsg[number-160];
|
msg=fatalmsg[number-FIRST_FATAL_ERROR];
|
||||||
pre=prefix[1];
|
pre=prefix[1];
|
||||||
errnum++; /* a fatal error also counts as an error */
|
errnum++; /* a fatal error also counts as an error */
|
||||||
} else {
|
} else {
|
||||||
@ -154,7 +154,7 @@ static short lastfile;
|
|||||||
} /* if */
|
} /* if */
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
if ((number>=160 && number<200) || errnum>25){
|
if ((number>=FIRST_FATAL_ERROR && number<200) || errnum>25){
|
||||||
if (strlen(errfname)==0) {
|
if (strlen(errfname)==0) {
|
||||||
va_start(argptr,number);
|
va_start(argptr,number);
|
||||||
pc_error(0,"\nCompilation aborted.",NULL,0,0,argptr);
|
pc_error(0,"\nCompilation aborted.",NULL,0,0,argptr);
|
||||||
@ -175,7 +175,7 @@ static short lastfile;
|
|||||||
if (!is_warning)
|
if (!is_warning)
|
||||||
errorcount++;
|
errorcount++;
|
||||||
if (errorcount>=3)
|
if (errorcount>=3)
|
||||||
error(167); /* too many error/warning messages on one line */
|
error(FATAL_ERROR_OVERWHELMED_BY_BAD);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -920,12 +920,12 @@ static void splat_to_binary(const char *binfname, void *bytes, size_t size)
|
|||||||
// Note: error 161 will setjmp(), which skips destructors :(
|
// Note: error 161 will setjmp(), which skips destructors :(
|
||||||
FILE *fp = fopen(binfname, "wb");
|
FILE *fp = fopen(binfname, "wb");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
error(161, binfname);
|
error(FATAL_ERROR_WRITE, binfname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fwrite(bytes, 1, size, fp) != size) {
|
if (fwrite(bytes, 1, size, fp) != size) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
error(161, binfname);
|
error(FATAL_ERROR_WRITE, binfname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -95,14 +95,14 @@ static void grow_stgbuffer(char **buffer, int *curmax, int requiredsize)
|
|||||||
* over a few kBytes, there is probably a run-away expression
|
* over a few kBytes, there is probably a run-away expression
|
||||||
*/
|
*/
|
||||||
if (requiredsize>sSTG_MAX)
|
if (requiredsize>sSTG_MAX)
|
||||||
error(163); /* staging buffer overflow (fatal error) */
|
error(FATAL_ERROR_OOM);
|
||||||
*curmax=requiredsize+sSTG_GROW;
|
*curmax=requiredsize+sSTG_GROW;
|
||||||
if (*buffer!=NULL)
|
if (*buffer!=NULL)
|
||||||
p=(char *)realloc(*buffer,*curmax*sizeof(char));
|
p=(char *)realloc(*buffer,*curmax*sizeof(char));
|
||||||
else
|
else
|
||||||
p=(char *)malloc(*curmax*sizeof(char));
|
p=(char *)malloc(*curmax*sizeof(char));
|
||||||
if (p==NULL)
|
if (p==NULL)
|
||||||
error(163); /* staging buffer overflow (fatal error) */
|
error(FATAL_ERROR_OOM);
|
||||||
*buffer=p;
|
*buffer=p;
|
||||||
if (clear)
|
if (clear)
|
||||||
**buffer='\0';
|
**buffer='\0';
|
||||||
|
17
sourcepawn/compiler/tests/fail-bad-array-decls.sp
Normal file
17
sourcepawn/compiler/tests/fail-bad-array-decls.sp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
int[] gInvalid = {1};
|
||||||
|
|
||||||
|
public OnPluginStart()
|
||||||
|
{
|
||||||
|
int v = 10;
|
||||||
|
int invalid1[v];
|
||||||
|
int[] invalid2 = {1};
|
||||||
|
static int[] invalid3 = {1};
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalid_arg1(int invalid[])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void invalid_arg2(int[] invalid = {1, 2, 3})
|
||||||
|
{
|
||||||
|
}
|
7
sourcepawn/compiler/tests/fail-bad-array-decls.txt
Normal file
7
sourcepawn/compiler/tests/fail-bad-array-decls.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
(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
|
||||||
|
(8) : error 165: cannot create dynamic arrays in static scope - did you mean to create a fixed-length array with brackets after the variable name?
|
||||||
|
(11) : 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')
|
||||||
|
(15) : error 160: brackets in between type and variable name indicate a dynamic-size array, but a fixed-size initializer was given
|
||||||
|
|
4
sourcepawn/compiler/tests/fail-dynamic-array-bad-type.sp
Normal file
4
sourcepawn/compiler/tests/fail-dynamic-array-bad-type.sp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
public main()
|
||||||
|
{
|
||||||
|
int[] x = new float[3];
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
(3) : error 164: allocated array type 'float' doesn't match original type 'int'
|
@ -0,0 +1,8 @@
|
|||||||
|
native print(const char[] str);
|
||||||
|
native printnum(num);
|
||||||
|
|
||||||
|
public main()
|
||||||
|
{
|
||||||
|
char[] egg = "!\n";
|
||||||
|
return sizeof(egg);
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
(7) : error 163: indeterminate array size in "sizeof" expression (symbol "egg")
|
@ -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])
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
sourcepawn/compiler/tests/ok-new-dynamic-array-syntax.sp
Normal file
10
sourcepawn/compiler/tests/ok-new-dynamic-array-syntax.sp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
native printnum(num);
|
||||||
|
|
||||||
|
public main()
|
||||||
|
{
|
||||||
|
new x = 4;
|
||||||
|
new y = 8;
|
||||||
|
int[][] v = new int[4][8];
|
||||||
|
v[2][3] = 9;
|
||||||
|
printnum(v[2][3]);
|
||||||
|
}
|
@ -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