Fix a bug where aliased constructors of nullable methodmaps could not be used.
This commit is contained in:
parent
9f5c8b60ae
commit
157549e119
@ -246,6 +246,7 @@ struct methodmap_method_s;
|
|||||||
|
|
||||||
typedef struct value_s {
|
typedef struct value_s {
|
||||||
symbol *sym; /* symbol in symbol table, NULL for (constant) expression */
|
symbol *sym; /* symbol in symbol table, NULL for (constant) expression */
|
||||||
|
symbol *proxy; /* original symbol if resolved via a proxy */
|
||||||
cell constval; /* value of the constant expression (if ident==iCONSTEXPR)
|
cell constval; /* value of the constant expression (if ident==iCONSTEXPR)
|
||||||
* also used for the size of a literal array */
|
* also used for the size of a literal array */
|
||||||
int tag; /* tag (of the expression) */
|
int tag; /* tag (of the expression) */
|
||||||
@ -640,7 +641,7 @@ void delete_symbol(symbol *root,symbol *sym);
|
|||||||
void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
|
void delete_symbols(symbol *root,int level,int del_labels,int delete_functions);
|
||||||
int refer_symbol(symbol *entry,symbol *bywhom);
|
int refer_symbol(symbol *entry,symbol *bywhom);
|
||||||
void markusage(symbol *sym,int usage);
|
void markusage(symbol *sym,int usage);
|
||||||
symbol *findglb(const char *name,int filter);
|
symbol *findglb(const char *name,int filter,symbol **alias = NULL);
|
||||||
symbol *findloc(const char *name);
|
symbol *findloc(const char *name);
|
||||||
symbol *findconst(const char *name,int *matchtag);
|
symbol *findconst(const char *name,int *matchtag);
|
||||||
symbol *finddepend(const symbol *parent);
|
symbol *finddepend(const symbol *parent);
|
||||||
|
@ -2999,7 +2999,7 @@ void markusage(symbol *sym,int usage)
|
|||||||
*
|
*
|
||||||
* Returns a pointer to the global symbol (if found) or NULL (if not found)
|
* Returns a pointer to the global symbol (if found) or NULL (if not found)
|
||||||
*/
|
*/
|
||||||
symbol *findglb(const char *name,int filter)
|
symbol *findglb(const char *name, int filter, symbol **alias)
|
||||||
{
|
{
|
||||||
/* find a symbol with a matching automaton first */
|
/* find a symbol with a matching automaton first */
|
||||||
symbol *sym=NULL;
|
symbol *sym=NULL;
|
||||||
@ -3024,8 +3024,11 @@ symbol *findglb(const char *name,int filter)
|
|||||||
if (sym==NULL)
|
if (sym==NULL)
|
||||||
sym=FindInHashTable(sp_Globals,name,fcurrent);
|
sym=FindInHashTable(sp_Globals,name,fcurrent);
|
||||||
|
|
||||||
if (sym && sym->ident == iPROXY)
|
if (sym && sym->ident == iPROXY) {
|
||||||
|
if (alias)
|
||||||
|
*alias = sym;
|
||||||
return sym->target;
|
return sym->target;
|
||||||
|
}
|
||||||
|
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
@ -2265,7 +2265,12 @@ restart:
|
|||||||
error(4,symname); /* function not defined */
|
error(4,symname); /* function not defined */
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
if (sym->flags & flgPROXIED) {
|
// Check whether we're calling a constructor. This is a bit hacky, since
|
||||||
|
// we're relying on whatever the lval state is.
|
||||||
|
if ((sym->flags & flgPROXIED) &&
|
||||||
|
lval1->proxy &&
|
||||||
|
lval1->proxy->target == sym)
|
||||||
|
{
|
||||||
// Only constructors should be proxied, but we check anyway.
|
// Only constructors should be proxied, but we check anyway.
|
||||||
assert(!implicitthis);
|
assert(!implicitthis);
|
||||||
if (methodmap_t *methodmap = methodmap_find_by_tag(sym->tag)) {
|
if (methodmap_t *methodmap = methodmap_find_by_tag(sym->tag)) {
|
||||||
@ -2310,6 +2315,7 @@ restart:
|
|||||||
|
|
||||||
funcenum_t *fe = funcenum_for_symbol(target);
|
funcenum_t *fe = funcenum_for_symbol(target);
|
||||||
lval1->sym = NULL;
|
lval1->sym = NULL;
|
||||||
|
lval1->proxy = NULL;
|
||||||
lval1->ident = iCONSTEXPR;
|
lval1->ident = iCONSTEXPR;
|
||||||
lval1->constval = (public_index << 1) | 1;
|
lval1->constval = (public_index << 1) | 1;
|
||||||
lval1->tag = fe->tag;
|
lval1->tag = fe->tag;
|
||||||
@ -2396,7 +2402,8 @@ static int primary(value *lval)
|
|||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
/* now try a global variable */
|
/* now try a global variable */
|
||||||
if ((sym=findglb(st,sSTATEVAR))!=0) {
|
symbol *alias = NULL;
|
||||||
|
if ((sym = findglb(st, sSTATEVAR, &alias)) != 0) {
|
||||||
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
||||||
/* if the function is only in the table because it was inserted as a
|
/* if the function is only in the table because it was inserted as a
|
||||||
* stub in the first pass (i.e. it was "used" but never declared or
|
* stub in the first pass (i.e. it was "used" but never declared or
|
||||||
@ -2408,6 +2415,7 @@ static int primary(value *lval)
|
|||||||
if ((sym->usage & uDEFINE)==0)
|
if ((sym->usage & uDEFINE)==0)
|
||||||
error(17,st);
|
error(17,st);
|
||||||
lval->sym=sym;
|
lval->sym=sym;
|
||||||
|
lval->proxy=alias;
|
||||||
lval->ident=sym->ident;
|
lval->ident=sym->ident;
|
||||||
lval->tag=sym->tag;
|
lval->tag=sym->tag;
|
||||||
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
|
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
|
||||||
@ -2431,6 +2439,7 @@ static int primary(value *lval)
|
|||||||
assert(sym!=NULL);
|
assert(sym!=NULL);
|
||||||
assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
|
assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
|
||||||
lval->sym=sym;
|
lval->sym=sym;
|
||||||
|
lval->proxy=alias;
|
||||||
lval->ident=sym->ident;
|
lval->ident=sym->ident;
|
||||||
lval->tag=sym->tag;
|
lval->tag=sym->tag;
|
||||||
return FALSE; /* return 0 for function (not an lvalue) */
|
return FALSE; /* return 0 for function (not an lvalue) */
|
||||||
@ -2446,6 +2455,7 @@ static int primary(value *lval)
|
|||||||
static void clear_value(value *lval)
|
static void clear_value(value *lval)
|
||||||
{
|
{
|
||||||
lval->sym=NULL;
|
lval->sym=NULL;
|
||||||
|
lval->proxy=NULL;
|
||||||
lval->constval=0L;
|
lval->constval=0L;
|
||||||
lval->tag=0;
|
lval->tag=0;
|
||||||
lval->ident=0;
|
lval->ident=0;
|
||||||
|
12
sourcepawn/compiler/tests/ok-use-aliased-constructor.sp
Normal file
12
sourcepawn/compiler/tests/ok-use-aliased-constructor.sp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
native Handle:CreateHandle();
|
||||||
|
|
||||||
|
methodmap Handle __nullable__
|
||||||
|
{
|
||||||
|
public native Handle() = CreateHandle;
|
||||||
|
public native ~Handle();
|
||||||
|
};
|
||||||
|
|
||||||
|
public main()
|
||||||
|
{
|
||||||
|
CreateHandle();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user