Module Name: src Committed By: rillig Date: Wed Nov 13 03:43:00 UTC 2024
Modified Files: src/tests/usr.bin/xlint/lint1: gcc_attribute_func.c msg_217.c src/usr.bin/xlint/common: tyname.c src/usr.bin/xlint/lint1: cgram.y debug.c decl.c externs1.h func.c lint1.h Log Message: lint: handle _Noreturn, [[noreturn]] and __attribute__((__noreturn__)) To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/tests/usr.bin/xlint/lint1/gcc_attribute_func.c cvs rdiff -u -r1.13 -r1.14 src/tests/usr.bin/xlint/lint1/msg_217.c cvs rdiff -u -r1.62 -r1.63 src/usr.bin/xlint/common/tyname.c cvs rdiff -u -r1.513 -r1.514 src/usr.bin/xlint/lint1/cgram.y cvs rdiff -u -r1.81 -r1.82 src/usr.bin/xlint/lint1/debug.c cvs rdiff -u -r1.407 -r1.408 src/usr.bin/xlint/lint1/decl.c cvs rdiff -u -r1.233 -r1.234 src/usr.bin/xlint/lint1/externs1.h cvs rdiff -u -r1.187 -r1.188 src/usr.bin/xlint/lint1/func.c cvs rdiff -u -r1.228 -r1.229 src/usr.bin/xlint/lint1/lint1.h 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/gcc_attribute_func.c diff -u src/tests/usr.bin/xlint/lint1/gcc_attribute_func.c:1.4 src/tests/usr.bin/xlint/lint1/gcc_attribute_func.c:1.5 --- src/tests/usr.bin/xlint/lint1/gcc_attribute_func.c:1.4 Tue Mar 28 14:44:34 2023 +++ src/tests/usr.bin/xlint/lint1/gcc_attribute_func.c Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: gcc_attribute_func.c,v 1.4 2023/03/28 14:44:34 rillig Exp $ */ +/* $NetBSD: gcc_attribute_func.c,v 1.5 2024/11/13 03:43:00 rillig Exp $ */ # 3 "gcc_attribute_func.c" /* @@ -23,11 +23,6 @@ void *__attribute__((__cold__)) attribut void *attribute_after_name __attribute__((__cold__))(void); void *attribute_after_parameters(void) __attribute__((__cold__)); -/* - * The attribute 'used' does not influence static functions, it only - * applies to function parameters. - */ -/* expect+2: warning: static function 'used_function' unused [236] */ static void __attribute__((used)) used_function(void) { Index: src/tests/usr.bin/xlint/lint1/msg_217.c diff -u src/tests/usr.bin/xlint/lint1/msg_217.c:1.13 src/tests/usr.bin/xlint/lint1/msg_217.c:1.14 --- src/tests/usr.bin/xlint/lint1/msg_217.c:1.13 Wed Nov 13 02:54:48 2024 +++ src/tests/usr.bin/xlint/lint1/msg_217.c Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: msg_217.c,v 1.13 2024/11/13 02:54:48 rillig Exp $ */ +/* $NetBSD: msg_217.c,v 1.14 2024/11/13 03:43:00 rillig Exp $ */ # 3 "msg_217.c" // Test for message: function '%s' falls off bottom without returning value [217] @@ -83,38 +83,28 @@ int call_noreturn_c11(void) { noreturn_c11(); - // FIXME - /* expect+1: warning: function 'call_noreturn_c11' falls off bottom without returning value [217] */ } int call_noreturn_c23(void) { noreturn_c23(); - // FIXME - /* expect+1: warning: function 'call_noreturn_c23' falls off bottom without returning value [217] */ } int call_noreturn_gnu_prefix(void) { noreturn_gnu_prefix(); - // FIXME - /* expect+1: warning: function 'call_noreturn_gnu_prefix' falls off bottom without returning value [217] */ } int call_noreturn_gnu_infix(void) { noreturn_gnu_infix(); - // FIXME - /* expect+1: warning: function 'call_noreturn_gnu_infix' falls off bottom without returning value [217] */ } int call_noreturn_gnu_suffix(void) { noreturn_gnu_suffix(); - // FIXME - /* expect+1: warning: function 'call_noreturn_gnu_suffix' falls off bottom without returning value [217] */ } Index: src/usr.bin/xlint/common/tyname.c diff -u src/usr.bin/xlint/common/tyname.c:1.62 src/usr.bin/xlint/common/tyname.c:1.63 --- src/usr.bin/xlint/common/tyname.c:1.62 Sat Mar 9 13:20:55 2024 +++ src/usr.bin/xlint/common/tyname.c Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: tyname.c,v 1.62 2024/03/09 13:20:55 rillig Exp $ */ +/* $NetBSD: tyname.c,v 1.63 2024/11/13 03:43:00 rillig Exp $ */ /*- * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: tyname.c,v 1.62 2024/03/09 13:20:55 rillig Exp $"); +__RCSID("$NetBSD: tyname.c,v 1.63 2024/11/13 03:43:00 rillig Exp $"); #endif #include <assert.h> @@ -261,6 +261,10 @@ type_name(const type_t *tp) buf_add(&buf, "const "); if (tp->t_volatile) buf_add(&buf, "volatile "); +#if IS_LINT1 + if (tp->t_noreturn) + buf_add(&buf, "noreturn "); +#endif #if IS_LINT1 if (is_struct_or_union(t) && tp->u.sou->sou_incomplete) Index: src/usr.bin/xlint/lint1/cgram.y diff -u src/usr.bin/xlint/lint1/cgram.y:1.513 src/usr.bin/xlint/lint1/cgram.y:1.514 --- src/usr.bin/xlint/lint1/cgram.y:1.513 Tue Oct 29 20:44:22 2024 +++ src/usr.bin/xlint/lint1/cgram.y Wed Nov 13 03:43:00 2024 @@ -1,5 +1,5 @@ %{ -/* $NetBSD: cgram.y,v 1.513 2024/10/29 20:44:22 rillig Exp $ */ +/* $NetBSD: cgram.y,v 1.514 2024/11/13 03:43:00 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: cgram.y,v 1.513 2024/10/29 20:44:22 rillig Exp $"); +__RCSID("$NetBSD: cgram.y,v 1.514 2024/11/13 03:43:00 rillig Exp $"); #endif #include <limits.h> @@ -956,6 +956,8 @@ begin_type_declaration_specifiers: /* se | type_attribute begin_type_declaration_specifiers { if ($1.used) dcs_set_used(); + if ($1.noreturn) + dcs->d_noreturn = true; } | begin_type_declaration_specifiers declmod | begin_type_declaration_specifiers notype_type_specifier { @@ -1025,7 +1027,12 @@ declmod: | T_FUNCTION_SPECIFIER { dcs_add_function_specifier($1); } -| type_attribute_list +| type_attribute_list { + if ($1.used) + dcs_set_used(); + if ($1.noreturn) + dcs->d_noreturn = true; + } ; type_attribute_list_opt: @@ -1072,6 +1079,7 @@ begin_type: | attribute_specifier_sequence { dcs_begin_type(); dcs->d_used = attributes_contain(&$1, "maybe_unused"); + dcs->d_noreturn = attributes_contain(&$1, "noreturn"); } ; @@ -1733,6 +1741,7 @@ abstract_decl_param_list: /* specific to $$ = $2; $$.prototype = true; $$.used = $4.used; + $$.noreturn = $4.noreturn; } | abstract_decl_lparen error T_RPAREN type_attribute_list_opt { $$ = (parameter_list){ .used = $4.used }; @@ -2130,6 +2139,9 @@ expression_statement: expression T_SEMI { expr($1, false, false, false, false); suppress_fallthrough = false; + if ($1 != NULL && $1->tn_op == CALL + && $1->u.call->func->tn_type->t_subt->t_noreturn) + stmt_call_noreturn(); } | T_SEMI { check_statement_reachable(); @@ -2511,6 +2523,8 @@ gcc_attribute: $$.used = true; else if (is_either(name, "fallthrough", "__fallthrough__")) suppress_fallthrough = true; + else if (is_either(name, "noreturn", "__noreturn__")) + $$.noreturn = true; } | T_NAME T_LPAREN T_RPAREN { $$ = (type_attributes){ .used = false }; Index: src/usr.bin/xlint/lint1/debug.c diff -u src/usr.bin/xlint/lint1/debug.c:1.81 src/usr.bin/xlint/lint1/debug.c:1.82 --- src/usr.bin/xlint/lint1/debug.c:1.81 Sat Sep 28 15:51:40 2024 +++ src/usr.bin/xlint/lint1/debug.c Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: debug.c,v 1.81 2024/09/28 15:51:40 rillig Exp $ */ +/* $NetBSD: debug.c,v 1.82 2024/11/13 03:43:00 rillig Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: debug.c,v 1.81 2024/09/28 15:51:40 rillig Exp $"); +__RCSID("$NetBSD: debug.c,v 1.82 2024/11/13 03:43:00 rillig Exp $"); #endif #include <stdlib.h> @@ -357,7 +357,12 @@ type_qualifiers_string(type_qualifiers t const char * type_attributes_string(type_attributes attrs) { - return attrs.used ? "used" : "none"; + static char buf[32]; + + snprintf(buf, sizeof(buf), "%s%s", + attrs.used ? " used" : "", + attrs.noreturn ? " noreturn" : ""); + return buf[0] != '\0' ? buf + 1 : "none"; } const char * @@ -505,6 +510,7 @@ debug_decl_level(const decl_level *dl) debug_word(dl->d_asm, "asm"); debug_word(dl->d_packed, "packed"); debug_word(dl->d_used, "used"); + debug_word(dl->d_noreturn, "noreturn"); if (dl->d_tag_type != NULL) debug_printf(" tag_type='%s'", type_name(dl->d_tag_type)); Index: src/usr.bin/xlint/lint1/decl.c diff -u src/usr.bin/xlint/lint1/decl.c:1.407 src/usr.bin/xlint/lint1/decl.c:1.408 --- src/usr.bin/xlint/lint1/decl.c:1.407 Tue Oct 29 20:48:31 2024 +++ src/usr.bin/xlint/lint1/decl.c Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: decl.c,v 1.407 2024/10/29 20:48:31 rillig Exp $ */ +/* $NetBSD: decl.c,v 1.408 2024/11/13 03:43:00 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: decl.c,v 1.407 2024/10/29 20:48:31 rillig Exp $"); +__RCSID("$NetBSD: decl.c,v 1.408 2024/11/13 03:43:00 rillig Exp $"); #endif #include <sys/param.h> @@ -191,6 +191,8 @@ dcs_add_function_specifier(function_spec warning(10, "inline"); dcs->d_inline = true; } + if (fs == FS_NORETURN) + dcs->d_noreturn = true; debug_func_dcs(__func__); } @@ -628,6 +630,7 @@ dcs_begin_type(void) // keep d_asm dcs->d_packed = false; dcs->d_used = false; + dcs->d_noreturn = false; // keep d_tag_type dcs->d_func_params = NULL; dcs->d_func_def_pos = (pos_t){ NULL, 0, 0 }; @@ -1293,13 +1296,15 @@ add_array(sym_t *decl, bool has_dim, int } static type_t * -block_derive_function(type_t *ret, bool proto, sym_t *params, bool vararg) +block_derive_function(type_t *ret, bool proto, sym_t *params, bool vararg, + bool noreturn) { type_t *tp = block_derive_type(ret, FUNC); tp->t_proto = proto; if (proto) tp->u.params = params; + tp->t_noreturn = noreturn; tp->t_vararg = vararg; debug_step("%s: '%s'", __func__, type_name(tp)); return tp; @@ -1410,7 +1415,8 @@ add_function(sym_t *decl, parameter_list } *tpp = block_derive_function(dcs->d_enclosing->d_type, - params.prototype, params.first, params.vararg); + params.prototype, params.first, params.vararg, + params.noreturn || dcs->d_enclosing->d_noreturn); debug_step("add_function: '%s'", type_name(decl->s_type)); debug_dcs_all(); Index: src/usr.bin/xlint/lint1/externs1.h diff -u src/usr.bin/xlint/lint1/externs1.h:1.233 src/usr.bin/xlint/lint1/externs1.h:1.234 --- src/usr.bin/xlint/lint1/externs1.h:1.233 Sat Sep 28 15:51:40 2024 +++ src/usr.bin/xlint/lint1/externs1.h Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: externs1.h,v 1.233 2024/09/28 15:51:40 rillig Exp $ */ +/* $NetBSD: externs1.h,v 1.234 2024/11/13 03:43:00 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -360,6 +360,7 @@ void stmt_goto(sym_t *); void stmt_continue(void); void stmt_break(void); void stmt_return(bool, tnode_t *); +void stmt_call_noreturn(void); void global_clean_up_decl(bool); void handle_lint_comment(lint_comment, int); Index: src/usr.bin/xlint/lint1/func.c diff -u src/usr.bin/xlint/lint1/func.c:1.187 src/usr.bin/xlint/lint1/func.c:1.188 --- src/usr.bin/xlint/lint1/func.c:1.187 Sun May 12 12:28:34 2024 +++ src/usr.bin/xlint/lint1/func.c Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: func.c,v 1.187 2024/05/12 12:28:34 rillig Exp $ */ +/* $NetBSD: func.c,v 1.188 2024/11/13 03:43:00 rillig Exp $ */ /* * Copyright (c) 1994, 1995 Jochen Pohl @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: func.c,v 1.187 2024/05/12 12:28:34 rillig Exp $"); +__RCSID("$NetBSD: func.c,v 1.188 2024/11/13 03:43:00 rillig Exp $"); #endif #include <stdlib.h> @@ -904,6 +904,12 @@ stmt_continue(void) set_reached(false); } +void +stmt_call_noreturn(void) +{ + set_reached(false); +} + static bool is_parenthesized(const tnode_t *tn) { Index: src/usr.bin/xlint/lint1/lint1.h diff -u src/usr.bin/xlint/lint1/lint1.h:1.228 src/usr.bin/xlint/lint1/lint1.h:1.229 --- src/usr.bin/xlint/lint1/lint1.h:1.228 Sat Sep 28 15:51:40 2024 +++ src/usr.bin/xlint/lint1/lint1.h Wed Nov 13 03:43:00 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: lint1.h,v 1.228 2024/09/28 15:51:40 rillig Exp $ */ +/* $NetBSD: lint1.h,v 1.229 2024/11/13 03:43:00 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -80,6 +80,7 @@ typedef struct { typedef struct { bool used; + bool noreturn; } type_attributes; /* A bool, integer or floating-point value. */ @@ -135,6 +136,7 @@ struct lint1_type { bool t_volatile:1; bool t_proto:1; /* function prototype (u.params valid) */ bool t_vararg:1; /* prototype with '...' */ + bool t_noreturn:1; /* function never returns normally */ bool t_typedef:1; /* type defined with typedef */ bool t_typeof:1; /* type defined with GCC's __typeof__ */ bool t_bitfield:1; @@ -366,6 +368,7 @@ typedef struct decl_level { bool d_asm:1; /* set if d_ctx == AUTO and asm() present */ bool d_packed:1; bool d_used:1; + bool d_noreturn:1; /* function never returns normally */ type_t *d_tag_type; /* during a member or enumerator declaration, * the tag type to which the member belongs */ sym_t *d_func_params; /* during a function declaration, the @@ -385,6 +388,7 @@ typedef struct { bool vararg:1; bool prototype:1; bool used:1; + bool noreturn:1; } parameter_list; /*