lint: fix buffer truncation for type names

Previously, most type names had been cut off after 63 significant
characters.  In some cases, 127 characters survived, or 255.  And for
the debugging messages, sometimes even 1023.  This inconsistency was
useless.

It was wrong in the first place to make the caller of the function
tyname responsible for handling the buffer.  That's not something a
caller of such a simple function should do.  These callers have better
things to do.

The API of the new function type_name is as simple as possible.

In the implementation, the name of the type is generated anew each time.
I just didn't know whether the type details could change, once the type
is initialized, and I didn't want to find out.  To be on the safe side,
the resulting type name is cached, independently of the type it was
generated for.  Using a trivial, unbalanced binary tree should be good
enough for now.

All this work is necessary to support adding new debug logging, without
being distracted by irrelevant implementation details such as these
buffer sizes.  Adding new debug messages should be fun and easy; up to
now, it was overly bureaucratic.
This commit is contained in:
rillig 2021-01-02 03:49:25 +00:00
parent bfa1e92456
commit 3ea7d2a77a
6 changed files with 216 additions and 176 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: externs.h,v 1.9 2021/01/01 01:42:55 rillig Exp $ */
/* $NetBSD: externs.h,v 1.10 2021/01/02 03:49:25 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@ -44,7 +44,7 @@ extern void inittyp(void);
/*
* tyname.c
*/
extern const char *tyname(char *, size_t, const type_t *);
extern const char *type_name(const type_t *);
extern int sametype(const type_t *, const type_t *);
extern const char *tspec_name(tspec_t);

View File

