Compiler warnings on FreeBSD

29 views
Skip to first unread message

Jure Bagić

unread,
Sep 2, 2026, 11:17:18 AM (2 days ago) Sep 2
to lua-l
Recently I have setup FreeBSD guest, and compiled latest Lua (7579fc9).

Build flags:
```
CC = clang
CFLAGS = -Wall -O2 -std=c99 -DLUA_USE_POSIX -fno-stack-protector -fno-common
AR = ar rc
RANLIB = ranlib
MYLDFLAGS = -Wl,-E
MYLIBS = -ldl
```
(CFLAGS also includes all the other warnings in the original makefile that are
also valid for clang.)

In ldebug.c:153, lvm.c:1214 and lvm.c:1120.
The 'sig_atomic_t' is 8 bytes on FreeBSD amd64 so the following warning is
generated:
```
implicit conversion loses integer precision: 'volatile sig_atomic_t' (aka
'volatile long') to 'int' [-Wshorten-64-to-32]
```

One more thing, the tests for 'os.time' will fail, this is because the FreeBSD
libc has a bug in 'mktime'. When it checks if the 'tm_year' is a leap year, it
adds 1900 to it and thus overflowing 'tm_year' when 'tm_year' is in range
[INT_MAX-1899, INT_MAX]. While glibc does a proper job to not overflow.
There are other bugs in 'mktime' on this platform, it keep setting EOVERFLOW
errno but does not return '-1' (meaning, input was valid).

However, in regards to Lua, here is what POSIX spec says about 'mktime':
```
If the time since the Epoch cannot be represented as a time_t or the value to
be returned in the tm_year member of the structure pointed to by timeptr cannot
be represented as an int, the function shall return the value (time_t)−1 and set
errno to [EOVERFLOW], and shall not change the value of the tm_wday component
of the structure.
Since (time_t)−1 is a valid return value for a successful call to mktime( ),
an application wishing to check for error situations should set tm_wday to
a value less than 0 or greater than 6 before calling mktime( ).
On return, if tm_wday has not changed an error has occurred.
```

So the error check in 'os_time' needs to be updated to something like this:
```
static int os_time (lua_State *L) {
time_t t;
+ struct tm ts;
+ ts.tm_wday = -1;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
else {
- struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_year = getfield(L, "year", -1, 1900);
ts.tm_mon = getfield(L, "month", -1, 1);
ts.tm_mday = getfield(L, "day", -1, 0);
ts.tm_hour = getfield(L, "hour", 12, 0);
ts.tm_min = getfield(L, "min", 0, 0);
ts.tm_sec = getfield(L, "sec", 0, 0);
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
setallfields(L, &ts); /* update fields with normalized values */
}
- if (t != (time_t)(l_timet)t || t == (time_t)(-1))
+ if (t != (time_t)(l_timet)t || (t == (time_t)(-1) && ts.tm_wday == -1))
return luaL_error(L,
"time result cannot be represented in this installation");
l_pushtime(L, t);
return 1;
}
```

-- Jure
signature.asc

Roberto Ierusalimschy

unread,
Sep 2, 2026, 1:17:50 PM (2 days ago) Sep 2
to lu...@googlegroups.com
Many thanks for both feedbacks.
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/apgvA0foVjQu7nUO%40archlinux.




-- Roberto
Reply all
Reply to author
Forward
0 new messages