Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: group functions according to their...
details: https://anonhg.NetBSD.org/src/rev/8261c8454edb
branches: trunk
changeset: 954048:8261c8454edb
user: rillig <rillig%NetBSD.org@localhost>
date: Sun Mar 28 10:52:41 2021 +0000
description:
lint: group functions according to their main object
No functional change.
diffstat:
usr.bin/xlint/lint1/init.c | 983 ++++++++++++++++++++++----------------------
1 files changed, 495 insertions(+), 488 deletions(-)
diffs (truncated from 1156 to 300 lines):
diff -r 2ab7ac4f447c -r 8261c8454edb usr.bin/xlint/lint1/init.c
--- a/usr.bin/xlint/lint1/init.c Sun Mar 28 10:29:05 2021 +0000
+++ b/usr.bin/xlint/lint1/init.c Sun Mar 28 10:52:41 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: init.c,v 1.157 2021/03/28 10:09:34 rillig Exp $ */
+/* $NetBSD: init.c,v 1.158 2021/03/28 10:52:41 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: init.c,v 1.157 2021/03/28 10:09:34 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.158 2021/03/28 10:52:41 rillig Exp $");
#endif
#include <stdlib.h>
@@ -394,6 +394,85 @@
}
+/* In traditional C, bit-fields can be initialized only by integer constants. */
+static void
+check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt)
+{
+ if (tflag &&
+ is_integer(lt) &&
+ ln->tn_type->t_bitfield &&
+ !is_integer(rt)) {
+ /* bit-field initialization is illegal in traditional C */
+ warning(186);
+ }
+}
+
+static void
+check_non_constant_initializer(const tnode_t *tn, scl_t sclass)
+{
+ /* TODO: rename CON to CONSTANT to avoid ambiguity with CONVERT */
+ if (tn == NULL || tn->tn_op == CON)
+ return;
+
+ sym_t *sym;
+ ptrdiff_t offs;
+ if (constant_addr(tn, &sym, &offs))
+ return;
+
+ if (sclass == AUTO || sclass == REG) {
+ /* non-constant initializer */
+ c99ism(177);
+ } else {
+ /* non-constant initializer */
+ error(177);
+ }
+}
+
+static void
+check_init_expr(scl_t sclass, type_t *tp, sym_t *sym, tnode_t *tn)
+{
+ tnode_t *ln;
+ tspec_t lt, rt;
+ struct mbl *tmem;
+
+ /* Create a temporary node for the left side. */
+ ln = tgetblk(sizeof *ln);
+ ln->tn_op = NAME;
+ ln->tn_type = tduptyp(tp);
+ ln->tn_type->t_const = false;
+ ln->tn_lvalue = true;
+ ln->tn_sym = sym;
+
+ tn = cconv(tn);
+
+ lt = ln->tn_type->t_tspec;
+ rt = tn->tn_type->t_tspec;
+
+ debug_step("typeok '%s', '%s'",
+ type_name(ln->tn_type), type_name(tn->tn_type));
+ if (!typeok(INIT, 0, ln, tn))
+ return;
+
+ /*
+ * Preserve the tree memory. This is necessary because otherwise
+ * expr() would free it.
+ */
+ tmem = tsave();
+ expr(tn, true, false, true, false);
+ trestor(tmem);
+
+ check_bit_field_init(ln, lt, rt);
+
+ /*
+ * XXX: Is it correct to do this conversion _after_ the typeok above?
+ */
+ if (lt != rt || (tp->t_bitfield && tn->tn_op == CON))
+ tn = convert(INIT, 0, tp, tn);
+
+ check_non_constant_initializer(tn, sclass);
+}
+
+
static struct brace_level *
brace_level_new(type_t *type, type_t *subtype, int remaining)
{
@@ -554,6 +633,50 @@
return true;
}
+/*
+ * If the removed element was a structure member, we must go
+ * to the next structure member.
+ *
+ * XXX: Nothing should ever be "removed" at this point.
+ *
+ * TODO: think of a better name than 'pop'
+ */
+static void
+brace_level_pop_item_unnamed(struct brace_level *level)
+{
+ if (level->bl_remaining > 0 && level->bl_type->t_tspec == STRUCT &&
+ !level->bl_seen_named_member) {
+ brace_level_next_member(level);
+ level->bl_subtype = level->bl_next_member->s_type;
+ }
+}
+
+static bool
+brace_level_check_too_many_initializers(struct brace_level *level)
+{
+ if (level->bl_remaining > 0)
+ return true;
+ /*
+ * FIXME: even with named members, there can be too many initializers
+ */
+ if (level->bl_array_of_unknown_size || level->bl_seen_named_member)
+ return true;
+
+ tspec_t t = level->bl_type->t_tspec;
+ if (t == ARRAY) {
+ /* too many array initializers, expected %d */
+ error(173, level->bl_type->t_dim);
+ } else if (t == STRUCT || t == UNION) {
+ /* too many struct/union initializers */
+ error(172);
+ } else {
+ /* too many initializers */
+ error(174);
+ }
+ return false;
+}
+
+
static struct initialization *
initialization_new(sym_t *sym)
@@ -603,124 +726,15 @@
#define initialization_debug(in) do { } while (false)
#endif
-static void
-initialization_set_error(struct initialization *in)
-{
- in->initerr = true;
-}
-
-/* XXX: unnecessary prototype since it is not recursive */
-static bool init_array_using_string(struct initialization *, tnode_t *);
-
-
-static struct initialization *
-current_init(void)
-{
- lint_assert(init != NULL);
- return init;
-}
-
-bool *
-current_initerr(void)
-{
- return ¤t_init()->initerr;
-}
-
-sym_t **
-current_initsym(void)
-{
- return ¤t_init()->initsym;
-}
-
-
-void
-begin_initialization(sym_t *sym)
-{
- struct initialization *in;
-
- debug_step("begin initialization of '%s'", type_name(sym->s_type));
- in = initialization_new(sym);
- in->next = init;
- init = in;
-}
-
-void
-end_initialization(void)
-{
- struct initialization *in;
-
- in = init;
- init = init->next;
- initialization_free(in);
- debug_step("end initialization");
-}
-
-void
-add_designator_member(sbuf_t *sb)
-{
- designation_add(¤t_init()->designation,
- designator_new(sb->sb_name));
-}
-
-/* TODO: Move the function body up here, to avoid the forward declaration. */
-static void initstack_pop_nobrace(struct initialization *);
-
-/*
- * A sub-object of an array is initialized using a designator. This does not
- * have to be an array element directly, it can also be used to initialize
- * only a sub-object of the array element.
- *
- * C99 example: struct { int member[4]; } var = { [2] = 12345 };
- *
- * GNU example: struct { int member[4]; } var = { [1 ... 3] = 12345 };
- *
- * TODO: test the following initialization with an outer and an inner type:
- *
- * .deeply[0].nested = {
- * .deeply[1].nested = {
- * 12345,
- * },
- * }
- */
-void
-add_designator_subscript(range_t range)
-{
- struct initialization *in = current_init();
- struct brace_level *level;
-
- debug_enter();
- if (range.lo == range.hi)
- debug_step("subscript is %zu", range.hi);
- else
- debug_step("subscript range is %zu ... %zu",
- range.lo, range.hi);
-
- /* XXX: This call is wrong here, it must be somewhere else. */
- initstack_pop_nobrace(in);
-
- level = in->brace_level;
- if (level->bl_array_of_unknown_size) {
- /* No +1 here, extend_if_array_of_unknown_size will add it. */
- int auto_dim = (int)range.hi;
- if (auto_dim > level->bl_type->t_dim)
- brace_level_set_array_dimension(level, auto_dim);
- }
-
- debug_leave();
-}
-
-
/*
* Initialize the initialization stack by putting an entry for the object
* which is to be initialized on it.
*
- * TODO: merge into begin_initialization
+ * TODO: merge into initialization_new if possible
*/
-void
-initstack_init(void)
+static void
+initialization_init(struct initialization *in)
{
- struct initialization *in = current_init();
-
if (in->initerr)
return;
@@ -740,168 +754,16 @@
debug_leave();
}
-/* TODO: document me */
static void
-initstack_pop_item_named_member(struct initialization *in, const char *name)
-{
- struct brace_level *level = in->brace_level;
- const sym_t *m;
-
- /*
- * TODO: fix wording of the debug message; this doesn't seem to be
- * related to initializing the named member.
- */
- debug_step("initializing named member '%s'", name);
-
Home |
Main Index |
Thread Index |
Old Index