@ -1,4 +1,4 @@
/* $NetBSD: tyname.c,v 1.19 2021/01/02 01:36:28 rillig Exp $ */
/* $NetBSD: tyname.c,v 1.20 2021/01/02 03:49:25 rillig Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: tyname.c,v 1.19 2021/01/02 01:36:28 rillig Exp $");
__RCSID("$NetBSD: tyname.c,v 1.20 2021/01/02 03:49:25 rillig Exp $");
#endif
#include <limits.h>
@ -53,6 +53,103 @@ __RCSID("$NetBSD: tyname.c,v 1.19 2021/01/02 01:36:28 rillig Exp $");
} while (/*CONSTCOND*/0)
#endif
/* A tree of strings. */
typedef struct name_tree_node {
char *ntn_name;
struct name_tree_node *ntn_less;
struct name_tree_node *ntn_greater;
} name_tree_node;
/* A growable string buffer. */
typedef struct buffer {
size_t len;
size_t cap;
char * data;
} buffer;
static name_tree_node *type_names;
static name_tree_node *
new_name_tree_node(const char *name)
{
name_tree_node *n;
n = xmalloc(sizeof(*n));
n->ntn_name = xstrdup(name);
n->ntn_less = NULL;
n->ntn_greater = NULL;
return n;
}
/* Return the canonical instance of the string, with unlimited life time. */
static const char *
intern(const char *name)
{
name_tree_node *n = type_names;
int cmp;
if (n == NULL) {
n = new_name_tree_node(name);
type_names = n;
return n->ntn_name;
}
while ((cmp = strcmp(name, n->ntn_name)) != 0) {
if (cmp < 0) {
if (n->ntn_less == NULL) {
n->ntn_less = new_name_tree_node(name);
return n->ntn_less->ntn_name;
}
n = n->ntn_less;
} else {
if (n->ntn_greater == NULL) {
n->ntn_greater = new_name_tree_node(name);
return n->ntn_greater->ntn_name;
}
n = n->ntn_greater;
}
}
return n->ntn_name;
}
static void
buf_init(buffer *buf)
{
buf->len = 0;
buf->cap = 128;
buf->data = xmalloc(buf->cap);
buf->data[0] = '\0';
}
static void
buf_done(buffer *buf)
{
free(buf->data);
}
static void
buf_add(buffer *buf, const char *s)
{
size_t len = strlen(s);
while (buf->len + len + 1 >= buf->cap) {
buf->data = xrealloc(buf->data, 2 * buf->cap);
buf->cap = 2 * buf->cap;
}
memcpy(buf->data + buf->len, s, len + 1);
buf->len += len;
}
static void
buf_add_int(buffer *buf, int n)
{
char num[1 + sizeof(n) * CHAR_BIT + 1];
snprintf(num, sizeof num, "%d", n);
buf_add(buf, num);
}
const char *
tspec_name(tspec_t t)
{
@ -160,25 +257,28 @@ sametype(const type_t *t1, const type_t *t2)
}
const char *
tyname(char *buf, size_t bufsiz, const type_t *tp)
type_name(const type_t *tp)
{
tspec_t t;
const char *s;
char lbuf[64];
char cv[20];
tspec_t t;
buffer buf;
const char *name;
if (tp == NULL)
return "(null)";
/*
* XXX: Why is this necessary, and in which cases does this apply?
* Shouldn't the type be an ENUM from the beginning?
*/
if ((t = tp->t_tspec) == INT && tp->t_isenum)
t = ENUM;
s = tspec_name(t);
cv[0] = '\0';
buf_init(&buf);
if (tp->t_const)
(void)strcat(cv, "const ");
buf_add(&buf, "const ");
if (tp->t_volatile)
(void)strcat(cv, "volatile ");
buf_add(&buf, "volatile ");
buf_add(&buf, tspec_name(t));
switch (t) {
case BOOL:
@ -208,37 +308,42 @@ tyname(char *buf, size_t bufsiz, const type_t *tp)
case LCOMPLEX:
case SIGNED:
case UNSIGN:
(void)snprintf(buf, bufsiz, "%s%s", cv, s);
break;
case PTR:
(void)snprintf(buf, bufsiz, "%s%s to %s", cv, s,
tyname(lbuf, sizeof(lbuf), tp->t_subt));
buf_add(&buf, " to ");
buf_add(&buf, type_name(tp->t_subt));
break;
case ENUM:
(void)snprintf(buf, bufsiz, "%s%s %s", cv, s,
buf_add(&buf, " ");
#ifdef t_enum
tp->t_enum->etag->s_name
buf_add(&buf, tp->t_enum->etag->s_name);
#else
tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name
buf_add(&buf,
tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name);
#endif
);
break;
case STRUCT:
case UNION:
(void)snprintf(buf, bufsiz, "%s%s %s", cv, s,
buf_add(&buf, " ");
#ifdef t_str
tp->t_str->stag->s_name
buf_add(&buf, tp->t_str->stag->s_name);
#else
tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name
buf_add(&buf,
tp->t_isuniqpos ? "*anonymous*" : tp->t_tag->h_name);
#endif
);
break;
case ARRAY:
(void)snprintf(buf, bufsiz, "%s%s of %s[%d]", cv, s,
tyname(lbuf, sizeof(lbuf), tp->t_subt), tp->t_dim);
buf_add(&buf, " of ");
buf_add(&buf, type_name(tp->t_subt));
buf_add(&buf, "[");
buf_add_int(&buf, tp->t_dim);
buf_add(&buf, "]");
break;
default:
LERROR("tyname(%d)", t);
}
return buf;
name = intern(buf.data);
buf_done(&buf);
return name;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: decl.c,v 1.97 2021/01/01 14:11:20 rillig Exp $ */
/* $NetBSD: decl.c,v 1.98 2021/01/02 03:49:25 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: decl.c,v 1.97 2021/01/01 14:11:20 rillig Exp $");
__RCSID("$NetBSD: decl.c,v 1.98 2021/01/02 03:49:25 rillig Exp $");
#endif
#include <sys/param.h>
@ -253,8 +253,7 @@ add_type(type_t *tp)
{
tspec_t t;
#ifdef DEBUG
char buf[1024];
printf("%s: %s\n", __func__, tyname(buf, sizeof(buf), tp));
printf("%s: %s\n", __func__, type_name(tp));
#endif
if (tp->t_typedef) {
/*
@ -505,7 +504,6 @@ setpackedsize(type_t *tp)
{
str_t *sp;
sym_t *mem;
char buf[256];
switch (tp->t_tspec) {
case STRUCT:
@ -527,7 +525,7 @@ setpackedsize(type_t *tp)
break;
default:
/* %s attribute ignored for %s */
warning(326, "packed", tyname(buf, sizeof(buf), tp));
warning(326, "packed", type_name(tp));
break;
}
}
@ -731,8 +729,7 @@ deftyp(void)
scl = dcs->d_scl;
#ifdef DEBUG
char buf[1024];
printf("%s: %s\n", __func__, tyname(buf, sizeof(buf), tp));
printf("%s: %s\n", __func__, type_name(tp));
#endif
if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && c == NOTSPEC &&
tp == NULL)
@ -1109,10 +1106,8 @@ declarator_1_struct_union(sym_t *dsym)
t == SHORT || t == USHORT || t == ENUM) {
if (bitfieldtype_ok == 0) {
if (sflag) {
char buf[64];
/* bit-field type '%s' invalid ... */
warning(273,
tyname(buf, sizeof(buf), tp));
warning(273, type_name(tp));
} else if (pflag) {
/* nonportable bit-field type */
warning(34);

View File

@ -1,4 +1,4 @@
/* $NetBSD: init.c,v 1.56 2021/01/02 01:06:15 rillig Exp $ */
/* $NetBSD: init.c,v 1.57 2021/01/02 03:49:25 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.56 2021/01/02 01:06:15 rillig Exp $");
__RCSID("$NetBSD: init.c,v 1.57 2021/01/02 03:49:25 rillig Exp $");
#endif
#include <stdlib.h>
@ -207,15 +207,12 @@ initstack_init(void)
static void
initstack_pop_item(void)
{
#ifdef DEBUG
char buf[64];
#endif
istk_t *istk;
sym_t *m;
istk = initstk;
DPRINTF(("%s: pop type=%s, brace=%d remaining=%d named=%d\n", __func__,
tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt),
type_name(istk->i_type ? istk->i_type : istk->i_subt),
istk->i_brace, istk->i_remaining, istk->i_namedmem));
initstk = istk->i_next;
@ -224,7 +221,7 @@ initstack_pop_item(void)
lint_assert(istk != NULL);
DPRINTF(("%s: top type=%s, brace=%d remaining=%d named=%d\n", __func__,
tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt),
type_name(istk->i_type ? istk->i_type : istk->i_subt),
istk->i_brace, istk->i_remaining, istk->i_namedmem));
istk->i_remaining--;
@ -237,7 +234,7 @@ initstack_pop_item(void)
DPRINTF(("%s: named remaining=%d type=%s, rhs.name=%s\n",
__func__, istk->i_remaining,
tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name));
type_name(istk->i_type), namedmem->n_name));
for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) {
DPRINTF(("%s: pop lhs.name=%s rhs.name=%s\n", __func__,
@ -309,9 +306,6 @@ initstack_pop_nobrace(void)
static void
initstack_push(void)
{
#ifdef DEBUG
char buf[64];
#endif
istk_t *istk, *inxt;
int cnt;
sym_t *m;
@ -320,8 +314,7 @@ initstack_push(void)
/* Extend an incomplete array type by one element */
if (istk->i_remaining == 0) {
DPRINTF(("%s(extend) %s\n", __func__,
tyname(buf, sizeof(buf), istk->i_type)));
DPRINTF(("%s(extend) %s\n", __func__, type_name(istk->i_type)));
/*
* Inside of other aggregate types must not be an incomplete
* type.
@ -345,7 +338,7 @@ initstack_push(void)
again:
istk = initstk;
DPRINTF(("%s(%s)\n", __func__, tyname(buf, sizeof(buf), istk->i_type)));
DPRINTF(("%s(%s)\n", __func__, type_name(istk->i_type)));
switch (istk->i_type->t_tspec) {
case ARRAY:
if (namedmem) {
@ -368,7 +361,7 @@ again:
istk->i_nolimit = incompl(istk->i_type);
istk->i_remaining = istk->i_type->t_dim;
DPRINTF(("%s: elements array %s[%d] %s\n", __func__,
tyname(buf, sizeof(buf), istk->i_subt), istk->i_remaining,
type_name(istk->i_subt), istk->i_remaining,
namedmem ? namedmem->n_name : "*none*"));
break;
case UNION:
@ -385,7 +378,7 @@ again:
}
cnt = 0;
DPRINTF(("%s: lookup type=%s, name=%s named=%d\n", __func__,
tyname(buf, sizeof(buf), istk->i_type),
type_name(istk->i_type),
namedmem ? namedmem->n_name : "*none*", istk->i_namedmem));
for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) {
if (m->s_bitfield && m->s_name == unnamed)
@ -419,8 +412,7 @@ again:
}
istk->i_brace = 1;
DPRINTF(("%s: unnamed type=%s, brace=%d\n", __func__,
tyname(buf, sizeof(buf),
istk->i_type ? istk->i_type : istk->i_subt),
type_name(istk->i_type ? istk->i_type : istk->i_subt),
istk->i_brace));
if (cnt == 0) {
/* cannot init. struct/union with no named member */
@ -478,13 +470,12 @@ initstack_check_too_many(void)
static void
initstack_next_brace(void)
{
char buf[64];
DPRINTF(("%s\n", __func__));
if (initstk->i_type != NULL &&
tspec_is_scalar(initstk->i_type->t_tspec)) {
/* invalid initializer type %s */
error(176, tyname(buf, sizeof(buf), initstk->i_type));
error(176, type_name(initstk->i_type));
initerr = 1;
}
if (!initerr)
@ -493,9 +484,7 @@ initstack_next_brace(void)
initstack_push();
if (!initerr) {
initstk->i_brace = 1;
DPRINTF(("%s: %p %s\n", __func__,
namedmem,
tyname(buf, sizeof(buf),
DPRINTF(("%s: %p %s\n", __func__, namedmem, type_name(
initstk->i_type ? initstk->i_type : initstk->i_subt)));
}
}
@ -567,11 +556,11 @@ mkinit(tnode_t *tn)
struct mbl *tmem;
scl_t sc;
#ifdef DEBUG
char buf[64], sbuf[64];
char sbuf[64];
#endif
DPRINTF(("%s: type=%s, value=%s\n", __func__,
tyname(buf, sizeof(buf), tn->tn_type),
type_name(tn->tn_type),
print_tnode(sbuf, sizeof(sbuf), tn)));
named_member_dprint();

View File

@ -1,4 +1,4 @@
/* $NetBSD: tree.c,v 1.114 2021/01/01 11:58:03 rillig Exp $ */
/* $NetBSD: tree.c,v 1.115 2021/01/02 03:49:25 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: tree.c,v 1.114 2021/01/01 11:58:03 rillig Exp $");
__RCSID("$NetBSD: tree.c,v 1.115 2021/01/02 03:49:25 rillig Exp $");
#endif
#include <float.h>
@ -97,7 +97,6 @@ static char *
dumpnode(char *buf, size_t len, tnode_t *tn) {
const char *n = getopname(tn->tn_op);
const char *s;
char tbuf[256];
switch (tn->tn_op) {
case NAME:
@ -126,7 +125,7 @@ dumpnode(char *buf, size_t len, tnode_t *tn) {
snprintf(buf, len, "%s: (%s) = %s [%s, %s]", n,
tyname(tbuf, sizeof(tbuf), tn->tn_type), s, lb, rb);
type_name(tn->tn_type), s, lb, rb);
return buf;
}
#endif
@ -439,16 +438,13 @@ struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
error(103);
}
} else {
char buf[64];
/* left operand of "->" must be pointer to ... */
if (tflag && tn->tn_type->t_tspec == PTR) {
tyname(buf, sizeof(buf), tn->tn_type);
/* left operand of '->' must be pointer ... */
warning(104, buf);
warning(104, type_name(tn->tn_type));
} else {
tyname(buf, sizeof(buf), tn->tn_type);
/* left operand of '->' must be pointer ... */
error(104, buf);
error(104, type_name(tn->tn_type));
}
}
} else {
@ -704,7 +700,6 @@ typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn)
tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC, olt = NOTSPEC,
ort = NOTSPEC;
type_t *ltp, *rtp = NULL, *lstp = NULL, *rstp = NULL;
char lbuf[128], rbuf[128];
tnode_t *tn;
mp = &modtab[op];
@ -968,10 +963,9 @@ typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn)
"pointer" : "integer";
const char *rx = rt == PTR ?
"pointer" : "integer";
tyname(lbuf, sizeof(lbuf), ltp);
tyname(rbuf, sizeof(rbuf), rtp);
/* illegal combination of %s (%s) and ... */
warning(123, lx, lbuf, rx, rbuf, mp->m_name);
warning(123, lx, type_name(ltp),
rx, type_name(rtp), mp->m_name);
} else {
warn_incompatible_types(op, lt, rt);
return 0;
@ -1015,10 +1009,9 @@ typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn)
(tspec_is_int(lt) && rt == PTR)) {
const char *lx = lt == PTR ? "pointer" : "integer";
const char *rx = rt == PTR ? "pointer" : "integer";
tyname(lbuf, sizeof(lbuf), ltp);
tyname(rbuf, sizeof(rbuf), rtp);
/* illegal combination of %s (%s) and %s (%s), op %s */
warning(123, lx, lbuf, rx, rbuf, mp->m_name);
warning(123, lx, type_name(ltp),
rx, type_name(rtp), mp->m_name);
break;
}
@ -1196,7 +1189,6 @@ check_assign_types_compatible(op_t op, int arg, tnode_t *ln, tnode_t *rn)
type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL;
mod_t *mp;
const char *lts, *rts;
char lbuf[128], rbuf[128];
if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
lst = (lstp = ltp->t_subt)->t_tspec;
@ -1248,21 +1240,21 @@ check_assign_types_compatible(op_t op, int arg, tnode_t *ln, tnode_t *rn)
((!lstp->t_const && rstp->t_const) ||
(!lstp->t_volatile && rstp->t_volatile))) {
/* left side has not all qualifiers of right */
tyname(lbuf, sizeof(lbuf), lstp);
tyname(rbuf, sizeof(rbuf), rstp);
switch (op) {
case INIT:
case RETURN:
/* incompatible pointer types (%s != %s) */
warning(182, lbuf, rbuf);
warning(182, type_name(lstp), type_name(rstp));
break;
case FARG:
/* argument has incompatible pointer type... */
warning(153, arg, lbuf, rbuf);
warning(153,
arg, type_name(lstp), type_name(rstp));
break;
default:
/* operands have incompatible pointer type... */
warning(128, mp->m_name, lbuf, rbuf);
warning(128, mp->m_name,
type_name(lstp), type_name(rstp));
break;
}
}
@ -1273,22 +1265,22 @@ check_assign_types_compatible(op_t op, int arg, tnode_t *ln, tnode_t *rn)
(tspec_is_int(lt) && rt == PTR)) {
const char *lx = lt == PTR ? "pointer" : "integer";
const char *rx = rt == PTR ? "pointer" : "integer";
tyname(lbuf, sizeof(lbuf), ltp);
tyname(rbuf, sizeof(rbuf), rtp);
switch (op) {
case INIT:
case RETURN:
/* illegal combination of %s (%s) and %s (%s) */
warning(183, lx, lbuf, rx, rbuf);
warning(183, lx, type_name(ltp), rx, type_name(rtp));
break;
case FARG:
/* illegal comb. of %s (%s) and %s (%s), arg #%d */
warning(154, lx, lbuf, rx, rbuf, arg);
warning(154,
lx, type_name(ltp), rx, type_name(rtp), arg);
break;
default:
/* illegal combination of %s (%s) and %s (%s), op %s */
warning(123, lx, lbuf, rx, rbuf, mp->m_name);
warning(123,
lx, type_name(ltp), rx, type_name(rtp), mp->m_name);
break;
}
return 1;
@ -1302,8 +1294,7 @@ check_assign_types_compatible(op_t op, int arg, tnode_t *ln, tnode_t *rn)
break;
case FARG:
/* arg. has incomp. pointer type, arg #%d (%s != %s) */
warning(153, arg, tyname(lbuf, sizeof(lbuf), ltp),
tyname(rbuf, sizeof(rbuf), rtp));
warning(153, arg, type_name(ltp), type_name(rtp));
break;
default:
warn_incompatible_pointers(mp, ltp, rtp);
@ -1315,13 +1306,11 @@ check_assign_types_compatible(op_t op, int arg, tnode_t *ln, tnode_t *rn)
switch (op) {
case INIT:
/* initialisation type mismatch (%s) and (%s) */
error(185, tyname(lbuf, sizeof(lbuf), ltp),
tyname(rbuf, sizeof(rbuf), rtp));
error(185, type_name(ltp), type_name(rtp));
break;
case RETURN:
/* return value type mismatch (%s) and (%s) */
error(211, tyname(lbuf, sizeof(lbuf), ltp),
tyname(rbuf, sizeof(rbuf), rtp));
error(211, type_name(ltp), type_name(rtp));
break;
case FARG:
/* argument is incompatible with prototype, arg #%d */
@ -1376,7 +1365,6 @@ static void
check_enum_type_mismatch(op_t op, int arg, tnode_t *ln, tnode_t *rn)
{
mod_t *mp;
char lbuf[128], rbuf[128];
mp = &modtab[op];
@ -1392,8 +1380,8 @@ check_enum_type_mismatch(op_t op, int arg, tnode_t *ln, tnode_t *rn)
break;
case RETURN:
/* return value type mismatch (%s) and (%s) */
warning(211, tyname(lbuf, sizeof(lbuf), ln->tn_type),
tyname(rbuf, sizeof(rbuf), rn->tn_type));
warning(211,
type_name(ln->tn_type), type_name(rn->tn_type));
break;
default:
/* enum type mismatch, op %s */
@ -1414,7 +1402,6 @@ check_enum_type_mismatch(op_t op, int arg, tnode_t *ln, tnode_t *rn)
static void
check_enum_int_mismatch(op_t op, int arg, tnode_t *ln, tnode_t *rn)
{
char lbuf[64], rbuf[64];
if (!eflag)
return;
@ -1432,23 +1419,20 @@ check_enum_int_mismatch(op_t op, int arg, tnode_t *ln, tnode_t *rn)
return;
}
/* initialisation of '%s' with '%s' */
warning(277, tyname(lbuf, sizeof(lbuf), ln->tn_type),
tyname(rbuf, sizeof(rbuf), rn->tn_type));
warning(277, type_name(ln->tn_type), type_name(rn->tn_type));
break;
case FARG:
/* combination of '%s' and '%s', arg #%d */
warning(278, tyname(lbuf, sizeof(lbuf), ln->tn_type),
tyname(rbuf, sizeof(rbuf), rn->tn_type), arg);
warning(278,
type_name(ln->tn_type), type_name(rn->tn_type), arg);
break;
case RETURN:
/* combination of '%s' and '%s' in return */
warning(279, tyname(lbuf, sizeof(lbuf), ln->tn_type),
tyname(rbuf, sizeof(rbuf), rn->tn_type));
warning(279, type_name(ln->tn_type), type_name(rn->tn_type));
break;
default:
/* combination of '%s' and '%s', op %s */
warning(242, tyname(lbuf, sizeof(lbuf), ln->tn_type),
tyname(rbuf, sizeof(rbuf), rn->tn_type),
warning(242, type_name(ln->tn_type), type_name(rn->tn_type),
modtab[op].m_name);
break;
}
@ -1738,7 +1722,6 @@ check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
tnode_t *tn)
{
tnode_t *ptn;
char buf[64];
if (!tspec_is_arith(nt) || !tspec_is_arith(ot))
return;
@ -1764,7 +1747,7 @@ check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
/* representation and/or width change */
if (!tspec_is_int(ot) || psize(ot) > psize(INT)) {
/* conversion to '%s' due to prototype, arg #%d */
warning(259, tyname(buf, sizeof(buf), tp), arg);
warning(259, type_name(tp), arg);
}
} else if (hflag) {
/*
@ -1780,7 +1763,7 @@ check_prototype_conversion(int arg, tspec_t nt, tspec_t ot, type_t *tp,
/* ok */
} else {
/* conversion to '%s' due to prototype, arg #%d */
warning(259, tyname(buf, sizeof(buf), tp), arg);
warning(259, type_name(tp), arg);
}
}
}
@ -1793,7 +1776,8 @@ static void
check_integer_conversion(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp,
tnode_t *tn)
{
char lbuf[64], rbuf[64], opbuf[16];
char opbuf[16];
if (tn->tn_op == CON)
return;
@ -1805,11 +1789,10 @@ check_integer_conversion(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp,
if (aflag && pflag) {
if (op == FARG) {
/* conversion to '%s' may sign-extend ... */
warning(297, tyname(lbuf, sizeof(lbuf), tp),
arg);
warning(297, type_name(tp), arg);
} else {
/* conversion to '%s' may sign-extend ... */
warning(131, tyname(lbuf, sizeof(lbuf), tp));
warning(131, type_name(tp));
}
}
}
@ -1821,9 +1804,7 @@ check_integer_conversion(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp,
case MULT:
case SHL:
/* suggest cast from '%s' to '%s' on op %s to ... */
warning(324,
tyname(rbuf, sizeof(rbuf), gettyp(ot)),
tyname(lbuf, sizeof(lbuf), tp),
warning(324, type_name(gettyp(ot)), type_name(tp),
print_tnode(opbuf, sizeof(opbuf), tn));
break;
default:
@ -1839,14 +1820,11 @@ check_integer_conversion(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp,
if (op == FARG) {
/* conv. from '%s' to '%s' may lose ... */
warning(298,
tyname(rbuf, sizeof(rbuf), tn->tn_type),
tyname(lbuf, sizeof(lbuf), tp),
arg);
type_name(tn->tn_type), type_name(tp), arg);
} else {
/* conv. from '%s' to '%s' may lose accuracy */
warning(132,
tyname(rbuf, sizeof(rbuf), tn->tn_type),
tyname(lbuf, sizeof(lbuf), tp));
type_name(tn->tn_type), type_name(tp));
}
}
}
@ -1858,7 +1836,6 @@ check_integer_conversion(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp,
static void
check_pointer_integer_conversion(op_t op, tspec_t nt, type_t *tp, tnode_t *tn)
{
char buf[64];
if (tn->tn_op == CON)
return;
@ -1871,10 +1848,10 @@ check_pointer_integer_conversion(op_t op, tspec_t nt, type_t *tp, tnode_t *tn)
if (psize(nt) < psize(PTR)) {
if (pflag && size(nt) >= size(PTR)) {
/* conv. of pointer to '%s' may lose bits */
warning(134, tyname(buf, sizeof(buf), tp));
warning(134, type_name(tp));
} else {
/* conv. of pointer to '%s' loses bits */
warning(133, tyname(buf, sizeof(buf), tp));
warning(133, type_name(tp));
}
}
}
@ -1942,7 +1919,6 @@ check_pointer_conversion(op_t op, tnode_t *tn, type_t *tp)
void
cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v)
{
char lbuf[64], rbuf[64];
tspec_t ot, nt;
ldbl_t max = 0.0, min = 0.0;
int sz, rchk;
@ -1999,14 +1975,11 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v)
if (op == FARG) {
/* conv. of '%s' to '%s' is out of range, ... */
warning(295,
tyname(lbuf, sizeof(lbuf), gettyp(ot)),
tyname(rbuf, sizeof(rbuf), tp),
arg);
type_name(gettyp(ot)), type_name(tp), arg);
} else {
/* conversion of '%s' to '%s' is out of range */
warning(119,
tyname(lbuf, sizeof(lbuf), gettyp(ot)),
tyname(rbuf, sizeof(rbuf), tp));
type_name(gettyp(ot)), type_name(tp));
}
v->v_ldbl = v->v_ldbl > 0 ? max : min;
}
@ -2090,10 +2063,8 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v)
(nv->v_quad & qbmasks[osz - 1]) != 0 &&
(nv->v_quad & xmask) != xmask) {
/* extra bits set to 0 in conv. of '%s' ... */
warning(309,
tyname(lbuf, sizeof(lbuf), gettyp(ot)),
tyname(rbuf, sizeof(rbuf), tp),
modtab[op].m_name);
warning(309, type_name(gettyp(ot)),
type_name(tp), modtab[op].m_name);
} else if (nsz < osz &&
(v->v_quad & xmask) != xmask &&
(v->v_quad & xmask) != 0) {
@ -2155,14 +2126,11 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v)
} else if (op == FARG) {
/* conv. of '%s' to '%s' is out of range, ... */
warning(295,
tyname(lbuf, sizeof(lbuf), gettyp(ot)),
tyname(rbuf, sizeof(rbuf), tp),
arg);
type_name(gettyp(ot)), type_name(tp), arg);
} else {
/* conversion of '%s' to '%s' is out of range */
warning(119,
tyname(lbuf, sizeof(lbuf), gettyp(ot)),
tyname(rbuf, sizeof(rbuf), tp));
type_name(gettyp(ot)), type_name(tp));
}
} else if (nv->v_quad != v->v_quad) {
if (op == ASSIGN && tp->t_isfield) {
@ -2177,14 +2145,11 @@ cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v)
} else if (op == FARG) {
/* conv. of '%s' to '%s' is out of range, ... */
warning(295,
tyname(lbuf, sizeof(lbuf), gettyp(ot)),
tyname(rbuf, sizeof(rbuf), tp),
arg);
type_name(gettyp(ot)), type_name(tp), arg);
} else {
/* conversion of '%s' to '%s' is out of range */
warning(119,
tyname(lbuf, sizeof(lbuf), gettyp(ot)),
tyname(rbuf, sizeof(rbuf), tp));
type_name(gettyp(ot)), type_name(tp));
}
}
}
@ -2383,7 +2348,6 @@ static tnode_t *
build_real_imag(op_t op, tnode_t *ln)
{
tnode_t *cn, *ntn;
char buf[64];
lint_assert(ln != NULL);
@ -2400,7 +2364,7 @@ build_real_imag(op_t op, tnode_t *ln)
default:
/* __%s__ is illegal for type %s */
error(276, op == REAL ? "real" : "imag",
tyname(buf, sizeof(buf), ln->tn_type));
type_name(ln->tn_type));
return NULL;
}
ntn = new_tnode(op, cn->tn_type, ln, cn);
@ -3172,7 +3136,6 @@ cast(tnode_t *tn, type_t *tp)
* But this seams really questionable.
*/
} else if (nt == UNION) {
char buf[256], buf1[256];
sym_t *m;
str_t *str = tp->t_str;
if (!Sflag) {
@ -3191,8 +3154,7 @@ cast(tnode_t *tn, type_t *tp)
}
}
/* type '%s' is not a member of '%s' */
error(329, tyname(buf, sizeof(buf), tn->tn_type),
tyname(buf1, sizeof(buf1), tp));
error(329, type_name(tn->tn_type), type_name(tp));
return NULL;
} else if (nt == STRUCT || nt == ARRAY || nt == FUNC) {
if (!Sflag || nt == ARRAY || nt == FUNC) {
@ -3282,9 +3244,8 @@ funccall(tnode_t *func, tnode_t *args)
if (func->tn_type->t_tspec != PTR ||
func->tn_type->t_subt->t_tspec != FUNC) {
char buf[256];
/* illegal function (type %s) */
error(149, tyname(buf, sizeof(buf), func->tn_type));
error(149, type_name(func->tn_type));
return NULL;
}
@ -3839,7 +3800,6 @@ check_array_index(tnode_t *tn, int amper)
static void
check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
{
char buf[64];
tspec_t lt, rt;
mod_t *mp;
@ -3871,12 +3831,11 @@ check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
if (rn->tn_val->v_quad < 0) {
/* comparison of %s with %s, op %s */
warning(162, tyname(buf, sizeof(buf), ln->tn_type),
warning(162, type_name(ln->tn_type),
"negative constant", mp->m_name);
} else if (op == LT || op == GE || (hflag && op == LE)) {
/* comparison of %s with %s, op %s */
warning(162, tyname(buf, sizeof(buf), ln->tn_type),
"0", mp->m_name);
warning(162, type_name(ln->tn_type), "0", mp->m_name);
}
return;
}
@ -3885,11 +3844,10 @@ check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
if (ln->tn_val->v_quad < 0) {
/* comparison of %s with %s, op %s */
warning(162, "negative constant",
tyname(buf, sizeof(buf), rn->tn_type), mp->m_name);
type_name(rn->tn_type), mp->m_name);
} else if (op == GT || op == LE || (hflag && op == GE)) {
/* comparison of %s with %s, op %s */
warning(162, "0", tyname(buf, sizeof(buf), rn->tn_type),
mp->m_name);
warning(162, "0", type_name(rn->tn_type), mp->m_name);
}
return;
}
@ -4011,7 +3969,7 @@ cat_strings(strg_t *strg1, strg_t *strg2)
else
COPY(st_wcp);
strg1->st_len = len - 1; /* - NUL */;
strg1->st_len = len - 1; /* - NUL */
free(strg2);
return strg1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: chk.c,v 1.30 2021/01/01 11:58:03 rillig Exp $ */
/* $NetBSD: chk.c,v 1.31 2021/01/02 03:49:26 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: chk.c,v 1.30 2021/01/01 11:58:03 rillig Exp $");
__RCSID("$NetBSD: chk.c,v 1.31 2021/01/02 03:49:26 rillig Exp $");
#endif
#include <ctype.h>
@ -320,12 +320,10 @@ chkvtdi(hte_t *hte, sym_t *def, sym_t *decl)
eq = eqtype(xt1 = tp1, xt2 = tp2, 0, 0, 0, &dowarn);
}
if (!eq || (sflag && dowarn)) {
char b1[64], b2[64];
pos1 = xstrdup(mkpos(&def->s_pos));
/* %s value declared inconsistently\t%s :: %s */
msg(5, hte->h_name, tyname(b1, sizeof(b1), xt1),
tyname(b2, sizeof(b2), xt2), pos1,
mkpos(&sym->s_pos));
msg(5, hte->h_name, type_name(xt1), type_name(xt2),
pos1, mkpos(&sym->s_pos));
free(pos1);
}
}
@ -452,7 +450,6 @@ chkau(hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p,
tspec_t t1, t2;
arginf_t *ai, *ai1;
char *pos1;
char tyname1[64], tyname2[64];
/*
* If a function definition is available (def != NULL), we compair the
@ -590,10 +587,8 @@ chkau(hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p,
pos1 = xstrdup(mkpos(pos1p));
/* %s, arg %d used inconsistently\t%s[%s] :: %s[%s] */
msg(6, hte->h_name, n, pos1,
tyname(tyname1, sizeof(tyname1), arg1),
mkpos(&call->f_pos),
tyname(tyname2, sizeof(tyname2), arg2));
msg(6, hte->h_name, n, pos1, type_name(arg1),
mkpos(&call->f_pos), type_name(arg2));
free(pos1);
}
@ -1157,13 +1152,11 @@ chkadecl(hte_t *hte, sym_t *def, sym_t *decl)
dowarn = 0;
eq = eqtype(xt1 = *ap1, xt2 = *ap2, 1, osdef, 0, &dowarn);
if (!eq || dowarn) {
char b1[64], b2[64];
pos1 = xstrdup(mkpos(&sym1->s_pos));
pos2 = mkpos(&sym->s_pos);
/* %s, arg %d declared inconsistently ... */
msg(11, hte->h_name, n + 1,
tyname(b1, sizeof(b1), xt1),
tyname(b2, sizeof(b2), xt2), pos1, pos2);
type_name(xt1), type_name(xt2), pos1, pos2);
free(pos1);
}
n++;