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

Reply via email to