summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-09-08 01:05:33 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-09-08 01:05:33 -0700
commit963e1ea9685f0c28a70635f2ef6450f8a4d1c7c6 (patch)
treeecca945d7cce67482213f7dabfa6e8c6029560bd
parent594ff00bcf230fd916dd710e83fe66d071abf0c6 (diff)
downloadtxr-963e1ea9685f0c28a70635f2ef6450f8a4d1c7c6.tar.gz
txr-963e1ea9685f0c28a70635f2ef6450f8a4d1c7c6.tar.bz2
txr-963e1ea9685f0c28a70635f2ef6450f8a4d1c7c6.zip
gcc11: warnings related to struct args allocation..
As reported by Paul A. Patience, GCC 11 warns about situations in a few places where we do args_decl(args, 0) to allocate an absolutely empty argument list object. (This by the way, is only done in places where we are absolutely sure that the function we call will not be accessing the arguments. The usual rule is that there have to be at least ARGS_MIN arguments allocated, currently 4, and code relies on that being the case! So the places which call args_decl(args, 0) are coded carefully, checking that args is not passed anywhere where ARGS_MIN space is required.) Anyway, in the 0 case, the val arg[1] member of struct args is not allocated at all, because we call alloca(offsetof (struct args, arg)). Now GCC 11 notices this and complains that accesses to the other members like args->fill or args->list are using a struct that has not been entirely allocated. This, even though those members lie entirely within the allocated area. The fix for this is two faceted. Firstly, on C99, this diagnostic goes away if we make one simple change: declare the arg array as a flexible array member: val arg[]. However, we still support C90 in maintainer mode. So in maintainer mode, we stick with the 1. But we ensure that the places which call args_decl(args, 0) will pass 1 instead of 0, so the whole structure is allocated. * lib.h (FLEX_ARRAY): New macro: empty definition in C99 or later, otherwise 1. * args.h (struct args): Declare the size of the arg member using the new FLEX_ARRAY macro from lib.h. (ARGS_ABS_MIN): New macro, the absolute args minimum: zero in C99 mode, 1 in maintainer C90 mode. * ffi.c (ffi_struct_in, ffi_struct_get, make_zstruct): Use ARGS_ABS_MIN instead of 0 when preparing dummy args for make_struct call. * struct.c (struct_from_plist, struct_from_args, make_struct_lit): Use ARGS_ABS_MIN instead of zero when preparing dummy args for make_struct_impl or make_struct call.
-rw-r--r--args.h8
-rw-r--r--ffi.c6
-rw-r--r--lib.h6
-rw-r--r--struct.c6
4 files changed, 19 insertions, 7 deletions
diff --git a/args.h b/args.h
index e023e290..d2d87de4 100644
--- a/args.h
+++ b/args.h
@@ -30,7 +30,7 @@ struct args {
cnum argc;
cnum fill;
val list;
- val arg[1];
+ val arg[FLEX_ARRAY];
};
typedef int arg_index;
@@ -38,6 +38,12 @@ typedef int arg_index;
#define ARGS_MAX 32
#define ARGS_MIN 4
+#if FLEX_ARRAY + 0 == 1
+#define ARGS_ABS_MIN 1
+#else
+#define ARGS_ABS_MIN 0
+#endif
+
struct args_bool_key {
val key;
val arg_p;
diff --git a/ffi.c b/ffi.c
index 6cbfe8c8..efd6cd42 100644
--- a/ffi.c
+++ b/ffi.c
@@ -2300,7 +2300,7 @@ static val ffi_struct_in(struct txr_ffi_type *tft, int copy, mem_t *src,
return strct;
if (strct == nil) {
- args_decl(args, 0);
+ args_decl(args, ARGS_ABS_MIN);
strct = make_struct(tft->lt, nil, args);
}
@@ -2367,7 +2367,7 @@ static val ffi_struct_get(struct txr_ffi_type *tft, mem_t *src, val self)
{
cnum i, nmemb = tft->nelem;
struct smemb *memb = tft->memb;
- args_decl(args, 0);
+ args_decl(args, ARGS_ABS_MIN);
val strct = make_struct(tft->lt, nil, args);
int flexp = tft->flexible;
@@ -6485,7 +6485,7 @@ val make_zstruct(val type, struct args *args)
val self = lit("make-zstruct");
struct txr_ffi_type *tft = ffi_type_struct_checked(self, type);
val pairs = args_get_list(args);
- args_decl(ms_args, 0);
+ args_decl(ms_args, ARGS_ABS_MIN);
val strct = make_struct(tft->lt, nil, ms_args);
mem_t *zbuf;
char *inited = coerce(char *, zalloca(tft->nelem));
diff --git a/lib.h b/lib.h
index 75aed65a..f5b5ed42 100644
--- a/lib.h
+++ b/lib.h
@@ -46,6 +46,12 @@ typedef double_uintptr_t dbl_ucnum;
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif
+#if __STDC_VERSION__ >= 199901L
+#define FLEX_ARRAY
+#else
+#define FLEX_ARRAY 1
+#endif
+
#define TAG_SHIFT 2
#define TAG_MASK ((convert(cnum, 1) << TAG_SHIFT) - 1)
#define TAG_PTR 0
diff --git a/struct.c b/struct.c
index 9fca97a3..004c66d1 100644
--- a/struct.c
+++ b/struct.c
@@ -846,13 +846,13 @@ val make_struct(val type, val plist, struct args *boa)
val struct_from_plist(val type, struct args *plist)
{
- args_decl(boa, 0);
+ args_decl(boa, ARGS_ABS_MIN);
return make_struct_impl(lit("struct-from-plist"), type, plist, boa);
}
val struct_from_args(val type, struct args *boa)
{
- args_decl(pargs, 0);
+ args_decl(pargs, ARGS_ABS_MIN);
return make_struct_impl(lit("struct-from-args"), type, pargs, boa);
}
@@ -933,7 +933,7 @@ val make_lazy_struct(val type, val argfun)
val make_struct_lit(val type, val plist)
{
- args_decl(args, 0);
+ args_decl(args, ARGS_ABS_MIN);
val strct;
if (opt_compat && opt_compat <= 154) {