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;
/*