diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index c819b4a99..74b65195f 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -754,6 +754,22 @@ StructAccessCode = player = PlayerLabels, } +local function tonegtag(LabelsTab, member, funcname) + local memb = LabelsTab[member] + LabelsTab[member] = { memb, memb.."="..funcname.."(%%s)" } +end + +function setup_negative_tag_check(funcname) + tonegtag(TspriteLabels, "tsprlotag", funcname) + tonegtag(TspriteLabels, "tsprhitag", funcname) + tonegtag(ActorLabels, "lotag", funcname) + tonegtag(ActorLabels, "hitag", funcname) + tonegtag(WallLabels, "lotag", funcname) + tonegtag(WallLabels, "hitag", funcname) + tonegtag(SectorLabels, "lotag", funcname) + tonegtag(SectorLabels, "hitag", funcname) +end + local PROJ = function(memb) return "projectile[%s]"..memb end local THISPROJ = function(memb) return "actor[%s].proj"..memb end diff --git a/polymer/eduke32/source/lunatic/control.lua b/polymer/eduke32/source/lunatic/control.lua index 4b2f8fa83..cf14c7419 100644 --- a/polymer/eduke32/source/lunatic/control.lua +++ b/polymer/eduke32/source/lunatic/control.lua @@ -528,6 +528,13 @@ function _get_userdef(pli) return ffiC.ud end +function _err_if_negative(val) + if (not (val >= 0)) then + error("setting tag to negative value", 2) + end + return val +end + --- player/actor/sprite searching functions --- local xmath = require("xmath") diff --git a/polymer/eduke32/source/lunatic/doc/lunacon.txt b/polymer/eduke32/source/lunatic/doc/lunacon.txt index feda13f01..9ae7a4147 100644 --- a/polymer/eduke32/source/lunatic/doc/lunacon.txt +++ b/polymer/eduke32/source/lunatic/doc/lunacon.txt @@ -181,6 +181,16 @@ If enabled, an attept to issue `getuserdef` or `setuserdef` when the current player doesn't equal the local player generates an error. Otherwise, the userdef structure can be accessed irrespective of the current player. +`-ferror-negative-tag-write` (default: off):: +If enabled, an attempt to assign a negative value to the `lotag` or `hitag` +member of the sector, wall or (t)sprite structures produces an error. +Normally, it is legal to assign negative values to these members, but since +they are unsigned 16-bit integers on the C side, such values will be converted +to positive ones and may entail undesired behavior. ++ +NOTE: From CON as well as Lunatic, `hitag` and `lotag` are seen as *signed* +16-bit integers. + `-fbad-getactorvar-use-pli` (default: off):: If enabled and `-Werror-bad-getactorvar` is off, a `getactorvar` of a per-player variable will result the gamevar being indexed with the current diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index ef296475f..c63dd286c 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -127,7 +127,8 @@ local g_cgopt = { ["no"]=false, ["debug-lineinfo"]=false, ["gendir"]=nil, ["cache-sap"]=false, ["error-nostate"]=true, ["playervar"]=true, ["trapv"]=false, ["wrapv"]=false, ["bad-getactorvar-use-pli"]=false, - ["error-nonlocal-userdef"]=true, } + ["error-nonlocal-userdef"]=true, + ["error-negative-tag-write"]=false, } local function csapp() return g_cgopt["cache-sap"] end @@ -230,6 +231,10 @@ else end end +if (g_cgopt["error-negative-tag-write"]) then + conl.setup_negative_tag_check("_st") +end + -- Stack with *true* on top if the innermost block is a "whilevar*n". local g_isWhile = {} -- Sequence number of 'while' statements, used to implement CON "break" inside @@ -309,6 +314,7 @@ local function new_initial_codetab() "local _setsprite,_ssp = _con._setsprite,_con._ssp", g_cgopt["error-nonlocal-userdef"] and "local _gud=_con._get_userdef_check" or "local _gud=_con._get_userdef", + "local _st=_con._err_if_negative", -- * CON "states" (subroutines) and -- * Switch function table, indexed by global switch sequence number: