LunaCON: add and document -Wnever-used-gamevar and -Wnever-read-gamevar.

git-svn-id: https://svn.eduke32.com/eduke32@4299 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2014-02-08 14:37:47 +00:00
parent 0d0f3a1cd2
commit bd34885653
2 changed files with 71 additions and 4 deletions

View file

@ -143,6 +143,14 @@ for a 32-bit integer, but inside that of an unsigned 32-bit integer. In this
case, 2^32^ is subtracted from the number, producing a negative value without case, 2^32^ is subtracted from the number, producing a negative value without
changing the bit representation. changing the bit representation.
`-Wnever-used-gamevar` (default: off)::
After translation, issues a warning for every CON-side user gamevar definition
that was never referenced, that is, neither read nor written in the CON code.
`-Wnever-read-gamevar` (default: off)::
After translation, issues a warning for every CON-side user gamevar definition
that was assigned to but never read in the CON code.
`-Wsystem-gamevar` (default: on):: `-Wsystem-gamevar` (default: on)::
Warns whenever the initial value of a system gamevar was overridden (by issuing Warns whenever the initial value of a system gamevar was overridden (by issuing
`gamevar` at file scope), but the provided gamevar flags did not match those of `gamevar` at file scope), but the provided gamevar flags did not match those of

View file

@ -119,7 +119,8 @@ local g_defaultDir = nil
-- -Wno-bad-identifier for disabling the "bad identifier" warning. -- -Wno-bad-identifier for disabling the "bad identifier" warning.
local g_warn = { ["not-redefined"]=true, ["bad-identifier"]=false, local g_warn = { ["not-redefined"]=true, ["bad-identifier"]=false,
["number-conversion"]=true, ["system-gamevar"]=true, ["number-conversion"]=true, ["system-gamevar"]=true,
["error-bad-getactorvar"]=false, ["chained-loadactor"]=true, } ["error-bad-getactorvar"]=false, ["chained-loadactor"]=true,
["never-used-gamevar"]=false, ["never-read-gamevar"]=false, }
-- Code generation and output options. -- Code generation and output options.
local g_cgopt = { ["no"]=false, ["debug-lineinfo"]=false, ["gendir"]=nil, local g_cgopt = { ["no"]=false, ["debug-lineinfo"]=false, ["gendir"]=nil,
@ -341,7 +342,8 @@ local function new_initial_gvartab()
local function GamevarCreationFunc(addflags) local function GamevarCreationFunc(addflags)
return function(varname) return function(varname)
return { name=varname, flags=GVFLAG.SYSTEM+addflags } -- 'used' is a bitmask: 1 is 'was read', 2 is 'was written to'
return { name=varname, flags=GVFLAG.SYSTEM+addflags, used=3 }
end end
end end
@ -1553,12 +1555,12 @@ function Cmd.gamevar(identifier, initval, flags)
-- Declare new session gamevar. -- Declare new session gamevar.
g_gamevar[identifier] = { name=format("_gv._sessionVar[%d]", g_numSessionVars), g_gamevar[identifier] = { name=format("_gv._sessionVar[%d]", g_numSessionVars),
flags=flags, loc=getLocation() } flags=flags, loc=getLocation(), used=0 }
g_numSessionVars = g_numSessionVars+1 g_numSessionVars = g_numSessionVars+1
return return
end end
local gv = { name=mangle_name(identifier, "V"), flags=flags, loc=getLocation() } local gv = { name=mangle_name(identifier, "V"), flags=flags, loc=getLocation(), used=0 }
g_gamevar[identifier] = gv g_gamevar[identifier] = gv
if (storeWithSavegames) then if (storeWithSavegames) then
@ -1624,6 +1626,8 @@ function lookup.gamevar(identifier, aorpvar, writable)
return "_READONLYGV" return "_READONLYGV"
end end
gv.used = bit.bor(gv.used, writable and 2 or 1)
if (bit.band(gv.flags, GVFLAG.PERACTOR)~=0) then if (bit.band(gv.flags, GVFLAG.PERACTOR)~=0) then
return format("%s[%s]", gv.name, aorpvar) return format("%s[%s]", gv.name, aorpvar)
elseif (bit.band(gv.flags, GVFLAG.CON_PERPLAYER)~=0 and g_cgopt["playervar"]) then elseif (bit.band(gv.flags, GVFLAG.CON_PERPLAYER)~=0 and g_cgopt["playervar"]) then
@ -1998,6 +2002,10 @@ function lookup.array_expr(writep, structname, index, membertab)
return "_INVALIDAV" return "_INVALIDAV"
end end
if (gv) then
gv.used = bit.bor(gv.used, writep and 2 or 1)
end
assert(#membertab == 1) assert(#membertab == 1)
return lookup.gamevar(membertab[1], index, writep) return lookup.gamevar(membertab[1], index, writep)
end end
@ -2108,6 +2116,10 @@ local function GetOrSetPerxvarCmd(Setp, Actorp)
idx = thisactor_to_pli(idx) idx = thisactor_to_pli(idx)
end end
if (gv) then
gv.used = bit.bor(gv.used, Setp and 2 or 1)
end
if (Setp) then if (Setp) then
return format("%s=%s", lookup.gamevar(perxvarname, idx, true), var) return format("%s=%s", lookup.gamevar(perxvarname, idx, true), var)
else else
@ -2252,6 +2264,8 @@ local handle =
-- even if we're saving it. -- even if we're saving it.
local code = lookup.gamevar(identifier, index, true) local code = lookup.gamevar(identifier, index, true)
gv.used = bit.bor(gv.used, not dosave and 2 or 1)
if (dosave) then if (dosave) then
return format("_con._savegamevar(%q,%s)", identifier, code) return format("_con._savegamevar(%q,%s)", identifier, code)
else else
@ -3730,6 +3744,51 @@ function parse(contents) -- local
end end
end end
-- Check read/written status of all user gamevars.
if (idx == #contents+1 and g_recurslevel==0) then
local gvs = {}
for identifier, gv in pairs(g_gamevar) do
if (gv.used ~= 3) then
-- NOTE: read but not written to gamevar (gv.used == 1) has its
-- use in C-CON
if (gv.used == 0 and g_warn["never-used-gamevar"] or
gv.used == 2 and g_warn["never-read-gamevar"]) then
gv.id = identifier
gvs[#gvs+1] = gv
end
end
end
function compare_gv(gva, gvb)
if (gva.loc[1] ~= gvb.loc[1]) then
return gva.loc[1] < gvb.loc[1]
end
return (gva.loc[2] < gvb.loc[2])
end
table.sort(gvs, compare_gv)
for i=1,#gvs do
local gv = gvs[i]
local loc = gv.loc
local locstr = loc and format("%s %d:%d: ", loc[1], loc[2], loc[3]) or ""
local perActor = (bit.band(gv.flags, GVFLAG.PERACTOR) ~= 0)
local perPlayer = (bit.band(gv.flags, GVFLAG.PERPLAYER) ~= 0)
local kindstr = perActor and "per-actor " or (perPlayer and "per-player " or "")
if (gv.used == 0) then
printf("%sWarning: never used %sgamevar `%s'", locstr,
kindstr, gv.id)
else
printf("%sWarning: never %s %sgamevar `%s'", locstr,
gv.used == 1 and "written to" or "read",
kindstr, gv.id)
end
end
end
addcodef("-- END %s", g_filename) addcodef("-- END %s", g_filename)
g_recurslevel = g_recurslevel-1 g_recurslevel = g_recurslevel-1