Skip to content

Commit

Permalink
Add "unused" warning
Browse files Browse the repository at this point in the history
  • Loading branch information
Sainan committed Nov 6, 2024
1 parent 483e081 commit 168cc3c
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 10 deletions.
5 changes: 5 additions & 0 deletions src/llex.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ enum WarningType : int {
WT_UNANNOTATED_FALLTHROUGH,
WT_DISCARDED_RETURN,
WT_FIELD_SHADOW,
WT_UNUSED,

NUM_WARNING_TYPES
};
Expand All @@ -232,6 +233,7 @@ inline const char* const luaX_warnNames[] = {
"unannotated-fallthrough",
"discarded-return",
"field-shadow",
"unused",
};
static_assert(sizeof(luaX_warnNames) / sizeof(const char*) == NUM_WARNING_TYPES);

Expand Down Expand Up @@ -263,6 +265,9 @@ class WarningConfig
#endif
#ifndef PLUTO_WARN_NON_PORTABLE_NAME
case WT_NON_PORTABLE_NAME:
#endif
#ifndef PLUTO_WARN_UNSUED
case WT_UNUSED: /* it kills me that I can't enable this by default but our test suite is horrible right now */
#endif
case NUM_WARNING_TYPES: /* dummy case so compiler doesn't cry when all macros are set */
return WS_OFF;
Expand Down
33 changes: 23 additions & 10 deletions src/lparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,7 @@ static int registerlocalvar (LexState *ls, FuncState *fs, TString *varname) {


#define new_localvarliteral(ls,v) \
new_localvar(ls, \
luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1));
new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char)) - 1), {}, true);


[[nodiscard]] static TypeHint* new_typehint (LexState *ls) {
Expand Down Expand Up @@ -694,7 +693,7 @@ static void checkforshadowing (LexState *ls, FuncState *fs, const std::unordered
** Create a new local variable with the given 'name'. Return its index
** in the function.
*/
static int new_localvar (LexState *ls, TString *name, int line, TypeHint hint = {}, bool check_globals = true) {
static int new_localvar (LexState *ls, TString *name, int line, TypeHint hint = {}, bool check_globals = true, bool used = false) {
lua_State *L = ls->L;
FuncState *fs = ls->fs;
Dyndata *dyd = ls->dyd;
Expand All @@ -710,11 +709,12 @@ static int new_localvar (LexState *ls, TString *name, int line, TypeHint hint =
*var->vd.hint = std::move(hint);
var->vd.name = name;
var->vd.line = line;
var->vd.used = used;
return dyd->actvar.n - 1 - fs->firstlocal;
}

static int new_localvar (LexState *ls, TString *name, TypeHint hint = {}) {
return new_localvar(ls, name, ls->getLineNumber(), std::move(hint));
static int new_localvar (LexState *ls, TString *name, TypeHint hint = {}, bool used = false) {
return new_localvar(ls, name, ls->getLineNumber(), std::move(hint), true, used);
}


Expand All @@ -725,7 +725,9 @@ static void init_var (FuncState *fs, expdesc *e, int vidx) {
e->f = e->t = NO_JUMP;
e->k = VLOCAL;
e->u.var.vidx = vidx;
e->u.var.ridx = getlocalvardesc(fs, vidx)->vd.ridx;
Vardesc *vd = getlocalvardesc(fs, vidx);
e->u.var.ridx = vd->vd.ridx;
vd->vd.used = true;
}


Expand Down Expand Up @@ -789,6 +791,15 @@ static void removevars (FuncState *fs, int tolevel) {
LocVar *var = localdebuginfo(fs, --fs->nactvar);
if (var) /* does it have debug information? */
var->endpc = fs->pc;
Vardesc *vd = getlocalvardesc(fs, fs->nactvar);
if (!vd->vd.used
&& (vd->vd.kind == VDKREG || vd->vd.kind == RDKTOCLOSE) /* only care if variable is in a register + we don't detect constants being used */
&& getstr(vd->vd.name)[0] != '_' /* common prefix for intentionally unused variables, assume it's intentional */
&& !eqstr(vd->vd.name, luaX_newliteral(fs->ls, "self")) /* not an issue if the var is generated by Pluto, but still possible with manual method definition */
) {
throw_warn(fs->ls, "unused local variable", luaO_fmt(fs->ls->L, "'%s' is unused", getstr(vd->vd.name)), vd->vd.line, WT_UNUSED);
fs->ls->L->top.p--; /* pop result of luaO_fmt */
}
}
}

Expand Down Expand Up @@ -825,8 +836,10 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
if (v->k == VLOCAL) {
up->instack = 1;
up->idx = v->u.var.ridx;
up->kind = getlocalvardesc(prev, v->u.var.vidx)->vd.kind;
lua_assert(eqstr(name, getlocalvardesc(prev, v->u.var.vidx)->vd.name));
Vardesc *vd = getlocalvardesc(prev, v->u.var.vidx);
up->kind = vd->vd.kind;
lua_assert(eqstr(name, vd->vd.name));
vd->vd.used = true;
}
else {
lua_assert(v->k == VUPVAL);
Expand Down Expand Up @@ -4305,9 +4318,9 @@ static void forvlist (LexState *ls, TypeHint *prop) {
new_localvarliteral(ls, "(for state)");
new_localvarliteral(ls, "(for state)");
/* create variable for key */
new_localvar(ls, luaS_newliteral(ls->L, "(for state)"));
new_localvar(ls, luaS_newliteral(ls->L, "(for state)"), {}, true);
/* create variable for value */
int vidx = new_localvar(ls, luaS_newliteral(ls->L, "(for state)"));
int vidx = new_localvar(ls, luaS_newliteral(ls->L, "(for state)"), {}, true);
nvars++;

line = ls->getLineNumber();
Expand Down
1 change: 1 addition & 0 deletions src/lparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ typedef union Vardesc {
short pidx; /* index of the variable in the Proto's 'locvars' array */
TString *name; /* variable name */
int line;
bool used;
} vd;
TValue k; /* constant value (if any) */
} Vardesc;
Expand Down
3 changes: 3 additions & 0 deletions src/luaconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,9 @@
// If defined, the "non-portable-name" warning is enabled by default.
//#define PLUTO_WARN_NON_PORTABLE_NAME

// If defined, the "unused" warning is enabled by default.
//#define PLUTO_WARN_UNUSED

/*
** {====================================================================
** Pluto Configuration: Compatibility
Expand Down

0 comments on commit 168cc3c

Please sign in to comment.