diff options
-rw-r--r-- | include/complex.h | 4 | ||||
-rw-r--r-- | include/stdbool.h | 4 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/decl.c | 124 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/emit1.c | 18 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/externs1.h | 3 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/lint.h | 16 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/lint1.h | 11 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/op.h | 4 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/scan.l | 73 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/tree.c | 69 | ||||
-rw-r--r-- | usr.bin/xlint/lint2/chk.c | 19 | ||||
-rw-r--r-- | usr.bin/xlint/lint2/emit2.c | 11 | ||||
-rw-r--r-- | usr.bin/xlint/lint2/read.c | 36 |
13 files changed, 341 insertions, 51 deletions
diff --git a/include/complex.h b/include/complex.h index aa89d70079e..be85c7c0914 100644 --- a/include/complex.h +++ b/include/complex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: complex.h,v 1.2 2008/12/04 03:52:31 ray Exp $ */ +/* $OpenBSD: complex.h,v 1.3 2010/07/24 22:17:03 guenther Exp $ */ /* * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> * @@ -28,6 +28,8 @@ #define _Complex __complex__ #endif #define _Complex_I 1.0fi +#elif defined(lint) +#define _Complex_I 1.0fi #endif #define complex _Complex diff --git a/include/stdbool.h b/include/stdbool.h index cc1104c6f85..34304130081 100644 --- a/include/stdbool.h +++ b/include/stdbool.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stdbool.h,v 1.4 2007/10/02 14:06:16 otto Exp $ */ +/* $OpenBSD: stdbool.h,v 1.5 2010/07/24 22:17:03 guenther Exp $ */ /* * Written by Marc Espie, September 25, 1999 @@ -10,7 +10,7 @@ #ifndef __cplusplus -#if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__PCC__) +#if (defined(__GNUC__) && __GNUC__ >= 3) || defined(__PCC__) || defined(lint) /* Support for _C99: type _Bool is already built-in. */ #define false 0 #define true 1 diff --git a/usr.bin/xlint/lint1/decl.c b/usr.bin/xlint/lint1/decl.c index bd52fdd3c79..3ee6f39670f 100644 --- a/usr.bin/xlint/lint1/decl.c +++ b/usr.bin/xlint/lint1/decl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: decl.c,v 1.24 2007/11/27 16:22:14 martynas Exp $ */ +/* $OpenBSD: decl.c,v 1.25 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: decl.c,v 1.11 1995/10/02 17:34:16 jpo Exp $ */ /* @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: decl.c,v 1.24 2007/11/27 16:22:14 martynas Exp $"; +static char rcsid[] = "$OpenBSD: decl.c,v 1.25 2010/07/24 22:17:03 guenther Exp $"; #endif #include <sys/param.h> @@ -97,6 +97,9 @@ initdecl(void) { UNSIGN, { 0, 0, 0, SIGNED, UNSIGN, 0, 0, 0, 0, 0, "unsigned" } }, + { BOOL, { sizeof (_Bool) * CHAR_BIT, CHAR_BIT, 1, + BOOL, BOOL, + 1, 1, 0, 1, 1, "_Bool" } }, { CHAR, { CHAR_BIT, CHAR_BIT, 20, SCHAR, UCHAR, 1, 0, 0, 1, 1, "char" } }, @@ -139,6 +142,32 @@ initdecl(void) { LDOUBLE, { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT, -1, LDOUBLE, LDOUBLE, 0, 0, 1, 1, 1, "long double" } }, + { COMPLEX, { sizeof (float _Complex) * CHAR_BIT, + 8 * CHAR_BIT, -1, + COMPLEX, COMPLEX, + 0, 0, 1, 1, 3, "float _Complex" } }, + { DCOMPLEX, { sizeof (double _Complex) * CHAR_BIT, + 16 * CHAR_BIT, -1, + DCOMPLEX, DCOMPLEX, + 0, 0, 1, 1, 3, "double _Complex" } }, + { LDCOMPLEX,{ sizeof (long double _Complex) * CHAR_BIT, + 20 * CHAR_BIT, -1, + LDCOMPLEX, LDCOMPLEX, + 0, 0, 1, 1, 3, "long double _Complex" } }, +#if 0 + { IMAGINARY,{ sizeof (float _Imaginary) * CHAR_BIT, + 4 * CHAR_BIT, -1, + IMAGINARY, IMAGINARY, + 0, 0, 1, 1, 2, "float _Imaginary" } }, + { DIMAGINARY,{ sizeof (double _Imaginary) * CHAR_BIT, + 8 * CHAR_BIT, -1, + DIMAGINARY, DIMAGINARY, + 0, 0, 1, 1, 2, "double _Imaginary" } }, + { LDIMAGINARY,{ sizeof (long double _Imaginary) * CHAR_BIT, + 10 * CHAR_BIT, -1, + LDIMAGINARY, LDIMAGINARY, + 0, 0, 1, 1, 2, "long double _Imaginary" } }, +#endif { VOID, { -1, -1, -1, VOID, VOID, 0, 0, 0, 0, 0, "void" } }, @@ -179,6 +208,7 @@ initdecl(void) typetab = xcalloc(NTSPEC, sizeof (type_t)); for (i = 0; i < NTSPEC; i++) typetab[i].t_tspec = NOTSPEC; + typetab[BOOL].t_tspec = BOOL; typetab[CHAR].t_tspec = CHAR; typetab[SCHAR].t_tspec = SCHAR; typetab[UCHAR].t_tspec = UCHAR; @@ -193,6 +223,12 @@ initdecl(void) typetab[FLOAT].t_tspec = FLOAT; typetab[DOUBLE].t_tspec = DOUBLE; typetab[LDOUBLE].t_tspec = LDOUBLE; + typetab[COMPLEX].t_tspec = COMPLEX; + typetab[DCOMPLEX].t_tspec = DCOMPLEX; + typetab[LDCOMPLEX].t_tspec = LDCOMPLEX; + typetab[IMAGINARY].t_tspec = IMAGINARY; + typetab[DIMAGINARY].t_tspec = DIMAGINARY; + typetab[LDIMAGINARY].t_tspec = LDIMAGINARY; typetab[VOID].t_tspec = VOID; /* * Next two are not real types. They are only used by the parser @@ -203,7 +239,7 @@ initdecl(void) } /* - * Returns a shared type structure vor arithmetic types and void. + * Returns a shared type structure for arithmetic types and void. * * It's important to duplicate this structure (using duptyp() or tduptyp()) * if it is to be modified (adding qualifiers or anything else). @@ -327,7 +363,8 @@ addtype(type_t *tp) if (tp->t_typedef) { if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC || - dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) { + dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC || + dcs->d_dmod != NOTSPEC) { /* * something like "typedef int a; int a b;" * This should not happen with current grammar. @@ -346,13 +383,15 @@ addtype(type_t *tp) * struct/union/enum with anything else is not allowed */ if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC || - dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) { + dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC || + dcs->d_dmod != NOTSPEC) { /* * remember that an error must be reported in * deftyp(). */ dcs->d_terr = 1; - dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC; + dcs->d_atyp = dcs->d_smod = dcs->d_lmod = + dcs->d_dmod = NOTSPEC; } dcs->d_type = tp; return; @@ -401,6 +440,15 @@ addtype(type_t *tp) /* more than one, print error in deftyp() */ dcs->d_terr = 1; dcs->d_lmod = t; + } else if (t == COMPLEX || t == IMAGINARY) { + /* + * remember specifiers "_Complex" and "_Imaginary" in + * dcs->d_dmod + */ + if (dcs->d_dmod != NOTSPEC) + /* more than one, print error in deftyp() */ + dcs->d_terr = 1; + dcs->d_dmod = t; } else { /* * remember specifiers "void", "char", "int", "float" or @@ -447,7 +495,8 @@ tdeferr(type_t *td, tspec_t t) break; case LONG: if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG || - t2 == FLOAT || t2 == DOUBLE) { + t2 == FLOAT || t2 == DOUBLE || t2 == COMPLEX || + t2 == IMAGINARY) { /* modifying typedef with ... */ warning(5, "long"); if (t2 == INT) { @@ -462,6 +511,14 @@ tdeferr(type_t *td, tspec_t t) td = gettyp(DOUBLE); } else if (t2 == DOUBLE) { td = gettyp(LDOUBLE); + } else if (t2 == COMPLEX) { + td = gettyp(DCOMPLEX); + } else if (t2 == DCOMPLEX) { + td = gettyp(LDCOMPLEX); + } else if (t2 == IMAGINARY) { + td = gettyp(DIMAGINARY); + } else if (t2 == DIMAGINARY) { + td = gettyp(LDIMAGINARY); } td = duptyp(td); td->t_typedef = 1; @@ -657,7 +714,7 @@ setasm(void) void clrtyp(void) { - dcs->d_atyp = dcs->d_smod = dcs->d_lmod = NOTSPEC; + dcs->d_atyp = dcs->d_smod = dcs->d_lmod = dcs->d_dmod = NOTSPEC; dcs->d_scl = NOSCL; dcs->d_type = NULL; dcs->d_const = dcs->d_volatile = 0; @@ -668,6 +725,33 @@ clrtyp(void) } /* + * Merge the domain (_Complex or _Imaginary) into a type. Returns non-zero + * if the merge doesn't make sense. e.g., no "int _Complex". + */ +int +mergedomain(tspec_t *tp, tspec_t domain) +{ + if (domain == NOTSPEC) + return (0); + if (domain != COMPLEX && domain != IMAGINARY) + lerror("mergedomain()"); + switch (*tp) { + case FLOAT: + *tp = domain; + break; + case DOUBLE: + *tp = domain == COMPLEX ? DCOMPLEX : DIMAGINARY; + break; + case LDOUBLE: + *tp = domain == COMPLEX ? LDCOMPLEX : LDIMAGINARY; + break; + default: + return (1); + } + return (0); +} + +/* * Create a type structure from the informations gathered in * the declaration stack. * Complain about storage classes which are not possible in current @@ -676,13 +760,15 @@ clrtyp(void) void deftyp(void) { - tspec_t t, s, l; + tspec_t t, s, l, d; type_t *tp; scl_t scl; - t = dcs->d_atyp; /* CHAR, INT, FLOAT, DOUBLE, VOID */ + t = dcs->d_atyp; /* BOOL, CHAR, INT, FLOAT, + DOUBLE, VOID */ s = dcs->d_smod; /* SIGNED, UNSIGNED */ l = dcs->d_lmod; /* SHORT, LONG, QUAD */ + d = dcs->d_dmod; /* COMPLEX, IMAGINARY */ tp = dcs->d_type; scl = dcs->d_scl; @@ -699,6 +785,8 @@ deftyp(void) case NOTSPEC: t = INT; /* FALLTHROUGH */ + case BOOL: + break; case INT: if (s == NOTSPEC) s = SIGNED; @@ -728,6 +816,8 @@ deftyp(void) default: lerror("deftyp() 2"); } + if (mergedomain(&t, d)) + dcs->d_terr = 1; if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) { dcs->d_terr = 1; l = s = NOTSPEC; @@ -1059,7 +1149,7 @@ decl1str(sym_t *dsym) warning(34); } } else if (t != INT && t != UINT && t != LONG && - t != ULONG && t != QUAD && t != UQUAD) { + t != ULONG && t != QUAD && t != UQUAD && t != BOOL) { /* illegal bit-field type */ error(35); sz = tp->t_flen; @@ -1985,6 +2075,8 @@ eqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int *warn) if (promot) { if (t == FLOAT) { t = DOUBLE; + } else if (t == BOOL) { + t = INT; } else if (t == CHAR || t == SCHAR) { t = INT; } else if (t == UCHAR) { @@ -1994,6 +2086,10 @@ eqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int *warn) } else if (t == USHORT) { /* CONSTCOND */ t = INT_MAX < USHRT_MAX ? UINT : INT; + } else if (t == COMPLEX) { + t = DCOMPLEX; + } else if (t == IMAGINARY) { + t = DIMAGINARY; } } @@ -2087,9 +2183,11 @@ mnoarg(type_t *tp, int *warn) *warn = 1; } for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) { - if ((t = arg->s_type->t_tspec) == FLOAT || + if ((t = arg->s_type->t_tspec) == FLOAT || t == BOOL || t == CHAR || t == SCHAR || t == UCHAR || - t == SHORT || t == USHORT) { + t == SHORT || t == USHORT || t == COMPLEX || + t == DCOMPLEX || t == LDCOMPLEX || t == IMAGINARY || + t == DIMAGINARY || t == LDIMAGINARY) { if (warn != NULL) *warn = 1; } diff --git a/usr.bin/xlint/lint1/emit1.c b/usr.bin/xlint/lint1/emit1.c index 0ee39c3b55a..03f471e8f6e 100644 --- a/usr.bin/xlint/lint1/emit1.c +++ b/usr.bin/xlint/lint1/emit1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: emit1.c,v 1.7 2007/03/21 03:31:19 tedu Exp $ */ +/* $OpenBSD: emit1.c,v 1.8 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: emit1.c,v 1.4 1995/10/02 17:21:28 jpo Exp $ */ /* @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: emit1.c,v 1.7 2007/03/21 03:31:19 tedu Exp $"; +static char rcsid[] = "$OpenBSD: emit1.c,v 1.8 2010/07/24 22:17:03 guenther Exp $"; #endif #include <ctype.h> @@ -48,6 +48,7 @@ static void outfstrg(strg_t *); * The type is written as a sequence of substrings, each of which describes a * node of type type_t * a node is coded as follows: + * _Bool B * char C * signed char s C * unsigned char u C @@ -62,6 +63,12 @@ static void outfstrg(strg_t *); * float s D * double D * long double l D + * float _Complex s X + * double _Complex X + * long double _Complex l X + * float _Imaginary s J + * double _Imaginary J + * long double _Imaginary l J * void V * * P * [n] A n @@ -93,6 +100,7 @@ outtype(type_t *tp) if ((ts = tp->t_tspec) == INT && tp->t_isenum) ts = ENUM; switch (ts) { + case BOOL: t = 'B'; s = '\0'; break; case CHAR: t = 'C'; s = '\0'; break; case SCHAR: t = 'C'; s = 's'; break; case UCHAR: t = 'C'; s = 'u'; break; @@ -107,6 +115,12 @@ outtype(type_t *tp) case FLOAT: t = 'D'; s = 's'; break; case DOUBLE: t = 'D'; s = '\0'; break; case LDOUBLE: t = 'D'; s = 'l'; break; + case COMPLEX: t = 'X'; s = 's'; break; + case DCOMPLEX: t = 'X'; s = '\0'; break; + case LDCOMPLEX: t = 'X'; s = 'l'; break; + case IMAGINARY: t = 'J'; s = 's'; break; + case DIMAGINARY: t = 'J'; s = '\0'; break; + case LDIMAGINARY:t = 'J'; s = 'l'; break; case VOID: t = 'V'; s = '\0'; break; case PTR: t = 'P'; s = '\0'; break; case ARRAY: t = 'A'; s = '\0'; break; diff --git a/usr.bin/xlint/lint1/externs1.h b/usr.bin/xlint/lint1/externs1.h index 437c0d8eb93..d9d19299b16 100644 --- a/usr.bin/xlint/lint1/externs1.h +++ b/usr.bin/xlint/lint1/externs1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: externs1.h,v 1.15 2006/05/29 20:47:22 cloder Exp $ */ +/* $OpenBSD: externs1.h,v 1.16 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: externs1.h,v 1.7 1995/10/02 17:31:39 jpo Exp $ */ /* @@ -138,6 +138,7 @@ extern void pushdecl(scl_t); extern void popdecl(void); extern void setasm(void); extern void clrtyp(void); +extern int mergedomain(tspec_t *, tspec_t); extern void deftyp(void); extern int length(type_t *, const char *); extern int getbound(type_t *); diff --git a/usr.bin/xlint/lint1/lint.h b/usr.bin/xlint/lint1/lint.h index 8ecadbee938..570832e04e5 100644 --- a/usr.bin/xlint/lint1/lint.h +++ b/usr.bin/xlint/lint1/lint.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lint.h,v 1.6 2006/05/29 20:47:22 cloder Exp $ */ +/* $OpenBSD: lint.h,v 1.7 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: lint.h,v 1.2 1995/07/03 21:24:18 cgd Exp $ */ /* @@ -45,6 +45,7 @@ typedef enum { NOTSPEC, SIGNED, /* keyword "signed", only used in the parser */ UNSIGN, /* keyword "unsigned", only used in the parser */ + BOOL, /* _Bool */ CHAR, /* char */ SCHAR, /* signed char */ UCHAR, /* unsigned char */ @@ -59,6 +60,12 @@ typedef enum { FLOAT, /* float */ DOUBLE, /* double */ LDOUBLE, /* long double */ + COMPLEX, /* float _Complex */ + DCOMPLEX, /* double _Complex */ + LDCOMPLEX, /* long double _Complex */ + IMAGINARY, /* float _Imaginary */ + DIMAGINARY, /* double _Imaginary */ + LDIMAGINARY, /* long double _Imaginary */ VOID, /* void */ STRUCT, /* structure tag */ UNION, /* union tag */ @@ -83,7 +90,8 @@ typedef struct { u_int tt_isutyp : 1; /* 1 if unsigned integer type */ u_int tt_isftyp : 1; /* 1 if floating point type */ u_int tt_isatyp : 1; /* 1 if arithmetic type */ - u_int tt_issclt : 1; /* 1 if scalar type */ + u_int tt_domain : 2; /* 0 if non-scalar, 1 if real, + 2 if imaginary, 3 if complex */ char *tt_name; /* type name */ } ttab_t; @@ -96,7 +104,9 @@ typedef struct { #define isutyp(t) (ttab[t].tt_isutyp) #define isftyp(t) (ttab[t].tt_isftyp) #define isatyp(t) (ttab[t].tt_isatyp) -#define issclt(t) (ttab[t].tt_issclt) +#define issclt(t) (ttab[t].tt_domain != 0) +#define iscomplex(t) (ttab[t].tt_domain == 3) +#define isimag(t) (ttab[t].tt_domain == 2) extern ttab_t ttab[]; diff --git a/usr.bin/xlint/lint1/lint1.h b/usr.bin/xlint/lint1/lint1.h index d4d3f8ed9a9..39f24fe9ad7 100644 --- a/usr.bin/xlint/lint1/lint1.h +++ b/usr.bin/xlint/lint1/lint1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lint1.h,v 1.13 2006/04/18 02:59:40 cloder Exp $ */ +/* $OpenBSD: lint1.h,v 1.14 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: lint1.h,v 1.6 1995/10/02 17:31:41 jpo Exp $ */ /* @@ -224,6 +224,7 @@ typedef struct sym { tqual_t _s_tqu; /* qualifier (only for keywords) */ struct sym *_s_args; /* arguments in old style function definitions */ + op_t _s_op; /* op type (only for operators) */ } u; struct sym *s_link; /* next symbol with same hash value */ struct sym **s_rlink; /* pointer to s_link of prev. symbol */ @@ -236,6 +237,7 @@ typedef struct sym { #define s_etyp u._s_et #define s_tspec u._s_tsp #define s_tqual u._s_tqu +#define s_op u._s_op #define s_args u._s_args /* @@ -294,9 +296,10 @@ typedef struct tnode { * */ typedef struct dinfo { - tspec_t d_atyp; /* VOID, CHAR, INT, FLOAT or DOUBLE */ - tspec_t d_smod; /* SIGNED or UNSIGN */ - tspec_t d_lmod; /* SHORT, LONG or QUAD */ + tspec_t d_atyp; /* NOTSPEC, VOID, CHAR, INT, FLOAT or DOUBLE */ + tspec_t d_smod; /* sign: NOTSPEC, SIGNED or UNSIGN */ + tspec_t d_lmod; /* length: NOTSPEC, SHORT, LONG or QUAD */ + tspec_t d_dmod; /* domain: NOTSPEC, COMPLEX or IMAGINARY */ scl_t d_scl; /* storage class */ type_t *d_type; /* after deftyp() pointer to the type used for all declarators */ diff --git a/usr.bin/xlint/lint1/op.h b/usr.bin/xlint/lint1/op.h index 80d55631795..2198822f8aa 100644 --- a/usr.bin/xlint/lint1/op.h +++ b/usr.bin/xlint/lint1/op.h @@ -1,4 +1,4 @@ -/* $OpenBSD: op.h,v 1.3 2005/11/29 20:09:57 cloder Exp $ */ +/* $OpenBSD: op.h,v 1.4 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: op.h,v 1.2 1995/07/03 21:24:27 cgd Exp $ */ /* @@ -114,6 +114,8 @@ typedef enum { LOAD, PUSH, RETURN, + REAL, /* gcc extension: __real__ */ + IMAG, /* gcc extension: __imag__ */ INIT, /* pseudo op, not used in trees */ CASE, /* pseudo op, not used in trees */ FARG /* pseudo op, not used in trees */ diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l index a8cf8d71463..55002fff854 100644 --- a/usr.bin/xlint/lint1/scan.l +++ b/usr.bin/xlint/lint1/scan.l @@ -1,5 +1,5 @@ %{ -/* $OpenBSD: scan.l,v 1.31 2007/09/05 16:32:17 fgsch Exp $ */ +/* $OpenBSD: scan.l,v 1.32 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: scan.l,v 1.8 1995/10/23 13:38:51 jpo Exp $ */ /* @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: scan.l,v 1.31 2007/09/05 16:32:17 fgsch Exp $"; +static char rcsid[] = "$OpenBSD: scan.l,v 1.32 2010/07/24 22:17:03 guenther Exp $"; #endif #include <stdlib.h> @@ -91,6 +91,7 @@ OD [0-7] HD [0-9A-Fa-f] EX ([eE][+-]?[0-9]+) HEX ([pP][+-]?[0-9]+) +FSUFF ([fFlL][iIjJ]?|[iIjJ][fFlL]?)? %% @@ -98,12 +99,12 @@ HEX ([pP][+-]?[0-9]+) 0{OD}*[lLuU]* return (icon(8)); {NZD}{D}*[lLuU]* return (icon(10)); 0[xX]{HD}+[lLuU]* return (icon(16)); -{D}+\.{D}*{EX}?[fFlL]? | -{D}+{EX}[fFlL]? | -\.{D}+{EX}?[fFlL]? return (fcon()); -0[xX]{HD}+\.{HD}*{HEX}[fFlL]? | -0[xX]{HD}+{HEX}[fFlL]? | -0[xX]\.{HD}+{HEX}[fFlL]? return (fhexcon()); +{D}+\.{D}*{EX}?{FSUFF} | +{D}+{EX}{FSUFF} | +\.{D}+{EX}?{FSUFF} return (fcon()); +0[xX]{HD}+\.{HD}*{HEX}{FSUFF} | +0[xX]{HD}+{HEX}{FSUFF} | +0[xX]\.{HD}+{HEX}{FSUFF} return (fhexcon()); "=" return (operator(T_ASSIGN, ASSIGN)); "*=" return (operator(T_OPASS, MULASS)); "/=" return (operator(T_OPASS, DIVASS)); @@ -189,6 +190,7 @@ static struct kwtab { scl_t kw_scl; /* storage class if kw_token T_SCLASS */ tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */ tqual_t kw_tqual; /* type qual. if kw_token T_QUAL */ + op_t kw_op; /* operator if kw_token T_UNOP */ } kw_u; u_int kw_stdc : 1; /* STDC keyword */ u_int kw_gcc : 1; /* GCC keyword */ @@ -198,9 +200,12 @@ static struct kwtab { { "__asm__", T_ASM, { 0 }, 0, 0 }, { "__attribute__", T_ATTRIBUTE, { 0 }, 0, 0 }, { "auto", T_SCLASS, { AUTO }, 0, 0 }, + { "_Bool", T_TYPE, { BOOL }, 1, 0 }, { "break", T_BREAK, { 0 }, 0, 0 }, { "case", T_CASE, { 0 }, 0, 0 }, { "char", T_TYPE, { CHAR }, 0, 0 }, + { "_Complex", T_TYPE, { COMPLEX }, 1, 0 }, + { "__complex__", T_TYPE, { COMPLEX }, 0, 1 }, { "const", T_QUAL, { CONST }, 1, 0 }, { "__const__", T_QUAL, { CONST }, 0, 0 }, { "__const", T_QUAL, { CONST }, 0, 0 }, @@ -215,12 +220,15 @@ static struct kwtab { { "for", T_FOR, { 0 }, 0, 0 }, { "goto", T_GOTO, { 0 }, 0, 0 }, { "if", T_IF, { 0 }, 0, 0 }, + { "__imag__", T_UNOP, { IMAG }, 0, 0 /*1*/ }, +/* { "_Imaginary", T_TYPE, { IMAGINARY }, 1, 0 }, */ { "inline", T_SCLASS, { INLINE }, 1, 0 }, { "__inline__", T_SCLASS, { INLINE }, 0, 0 }, { "__inline", T_SCLASS, { INLINE }, 0, 0 }, { "int", T_TYPE, { INT }, 0, 0 }, { "__lint_equal__", T_LEQUAL, { 0 }, 0, 0 }, { "long", T_TYPE, { LONG }, 0, 0 }, + { "__real__", T_UNOP, { REAL }, 0, 0 /*1*/ }, { "register", T_SCLASS, { REG }, 0, 0 }, { "__restrict", T_QUAL, { RESTRICT }, 0, 0 }, { "__restrict__", T_QUAL, { RESTRICT }, 0, 0 }, @@ -247,6 +255,7 @@ static struct kwtab { #define kw_scl kw_u.kw_scl #define kw_tspec kw_u.kw_tspec #define kw_tqual kw_u.kw_tqual +#define kw_op kw_u.kw_op /* Symbol table */ static sym_t *symtab[HSHSIZ1]; @@ -292,6 +301,8 @@ initscan(void) sym->s_scl = kw->kw_scl; } else if (kw->kw_token == T_QUAL) { sym->s_tqual = kw->kw_tqual; + } else if (kw->kw_token == T_UNOP) { + sym->s_op = kw->kw_op; } h = hash(sym->s_name); if ((sym->s_link = symtab[h]) != NULL) @@ -444,6 +455,8 @@ keyw(sym_t *sym) yylval.y_tspec = sym->s_tspec; } else if (t == T_QUAL) { yylval.y_tqual = sym->s_tqual; + } else if (t == T_UNOP) { + yylval.y_op = sym->s_op; } return (t); } @@ -627,6 +640,7 @@ fcon(void) const char *cp; int len; tspec_t typ; + tspec_t domain = NOTSPEC; char c, *eptr; double d; float f; @@ -634,15 +648,29 @@ fcon(void) cp = yytext; len = yyleng; - if ((c = cp[len - 1]) == 'f' || c == 'F') { + c = cp[len - 1]; + if (c == 'i' || c == 'I' || c == 'j' || c == 'J') { + domain = COMPLEX; /* XXX should be IMAGINARY */ + len--; + c = cp[len - 1]; + } + if (c == 'f' || c == 'F') { typ = FLOAT; len--; + c = cp[len - 1]; } else if (c == 'l' || c == 'L') { typ = LDOUBLE; len--; + c = cp[len - 1]; } else { typ = DOUBLE; } + if (c == 'i' || c == 'I' || c == 'j' || c == 'J') { + if (domain != NOTSPEC) + lerror("fcon() 2"); /* can't happen */ + domain = COMPLEX; /* XXX should be IMAGINARY */ + len--; + } errno = 0; d = strtod(cp, &eptr); @@ -661,12 +689,15 @@ fcon(void) } } - (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; + yylval.y_val = xcalloc(1, sizeof (val_t)); if (typ == FLOAT) { yylval.y_val->v_ldbl = f; } else { yylval.y_val->v_ldbl = d; } + if (mergedomain(&typ, domain)) + lerror("fcon() 3"); + yylval.y_val->v_tspec = typ; return (T_CON); } @@ -684,6 +715,7 @@ fhexcon(void) const char *cp; int len; tspec_t typ; + tspec_t domain = NOTSPEC; char c; double d; float f; @@ -691,15 +723,29 @@ fhexcon(void) cp = yytext; len = yyleng; - if ((c = cp[len - 1]) == 'f' || c == 'F') { + c = cp[len - 1]; + if (c == 'i' || c == 'I' || c == 'j' || c == 'J') { + domain = COMPLEX; /* XXX should be IMAGINARY */ + len--; + c = cp[len - 1]; + } + if (c == 'f' || c == 'F') { typ = FLOAT; len--; + c = cp[len - 1]; } else if (c == 'l' || c == 'L') { typ = LDOUBLE; len--; + c = cp[len - 1]; } else { typ = DOUBLE; } + if (c == 'i' || c == 'I' || c == 'j' || c == 'J') { + if (domain != NOTSPEC) + lerror("fhexcon() 1"); /* can't happen */ + domain = COMPLEX; /* XXX should be IMAGINARY */ + len--; + } /* arbitrary value, until strtod can cope */ d = 1.0; @@ -708,12 +754,15 @@ fhexcon(void) f = (float)d; } - (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; + yylval.y_val = xcalloc(1, sizeof (val_t)); if (typ == FLOAT) { yylval.y_val->v_ldbl = f; } else { yylval.y_val->v_ldbl = d; } + if (mergedomain(&typ, domain)) + lerror("fhexcon() 2"); + yylval.y_val->v_tspec = typ; return (T_CON); } diff --git a/usr.bin/xlint/lint1/tree.c b/usr.bin/xlint/lint1/tree.c index c674be2e743..0ed9c24eac4 100644 --- a/usr.bin/xlint/lint1/tree.c +++ b/usr.bin/xlint/lint1/tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tree.c,v 1.46 2007/10/17 20:10:44 chl Exp $ */ +/* $OpenBSD: tree.c,v 1.47 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: tree.c,v 1.12 1995/10/02 17:37:57 jpo Exp $ */ /* @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: tree.c,v 1.46 2007/10/17 20:10:44 chl Exp $"; +static char rcsid[] = "$OpenBSD: tree.c,v 1.47 2010/07/24 22:17:03 guenther Exp $"; #endif #include <stdlib.h> @@ -203,6 +203,10 @@ initmtab(void) "PUSH" } }, { RETURN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, "RETURN" } }, + { REAL, { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1, + "__real__" } }, + { IMAG, { 0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,1, + "__imag__" } }, { INIT, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, "INIT" } }, { FARG, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, @@ -629,6 +633,17 @@ build(op_t op, tnode_t *ln, tnode_t *rn) case QUEST: ntn = mktnode(op, rn->tn_type, ln, rn); break; + case REAL: + case IMAG: + rtp = ln->tn_type; + if (rtp->t_tspec == COMPLEX) + rtp = gettyp(FLOAT); + else if (rtp->t_tspec == DCOMPLEX) + rtp = gettyp(DOUBLE); + else if (rtp->t_tspec == LDCOMPLEX) + rtp = gettyp(LDOUBLE); + ntn = mktnode(op, rtp, ln, rn); + break; default: rtp = mp->m_logop ? gettyp(INT) : ln->tn_type; if (!mp->m_binary && rn != NULL) @@ -747,6 +762,9 @@ typeok(op_t op, farg_t *farg, tnode_t *ln, tnode_t *rn) } if (mp->m_rqint) { + if (op == COMPL && iscomplex(lt)) { + /* use of '~' for complex conjugation is a GNUism */ + } else /* integer types required */ if (!isityp(lt) || (mp->m_binary && !isityp(rt))) { incompat(op, lt, rt); @@ -1434,6 +1452,8 @@ mktnode(op_t op, type_t *type, tnode_t *ln, tnode_t *rn) } else { lerror("mktnode() 2"); } + } else if (op == REAL || op == IMAG) { + ntn->tn_lvalue = ln->tn_lvalue; } return (ntn); @@ -1715,6 +1735,10 @@ iiconv(op_t op, farg_t *farg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) if (op == CVT) return; + /* logical ops return int, so silently convert int to _Bool */ + if (ot == INT && nt == BOOL) + return; + if (rank(nt) < rank(ot)) { /* coercion from greater to lesser width */ if (op == FARG) { @@ -1842,6 +1866,8 @@ cvtcon(op_t op, farg_t *farg, type_t *tp, val_t *nv, val_t *v) if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) { switch (nt) { + case BOOL: + max = 1; min = 0; break; case CHAR: max = CHAR_MAX; min = CHAR_MIN; break; case UCHAR: @@ -1873,11 +1899,21 @@ cvtcon(op_t op, farg_t *farg, type_t *tp, val_t *nv, val_t *v) /* Already an error because of float --> ptr */ case LDOUBLE: max = LDBL_MAX; min = -LDBL_MAX; break; + case COMPLEX: + max = FLT_MAX; min = -FLT_MAX; break; + case DCOMPLEX: + max = DBL_MAX; min = -DBL_MAX; break; + case LDCOMPLEX: + max = LDBL_MAX; min = -LDBL_MAX; break; + case IMAGINARY: + case DIMAGINARY: + case LDIMAGINARY: + max = 0; min = 0; break; default: lerror("cvtcon() 1"); } if (v->v_ldbl > max || v->v_ldbl < min) { - if (nt == LDOUBLE) + if (nt == LDOUBLE || nt == LDCOMPLEX) lerror("cvtcon() 2"); if (op == FARG) { /* %s arg #%d: conv. of %s to %s is out of range */ @@ -1900,15 +1936,18 @@ cvtcon(op_t op, farg_t *farg, type_t *tp, val_t *nv, val_t *v) (u_quad_t)v->v_ldbl : (quad_t)v->v_ldbl; } } else { - if (nt == FLOAT) { + if (nt == FLOAT || nt == COMPLEX) { nv->v_ldbl = (ot == PTR || isutyp(ot)) ? (float)(u_quad_t)v->v_quad : (float)v->v_quad; - } else if (nt == DOUBLE) { + } else if (nt == DOUBLE || nt == DCOMPLEX) { nv->v_ldbl = (ot == PTR || isutyp(ot)) ? (double)(u_quad_t)v->v_quad : (double)v->v_quad; - } else if (nt == LDOUBLE) { + } else if (nt == LDOUBLE || nt == LDCOMPLEX) { nv->v_ldbl = (ot == PTR || isutyp(ot)) ? (ldbl_t)(u_quad_t)v->v_quad : (ldbl_t)v->v_quad; + } else if (nt == IMAGINARY || nt == DIMAGINARY || + nt == LDIMAGINARY) { + nv->v_ldbl = 0; } else { rchk = 1; /* Check for lost precision. */ nv->v_quad = v->v_quad; @@ -2200,6 +2239,7 @@ tyname(type_t *tp) t = ENUM; switch (t) { + case BOOL: s = "_Bool"; break; case CHAR: s = "char"; break; case UCHAR: s = "unsigned char"; break; case SCHAR: s = "signed char"; break; @@ -2214,6 +2254,12 @@ tyname(type_t *tp) case FLOAT: s = "float"; break; case DOUBLE: s = "double"; break; case LDOUBLE: s = "long double"; break; + case COMPLEX: s = "float _Complex"; break; + case DCOMPLEX: s = "double _Complex"; break; + case LDCOMPLEX: s = "long double _Complex"; break; + case IMAGINARY: s = "float _Imaginary"; break; + case DIMAGINARY: s = "double _Imaginary"; break; + case LDIMAGINARY:s = "long double _Imaginary"; break; case PTR: s = "pointer"; break; case ENUM: s = "enum"; break; case STRUCT: s = "struct"; break; @@ -2757,6 +2803,9 @@ fold(tnode_t *tn) case OR: q = utyp ? ul | ur : sl | sr; break; + case REAL: + case IMAG: + q = sl; default: lerror("fold() 5"); } @@ -2897,6 +2946,10 @@ foldflt(tnode_t *tn) case NE: v->v_quad = l != r; break; + case REAL: + case IMAG: + v->v_ldbl = l; + break; default: lerror("foldflt() 4"); } @@ -2933,6 +2986,8 @@ bldszoftrm(tnode_t *tn) case STAR: case NAME: case STRING: + case REAL: + case IMAG: break; default: warning(312, modtab[tn->tn_op].m_name); @@ -3504,6 +3559,8 @@ chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, case XORASS: case SHLASS: case SHRASS: + case REAL: + case IMAG: if (ln->tn_op == NAME && (reached || rchflg)) { sc = ln->tn_sym->s_scl; /* diff --git a/usr.bin/xlint/lint2/chk.c b/usr.bin/xlint/lint2/chk.c index 5dddd17b039..5ec065a5995 100644 --- a/usr.bin/xlint/lint2/chk.c +++ b/usr.bin/xlint/lint2/chk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: chk.c,v 1.16 2007/05/26 00:36:04 krw Exp $ */ +/* $OpenBSD: chk.c,v 1.17 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: chk.c,v 1.2 1995/07/03 21:24:42 cgd Exp $ */ /* @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: chk.c,v 1.16 2007/05/26 00:36:04 krw Exp $"; +static char rcsid[] = "$OpenBSD: chk.c,v 1.17 2010/07/24 22:17:03 guenther Exp $"; #endif #include <stdlib.h> @@ -83,6 +83,9 @@ inittyp(void) { UNSIGN, { 0, 0, 0, SIGNED, UNSIGN, 0, 0, 0, 0, 0, "unsigned" } }, + { BOOL, { sizeof (_Bool) * CHAR_BIT, CHAR_BIT, 1, + BOOL, BOOL, + 1, 1, 0, 1, 1, "_Bool" } }, { CHAR, { CHAR_BIT, CHAR_BIT, 20, SCHAR, UCHAR, 1, 0, 0, 1, 1, "char" } }, @@ -125,6 +128,18 @@ inittyp(void) { LDOUBLE, { sizeof (ldbl_t) * CHAR_BIT, 10 * CHAR_BIT, -1, LDOUBLE, LDOUBLE, 0, 0, 1, 1, 1, "long double" } }, + { COMPLEX, { sizeof (_Complex float) * CHAR_BIT, + 8 * CHAR_BIT, -1, + COMPLEX, COMPLEX, + 0, 0, 1, 1, 1, "float _Complex" } }, + { DCOMPLEX, { sizeof (double _Complex) * CHAR_BIT, + 16 * CHAR_BIT, -1, + DCOMPLEX, DCOMPLEX, + 0, 0, 1, 1, 1, "double _Complex" } }, + { LDCOMPLEX,{ sizeof (long double _Complex) * CHAR_BIT, + 20 * CHAR_BIT, -1, + LDCOMPLEX, LDCOMPLEX, + 0, 0, 1, 1, 1, "long double _Complex" } }, { VOID, { -1, -1, -1, VOID, VOID, 0, 0, 0, 0, 0, "void" } }, diff --git a/usr.bin/xlint/lint2/emit2.c b/usr.bin/xlint/lint2/emit2.c index de032bdb16b..08d796a0fa5 100644 --- a/usr.bin/xlint/lint2/emit2.c +++ b/usr.bin/xlint/lint2/emit2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: emit2.c,v 1.5 2005/11/20 17:09:55 cloder Exp $ */ +/* $OpenBSD: emit2.c,v 1.6 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: emit2.c,v 1.2 1995/07/03 21:24:44 cgd Exp $ */ /* @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: emit2.c,v 1.5 2005/11/20 17:09:55 cloder Exp $"; +static char rcsid[] = "$OpenBSD: emit2.c,v 1.6 2010/07/24 22:17:03 guenther Exp $"; #endif #include <err.h> @@ -58,6 +58,7 @@ outtype(type_t *tp) if ((ts = tp->t_tspec) == INT && tp->t_isenum) ts = ENUM; switch (ts) { + case BOOL: t = 'B'; s = '\0'; break; case CHAR: t = 'C'; s = '\0'; break; case SCHAR: t = 'C'; s = 's'; break; case UCHAR: t = 'C'; s = 'u'; break; @@ -72,6 +73,12 @@ outtype(type_t *tp) case FLOAT: t = 'D'; s = 's'; break; case DOUBLE: t = 'D'; s = '\0'; break; case LDOUBLE: t = 'D'; s = 'l'; break; + case COMPLEX: t = 'X'; s = 's'; break; + case DCOMPLEX: t = 'X'; s = '\0'; break; + case LDCOMPLEX: t = 'X'; s = 'l'; break; + case IMAGINARY: t = 'J'; s = 's'; break; + case DIMAGINARY: t = 'J'; s = '\0'; break; + case LDIMAGINARY:t = 'J'; s = 'l'; break; case VOID: t = 'V'; s = '\0'; break; case PTR: t = 'P'; s = '\0'; break; case ARRAY: t = 'A'; s = '\0'; break; diff --git a/usr.bin/xlint/lint2/read.c b/usr.bin/xlint/lint2/read.c index d59bf939d1d..615c6a971c8 100644 --- a/usr.bin/xlint/lint2/read.c +++ b/usr.bin/xlint/lint2/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.9 2005/12/01 05:06:40 cloder Exp $ */ +/* $OpenBSD: read.c,v 1.10 2010/07/24 22:17:03 guenther Exp $ */ /* $NetBSD: read.c,v 1.2 1995/07/03 21:24:59 cgd Exp $ */ /* @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$OpenBSD: read.c,v 1.9 2005/12/01 05:06:40 cloder Exp $"; +static char rcsid[] = "$OpenBSD: read.c,v 1.10 2010/07/24 22:17:03 guenther Exp $"; #endif #include <stdio.h> @@ -517,6 +517,9 @@ inptype(const char *cp, const char **epp) } switch (c) { + case 'B': + tp->t_tspec = BOOL; + break; case 'C': tp->t_tspec = s == 's' ? SCHAR : (s == 'u' ? UCHAR : CHAR); break; @@ -535,6 +538,14 @@ inptype(const char *cp, const char **epp) case 'D': tp->t_tspec = s == 's' ? FLOAT : (s == 'l' ? LDOUBLE : DOUBLE); break; + case 'X': + tp->t_tspec = s == 's' ? COMPLEX : (s == 'l' ? + LDCOMPLEX : DCOMPLEX); + break; + case 'J': + tp->t_tspec = s == 's' ? IMAGINARY : (s == 'l' ? + LDIMAGINARY : DIMAGINARY); + break; case 'V': tp->t_tspec = VOID; break; @@ -649,6 +660,9 @@ gettlen(const char *cp, const char **epp) t = NOTSPEC; switch (c) { + case 'B': + t = BOOL; + break; case 'C': if (s == 's') { t = SCHAR; @@ -695,6 +709,24 @@ gettlen(const char *cp, const char **epp) t = DOUBLE; } break; + case 'X': + if (s == 's') { + t = COMPLEX; + } else if (s == 'l') { + t = LDCOMPLEX; + } else if (s == '\0') { + t = DCOMPLEX; + } + break; + case 'J': + if (s == 's') { + t = IMAGINARY; + } else if (s == 'l') { + t = LDIMAGINARY; + } else if (s == '\0') { + t = DIMAGINARY; + } + break; case 'V': if (s == '\0') t = VOID; |