Christoph Moench-Tegeder
2013-12-28 22:28:21 UTC
Hi,
when building ast-ksh (2012-08-01, which seems to be the latest "production"
release) on freebsd10.i386 with clang, the build failed in
src/lib/libast/hash/hashalloc.c:154 with the error message
: error: non-const lvalue reference to type '__builtin_va_list' cannot bind to a temporary of type 'va_list' (aka 'char *')
The same happens in src/lib/libast/string/tokscan.c.
After tracking that down to the va_copy/va_listval #defines generated
via src/lib/libast/features/common, I found that the issue had been
addressed sometime between the 2012-08-01 release and the current alpha
(2013-12-06) with some #ifdefs in hashalloc.c and tokscan.c. (There's
no changelog entry about that, and I failed to find a public source
repository.)
The solution I came up with even does not require those #ifdef constructs,
as it takes advantages of va_listarg #define provided by features/common.
The patch is at http://burggraben.net/hacks/ksh-valist-fix.gz (as some
mail system will surely mangle it), and enclosed inline for your
convenience.
I tested the quivalent patch against ast-ksh 2012-08-01 on
- freebsd10.i386 (clang)
- freebsd10.amd64 (clang)
- freebsd9.amd64 (gcc)
and the shell works fine so far.
Here's the patch:
--- src/lib/libast/hash/hashalloc.c.orig 2013-12-28 22:54:11.000000000 +0100
+++ src/lib/libast/hash/hashalloc.c 2013-12-28 22:57:07.000000000 +0100
@@ -47,6 +47,7 @@
va_list ap;
va_list va[4];
va_list* vp = va;
+ va_listarg np;
Hash_region_f region = 0;
void* handle;
@@ -151,16 +152,8 @@
va_copy(*vp, ap);
vp++;
}
-#if __clang__ && __SIZEOF_POINTER__ == 4
- {
- va_list np;
-
- np = va_listval(va_arg(ap, va_listarg));
- va_copy(ap, np);
- }
-#else
- va_copy(ap, va_listval(va_arg(ap, va_listarg)));
-#endif
+ np = va_listval(va_arg(ap, va_listarg));
+ va_copy(ap, np);
break;
case 0:
if (vp > va)
--- src/lib/libast/string/tokscan.c.orig 2013-12-28 22:53:53.000000000 +0100
+++ src/lib/libast/string/tokscan.c 2013-12-28 22:56:11.000000000 +0100
@@ -197,6 +197,7 @@
char** p_string;
char* prv_f = 0;
va_list prv_ap;
+ va_listarg np;
va_start(ap, fmt);
if (!*s || *s == '\n')
@@ -242,16 +243,8 @@
prv_f = f;
f = va_arg(ap, char*);
va_copy(prv_ap, ap);
-#if __clang__ && __SIZEOF_POINTER__ == 4
- {
- va_list np;
-
- np = va_listval(va_arg(ap, va_listarg));
- va_copy(ap, np);
- }
-#else
- va_copy(ap, va_listval(va_arg(ap, va_listarg)));
-#endif
+ np = va_listval(va_arg(ap, va_listarg));
+ va_copy(ap, np);
continue;
case 'c':
p_char = va_arg(ap, char*);
Regards,
Christoph
when building ast-ksh (2012-08-01, which seems to be the latest "production"
release) on freebsd10.i386 with clang, the build failed in
src/lib/libast/hash/hashalloc.c:154 with the error message
: error: non-const lvalue reference to type '__builtin_va_list' cannot bind to a temporary of type 'va_list' (aka 'char *')
The same happens in src/lib/libast/string/tokscan.c.
After tracking that down to the va_copy/va_listval #defines generated
via src/lib/libast/features/common, I found that the issue had been
addressed sometime between the 2012-08-01 release and the current alpha
(2013-12-06) with some #ifdefs in hashalloc.c and tokscan.c. (There's
no changelog entry about that, and I failed to find a public source
repository.)
The solution I came up with even does not require those #ifdef constructs,
as it takes advantages of va_listarg #define provided by features/common.
The patch is at http://burggraben.net/hacks/ksh-valist-fix.gz (as some
mail system will surely mangle it), and enclosed inline for your
convenience.
I tested the quivalent patch against ast-ksh 2012-08-01 on
- freebsd10.i386 (clang)
- freebsd10.amd64 (clang)
- freebsd9.amd64 (gcc)
and the shell works fine so far.
Here's the patch:
--- src/lib/libast/hash/hashalloc.c.orig 2013-12-28 22:54:11.000000000 +0100
+++ src/lib/libast/hash/hashalloc.c 2013-12-28 22:57:07.000000000 +0100
@@ -47,6 +47,7 @@
va_list ap;
va_list va[4];
va_list* vp = va;
+ va_listarg np;
Hash_region_f region = 0;
void* handle;
@@ -151,16 +152,8 @@
va_copy(*vp, ap);
vp++;
}
-#if __clang__ && __SIZEOF_POINTER__ == 4
- {
- va_list np;
-
- np = va_listval(va_arg(ap, va_listarg));
- va_copy(ap, np);
- }
-#else
- va_copy(ap, va_listval(va_arg(ap, va_listarg)));
-#endif
+ np = va_listval(va_arg(ap, va_listarg));
+ va_copy(ap, np);
break;
case 0:
if (vp > va)
--- src/lib/libast/string/tokscan.c.orig 2013-12-28 22:53:53.000000000 +0100
+++ src/lib/libast/string/tokscan.c 2013-12-28 22:56:11.000000000 +0100
@@ -197,6 +197,7 @@
char** p_string;
char* prv_f = 0;
va_list prv_ap;
+ va_listarg np;
va_start(ap, fmt);
if (!*s || *s == '\n')
@@ -242,16 +243,8 @@
prv_f = f;
f = va_arg(ap, char*);
va_copy(prv_ap, ap);
-#if __clang__ && __SIZEOF_POINTER__ == 4
- {
- va_list np;
-
- np = va_listval(va_arg(ap, va_listarg));
- va_copy(ap, np);
- }
-#else
- va_copy(ap, va_listval(va_arg(ap, va_listarg)));
-#endif
+ np = va_listval(va_arg(ap, va_listarg));
+ va_copy(ap, np);
continue;
case 'c':
p_char = va_arg(ap, char*);
Regards,
Christoph
--
Spare Space
Spare Space