Module Name: src Committed By: rillig Date: Fri Jul 14 08:53:52 UTC 2023
Modified Files: src/tests/usr.bin/xlint/lint1: c23.c expr_binary.c msg_247.c msg_353.c src/usr.bin/xlint/lint1: lint1.h tree.c Log Message: lint: clean up comments, add a test for the '?:' operator To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/c23.c cvs rdiff -u -r1.7 -r1.8 src/tests/usr.bin/xlint/lint1/expr_binary.c cvs rdiff -u -r1.31 -r1.32 src/tests/usr.bin/xlint/lint1/msg_247.c cvs rdiff -u -r1.3 -r1.4 src/tests/usr.bin/xlint/lint1/msg_353.c cvs rdiff -u -r1.192 -r1.193 src/usr.bin/xlint/lint1/lint1.h cvs rdiff -u -r1.563 -r1.564 src/usr.bin/xlint/lint1/tree.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/usr.bin/xlint/lint1/c23.c diff -u src/tests/usr.bin/xlint/lint1/c23.c:1.2 src/tests/usr.bin/xlint/lint1/c23.c:1.3 --- src/tests/usr.bin/xlint/lint1/c23.c:1.2 Thu Jul 13 20:30:21 2023 +++ src/tests/usr.bin/xlint/lint1/c23.c Fri Jul 14 08:53:52 2023 @@ -1,16 +1,16 @@ -/* $NetBSD: c23.c,v 1.2 2023/07/13 20:30:21 rillig Exp $ */ +/* $NetBSD: c23.c,v 1.3 2023/07/14 08:53:52 rillig Exp $ */ # 3 "c23.c" // Tests for the option -Ac23, which allows features from C23 and all earlier // ISO standards, but none of the GNU extensions. // // See also: -// msg_353.c +// msg_353.c for empty initializer braces /* lint1-flags: -Ac23 -w -X 351 */ int -c23(void) +empty_initializer_braces(void) { struct s { int member; @@ -25,8 +25,7 @@ c23(void) // The keyword 'thread_local' was introduced in C23. thread_local int globally_visible; -// Thread-local functions don't make sense; they are syntactically allowed, -// though. +// Thread-local functions don't make sense; lint allows them, though. thread_local void thread_local_function(void) { Index: src/tests/usr.bin/xlint/lint1/expr_binary.c diff -u src/tests/usr.bin/xlint/lint1/expr_binary.c:1.7 src/tests/usr.bin/xlint/lint1/expr_binary.c:1.8 --- src/tests/usr.bin/xlint/lint1/expr_binary.c:1.7 Tue Mar 28 14:44:34 2023 +++ src/tests/usr.bin/xlint/lint1/expr_binary.c Fri Jul 14 08:53:52 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: expr_binary.c,v 1.7 2023/03/28 14:44:34 rillig Exp $ */ +/* $NetBSD: expr_binary.c,v 1.8 2023/07/14 08:53:52 rillig Exp $ */ # 3 "expr_binary.c" /* @@ -128,3 +128,38 @@ cover_balance(void) /* expect+1: ... '__uint128_t' ... */ sink((__int128_t)1 + (__uint128_t)1); } + +struct point { + int x, y; +}; + +static struct point +returning_struct(void) +{ + return (struct point){ 0, 0 }; +} + +static void +returning_void(void) +{ +} + +static inline void +op_colon(_Bool cond) +{ + // FIXME: GCC doesn't warn, as the 'type mismatch' is not wrong. + /* expect+1: warning: incompatible types 'struct point' and 'void' in conditional [126] */ + cond ? returning_struct() : returning_void(); + + // TODO: Test the other combinations as well. + // | | void | bool | arith | sou | int | flt | ptr | nullptr | + // |---------|------|------|-------|-----|-----|-----|-----|---------| + // | void | ok | | | | | | | | + // | bool | | ok | | | | | | | + // | arith | | | ok | | | | | | + // | sou | | | | ok | | | | | + // | int | | | | | | | ok | | + // | flt | | | | | | | | | + // | ptr | | | | | ok | | | ok | + // | nullptr | | | | | | | ok | | +} Index: src/tests/usr.bin/xlint/lint1/msg_247.c diff -u src/tests/usr.bin/xlint/lint1/msg_247.c:1.31 src/tests/usr.bin/xlint/lint1/msg_247.c:1.32 --- src/tests/usr.bin/xlint/lint1/msg_247.c:1.31 Fri Jul 7 06:03:31 2023 +++ src/tests/usr.bin/xlint/lint1/msg_247.c Fri Jul 14 08:53:52 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: msg_247.c,v 1.31 2023/07/07 06:03:31 rillig Exp $ */ +/* $NetBSD: msg_247.c,v 1.32 2023/07/14 08:53:52 rillig Exp $ */ # 3 "msg_247.c" // Test for message: pointer cast from '%s' to '%s' may be troublesome [247] @@ -59,7 +59,7 @@ cast_to_char_pointer(struct Other *arg) } /* - * In traditional C there was 'unsigned char' as well, so the same reasoning + * In traditional C, there was 'unsigned char' as well, so the same reasoning * as for plain 'char' applies here. */ unsigned char * Index: src/tests/usr.bin/xlint/lint1/msg_353.c diff -u src/tests/usr.bin/xlint/lint1/msg_353.c:1.3 src/tests/usr.bin/xlint/lint1/msg_353.c:1.4 --- src/tests/usr.bin/xlint/lint1/msg_353.c:1.3 Fri Jul 7 19:45:22 2023 +++ src/tests/usr.bin/xlint/lint1/msg_353.c Fri Jul 14 08:53:52 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: msg_353.c,v 1.3 2023/07/07 19:45:22 rillig Exp $ */ +/* $NetBSD: msg_353.c,v 1.4 2023/07/14 08:53:52 rillig Exp $ */ # 3 "msg_353.c" // Test for message 353: empty initializer braces require C23 or later [353] @@ -9,7 +9,7 @@ /* lint1-extra-flags: -Ac11 -X 351 */ void -c23(void) +empty_initializer_braces(void) { struct s { int member; Index: src/usr.bin/xlint/lint1/lint1.h diff -u src/usr.bin/xlint/lint1/lint1.h:1.192 src/usr.bin/xlint/lint1/lint1.h:1.193 --- src/usr.bin/xlint/lint1/lint1.h:1.192 Thu Jul 13 23:27:20 2023 +++ src/usr.bin/xlint/lint1/lint1.h Fri Jul 14 08:53:52 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: lint1.h,v 1.192 2023/07/13 23:27:20 rillig Exp $ */ +/* $NetBSD: lint1.h,v 1.193 2023/07/14 08:53:52 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -86,7 +86,7 @@ typedef struct { bool tq_atomic:1; } type_qualifiers; -/* An integer or floating-point value. */ +/* A bool, integer or floating-point value. */ typedef struct { tspec_t v_tspec; /* @@ -293,11 +293,10 @@ typedef struct tnode { bool tn_lvalue:1; /* node is lvalue */ bool tn_cast:1; /* if tn_op == CVT, it's an explicit cast */ bool tn_parenthesized:1; - bool tn_sys:1; /* in strict bool mode, allow mixture between - * bool and scalar, for code from system - * headers that may be a mixture between - * scalar types and bool - */ + bool tn_sys:1; /* the operator comes from a system header; + * used in strict bool mode to allow mixing + * bool and scalar, as these places are not + * considered fixable */ bool tn_system_dependent:1; /* depends on sizeof or offsetof */ union { struct { @@ -392,7 +391,7 @@ typedef struct decl_level { * A sequence of asterisks and qualifiers, from right to left. For example, * 'const ***volatile **const volatile' results in [c-v-, ----, --v-, ----, * ----]. The leftmost 'const' is not included in this list, it is stored in - * dcs->d_const instead. + * dcs->d_qual instead. */ typedef struct qual_ptr { type_qualifiers qualifiers; Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.563 src/usr.bin/xlint/lint1/tree.c:1.564 --- src/usr.bin/xlint/lint1/tree.c:1.563 Thu Jul 13 08:40:38 2023 +++ src/usr.bin/xlint/lint1/tree.c Fri Jul 14 08:53:52 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.563 2023/07/13 08:40:38 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.564 2023/07/14 08:53:52 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: tree.c,v 1.563 2023/07/13 08:40:38 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.564 2023/07/14 08:53:52 rillig Exp $"); #endif #include <float.h> @@ -343,9 +343,7 @@ expr_derive_type(type_t *tp, tspec_t t) return tp2; } -/* - * Build and initialize a new node. - */ +/* Create an expression from a unary or binary operator and its operands. */ static tnode_t * new_tnode(op_t op, bool sys, type_t *type, tnode_t *ln, tnode_t *rn) { @@ -367,9 +365,6 @@ new_tnode(op_t op, bool sys, type_t *typ return ntn; } -/* - * Create a node for a constant. - */ tnode_t * build_constant(type_t *tp, val_t *v) { @@ -408,6 +403,7 @@ fallback_symbol(sym_t *sym) strcmp(sym->s_name, "__PRETTY_FUNCTION__") == 0)) { /* __FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension */ gnuism(316); + // XXX: Should probably be ARRAY instead of PTR. sym->s_type = block_derive_type(gettyp(CHAR), PTR); sym->s_type->t_const = true; return; @@ -1159,6 +1155,9 @@ build_bit_shift(op_t op, bool sys, tnode { if (!allow_c90 && rn->tn_type->t_tspec != INT) + // XXX: C1978 7.5 says: "Both [operators] perform the usual + // arithmetic conversions on their operands." + // TODO: Add a test to exercise this part of the code. rn = convert(NOOP, 0, gettyp(INT), rn); return new_tnode(op, sys, ln->tn_type, ln, rn); } @@ -1168,6 +1167,9 @@ is_null_pointer(const tnode_t *tn) { tspec_t t = tn->tn_type->t_tspec; + // TODO: Investigate how other pointers are stored, in particular, + // whether a pointer constant can have a non-zero value. + // If not, simplify the code below. return ((t == PTR && tn->tn_type->t_subt->t_tspec == VOID) || is_integer(t)) && (tn->tn_op == CON && tn->tn_val.u.integer == 0); @@ -1624,6 +1626,7 @@ fold_float(tnode_t *tn) lint_assert(/*CONSTCOND*/false); } + // XXX: Must not access u.floating after setting u.integer. lint_assert(fpe != 0 || isnan(v->u.floating) == 0); if (is_complex(v->v_tspec)) { /* @@ -2285,7 +2288,7 @@ typeok_shr(op_t op, !is_uinteger(olt) && !is_uinteger(ort) && portable_rank_cmp(lt, rt) < 0) { /* - * In traditional C the left operand would be extended + * In traditional C, the left operand would be extended * (possibly sign-extended) and then shifted. */ if (hflag && (ln->tn_op != CON || ln->tn_val.u.integer < 0)) {