[Toybox] [PATCH] Fix flags that don't fit in 32 bits.
Rob Landley
rob at landley.net
Tue Feb 25 11:07:52 PST 2020
On 2/23/20 1:25 PM, enh via Toybox wrote:
> Fixes https://github.com/landley/toybox/issues/164.
I'm out with my laptop somewhere I can't get net (for some reason the broken
wifi here interferes with my phone associating as an access point, and I only
brought a normal USB cable, not USB-C). I thought I'd look at the patch itself
to see if that had a description of what it was fixing, but no. (Did I need to
pass a second flag to reproduce this, or...)
Luckily I figured it out, but locality of context vs external references are a
thing.
> --- a/scripts/mkflags.c
> +++ b/scripts/mkflags.c
> @@ -220,7 +220,7 @@ int main(int argc, char *argv[])
> out += strlen(out);
>
> while (aflist) {
> - char *llstr = bit>31 ? "LL" : "", *s = (char []){0, 0, 0, 0};
> + char *s = (char []){0, 0, 0, 0};
> int enabled = 0;
The smallest fix is replacing the "31" with a "30", since 1<<31 as a signed int
becomes unsigned and sets lots more flags. (That's the bug, an off-by-one.)
> // Output flag macro for bare longopts
> @@ -235,8 +235,8 @@ int main(int argc, char *argv[])
> if (flist && flist->command && *aflist->command == *flist->command)
> enabled++;
> }
> - out += sprintf(out, "#define FLAG_%s (%s%s<<%d)\n",
> - s, enabled ? "1" : "FORCED_FLAG", llstr, bit++);
> + out += sprintf(out, "#define FLAG_%s (%sULL<<%d)\n",
> + s, enabled ? "1" : "FORCED_FLAG", bit++);
How... does that ever work at all?
printf("#undef FORCED_FLAG\n#undef FORCED_FLAGLL\n"
"#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n#define FORCED_FLAGLL 1ULL\n"
"#else\n#define FORCED_FLAG 0\n#define FORCED_FLAGLL 0\n#endif\n\n");
You're printing out #define FLAG_%s (FORCED_FLAGULL<<1), is it ignoring the
FORCED_FLAGLL macro and instead having FORCED_FLAGULL match the shorter macro
and then the ULL append to it?
cat > hello.c << EOF
#include <stdio.h>
#define WALRUS 1
int main(int argc, char *argv[])
{
dprintf(2, "%ld\n", WALRUSULL);
}
EOF
$ gcc hello.c
hello.c: In function ‘main’:
hello.c:7:23: error: ‘WALRUSULL’ undeclared (first use in this function)
dprintf(2, "%ld\n", WALRUSULL);
No? That's not it? And I can't append a space to force the macro resolution
becaue "1 ULL" isn't parsed the same as "1ULL". Hmmm...
Rob
P.S. I didn't want to have the constants all be long long because when it _can_
use shorter math in the flag macros (which is the common case) I want it to. But
I guess you're trusting the optimizer to notice that?
More information about the Toybox
mailing list