Skip to content

Commit d562f5d

Browse files
Peter Neissclaude
andcommitted
Phase 116.1: Fix Clang 15 sign-conversion errors in span accessors
Fixed implicit sign conversion errors when using std::span with integer indices. Changed loop variables from 'int' to 'size_t' where used as span indices. Files modified: - src/core/ldebug.cpp: Fixed 3 functions (luaG_getfuncline, nextline, changedline, collectvalidlines) to use size_t for span indexing - src/objects/ltable.cpp: Fixed NodeArray::allocate overflow check - src/serialization/lundump.cpp: Fixed loadConstants, loadUpvalues, loadDebug to use size_t loop variables Critical fix in luaG_getfuncline: Changed loop from 'i < pc' to 'i <= pc' to match original while(basepc++ < pc) semantics (process indices basepc+1 through pc inclusive). All tests passing with GCC 13 and Clang 15 in Release and Debug modes. Performance: 2.26-2.56s (well within target ≤4.33s) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent bf12327 commit d562f5d

File tree

3 files changed

+17
-18
lines changed

3 files changed

+17
-18
lines changed

src/core/ldebug.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,10 @@ int luaG_getfuncline (const Proto *f, int pc) {
9696
else {
9797
int basepc;
9898
int baseline = getbaseline(f, pc, &basepc);
99-
while (basepc++ < pc) { /* walk until given instruction */
100-
lua_assert(lineInfoSpan[basepc] != ABSLINEINFO);
101-
baseline += lineInfoSpan[basepc]; /* correct line */
99+
/* Walk from basepc+1 to pc (inclusive), accumulating line deltas */
100+
for (size_t i = static_cast<size_t>(basepc + 1); i <= static_cast<size_t>(pc); i++) {
101+
lua_assert(lineInfoSpan[i] != ABSLINEINFO);
102+
baseline += lineInfoSpan[i]; /* correct line */
102103
}
103104
return baseline;
104105
}
@@ -295,12 +296,12 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
295296

296297

297298
// Phase 115.2: Use span accessors
298-
static int nextline (const Proto *p, int currentline, int pc) {
299+
static int nextline (const Proto *p, int currentline, size_t pc) {
299300
auto lineInfoSpan = p->getDebugInfo().getLineInfoSpan();
300301
if (lineInfoSpan[pc] != ABSLINEINFO)
301302
return currentline + lineInfoSpan[pc];
302303
else
303-
return luaG_getfuncline(p, pc);
304+
return luaG_getfuncline(p, static_cast<int>(pc));
304305
}
305306

306307

@@ -317,7 +318,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
317318
api_incr_top(L);
318319
auto lineInfoSpan = p->getDebugInfo().getLineInfoSpan();
319320
if (!lineInfoSpan.empty()) { /* proto with debug information? */
320-
int i;
321+
size_t i;
321322
TValue v;
322323
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
323324
if (!(p->getFlag() & PF_ISVARARG)) /* regular function? */
@@ -328,7 +329,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
328329
currentline = nextline(p, currentline, 0);
329330
i = 1; /* skip first instruction (OP_VARARGPREP) */
330331
}
331-
for (; i < static_cast<int>(lineInfoSpan.size()); i++) { /* for each instruction */
332+
for (; i < lineInfoSpan.size(); i++) { /* for each instruction */
332333
currentline = nextline(p, currentline, i); /* get its line */
333334
luaH_setint(L, t, currentline, &v); /* table[line] = true */
334335
}
@@ -953,13 +954,14 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
953954
return 0;
954955
if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */
955956
int delta = 0; /* line difference */
956-
int pc = oldpc;
957+
size_t pc = static_cast<size_t>(oldpc);
957958
for (;;) {
958-
int lineinfo = lineInfoSpan[++pc];
959+
++pc;
960+
int lineinfo = lineInfoSpan[pc];
959961
if (lineinfo == ABSLINEINFO)
960962
break; /* cannot compute delta; fall through */
961963
delta += lineinfo;
962-
if (pc == newpc)
964+
if (static_cast<int>(pc) == newpc)
963965
return (delta != 0); /* delta computed successfully */
964966
}
965967
}

src/objects/ltable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class NodeArray {
111111
// Large table: allocate Limbox + Node[]
112112
// LAYOUT: [Limbox header][Node array of size n]
113113
// Verify no overflow in size calculation
114-
if (n > (MAX_SIZET - sizeof(Limbox)) / sizeof(Node)) {
114+
if (static_cast<size_t>(n) > (MAX_SIZET - sizeof(Limbox)) / sizeof(Node)) {
115115
luaG_runerror(L, "table size overflow");
116116
}
117117
size_t total = sizeof(Limbox) + n * sizeof(Node);

src/serialization/lundump.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,15 +213,14 @@ static void loadFunction(LoadState *S, Proto *f);
213213

214214
// Phase 115.2: Use span accessors
215215
static void loadConstants (LoadState *S, Proto *f) {
216-
int i;
217216
int n = loadInt(S);
218217
f->setConstants(luaM_newvectorchecked(S->L, n, TValue));
219218
f->setConstantsSize(n);
220219
auto constantsSpan = f->getConstantsSpan();
221220
for (TValue& v : constantsSpan) {
222221
setnilvalue(&v);
223222
}
224-
for (i = 0; i < n; i++) {
223+
for (size_t i = 0; i < static_cast<size_t>(n); i++) {
225224
TValue *o = &constantsSpan[i];
226225
int t = loadByte(S);
227226
switch (t) {
@@ -278,7 +277,6 @@ static void loadProtos (LoadState *S, Proto *f) {
278277
*/
279278
// Phase 115.2: Use span accessors
280279
static void loadUpvalues (LoadState *S, Proto *f) {
281-
int i;
282280
int n = loadInt(S);
283281
f->setUpvalues(luaM_newvectorchecked(S->L, n, Upvaldesc));
284282
f->setUpvaluesSize(n);
@@ -287,7 +285,7 @@ static void loadUpvalues (LoadState *S, Proto *f) {
287285
for (Upvaldesc& uv : upvaluesSpan) {
288286
uv.setName(nullptr);
289287
}
290-
for (i = 0; i < n; i++) { /* following calls can raise errors */
288+
for (size_t i = 0; i < static_cast<size_t>(n); i++) { /* following calls can raise errors */
291289
upvaluesSpan[i].setInStack(loadByte(S));
292290
upvaluesSpan[i].setIndex(loadByte(S));
293291
upvaluesSpan[i].setKind(loadByte(S));
@@ -297,7 +295,6 @@ static void loadUpvalues (LoadState *S, Proto *f) {
297295

298296
// Phase 115.2: Use span accessors
299297
static void loadDebug (LoadState *S, Proto *f) {
300-
int i;
301298
int n = loadInt(S);
302299
if (S->fixed) {
303300
f->setLineInfo(getaddr(S, n, ls_byte));
@@ -330,7 +327,7 @@ static void loadDebug (LoadState *S, Proto *f) {
330327
for (LocVar& lv : locVarsSpan) {
331328
lv.setVarName(nullptr);
332329
}
333-
for (i = 0; i < n; i++) {
330+
for (size_t i = 0; i < static_cast<size_t>(n); i++) {
334331
loadString(S, f, locVarsSpan[i].getVarNamePtr());
335332
locVarsSpan[i].setStartPC(loadInt(S));
336333
locVarsSpan[i].setEndPC(loadInt(S));
@@ -339,7 +336,7 @@ static void loadDebug (LoadState *S, Proto *f) {
339336
if (n != 0) /* does it have debug information? */
340337
n = f->getUpvaluesSize(); /* must be this many */
341338
auto upvaluesSpan = f->getUpvaluesSpan();
342-
for (i = 0; i < n; i++)
339+
for (size_t i = 0; i < static_cast<size_t>(n); i++)
343340
loadString(S, f, upvaluesSpan[i].getNamePtr());
344341
}
345342

0 commit comments

Comments
 (0)