linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] sparse/parse: update decl->pos when direct_declarator() sees TOKEN_IDENT
@ 2025-12-21 14:28 Oleg Nesterov
  0 siblings, 0 replies; only message in thread
From: Oleg Nesterov @ 2025-12-21 14:28 UTC (permalink / raw)
  To: Chris Li, Luc Van Oostenryck; +Cc: Alexey Gladkov, linux-sparse

Test-case:

	$ cat -n DECL_POS.c
	     1	void
	     2	 *       ptr,
	     3	 *   (*  fptr  ) (int),
	     4	 *       ary[2];
	     5
	     6	struct T {
	     7	 void
	     8	  *      mptr1[],
	     9	  *      mptr2[];
	    10	 int     dummy;
	    11	};
	    12
	    13	static void func(struct T *t)
	    14	{
	    15		__builtin_offsetof(typeof(*t), dummy);
	    16	}

Note that all variables/members are defined at column 10.

However, before this patch

	$ ./sparse DECL_POS.c
	DECL_POS.c:2:2: warning: symbol 'ptr' was not declared. Should it be static?
	DECL_POS.c:3:2: warning: symbol 'fptr' was not declared. Should it be static?
	DECL_POS.c:4:2: warning: symbol 'ary' was not declared. Should it be static?
	DECL_POS.c:8:3: error: flexible array member 'mptr1' is not last
	DECL_POS.c:9:3: error: flexible array member 'mptr2' is not last

every reported position is wrong.

This is because the users of declarator() do alloc_symbol(token->pos),
but the current token is not necessarily the ident found later in the
declarator() paths.

With this patch:

	$ ./sparse DECL_POS.c
	DECL_POS.c:2:10: warning: symbol 'ptr' was not declared. Should it be static?
	DECL_POS.c:3:10: warning: symbol 'fptr' was not declared. Should it be static?
	DECL_POS.c:4:10: warning: symbol 'ary' was not declared. Should it be static?
	DECL_POS.c:8:10: error: flexible array member 'mptr1' is not last
	DECL_POS.c:9:10: error: flexible array member 'mptr2' is not last

See also the fixes in validation/{function-redecl,reserved}.c, some
of the old positions in the check-error-start/end blocks were wrong.

TODO: there are more users of users of declarator() which should
probably be updated the same way.

NOTE: unlike external_declaration(), declaration_list() doesn't check
ident != NULL, so ./sparse doesn't complain about "struct { int; };",
this should probably be fixed.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
 parse.c                      |   5 ++
 symbol.h                     |   1 +
 validation/function-redecl.c |  16 ++--
 validation/reserved.c        | 144 +++++++++++++++++------------------
 4 files changed, 86 insertions(+), 80 deletions(-)

diff --git a/parse.c b/parse.c
index 9389079e..1166ab7b 100644
--- a/parse.c
+++ b/parse.c
@@ -1821,6 +1821,8 @@ static struct token *direct_declarator(struct token *token, struct decl_state *c
 
 	if (ctx->ident && token_type(token) == TOKEN_IDENT) {
 		*ctx->ident = token->ident;
+		if (ctx->d_pos)
+			*ctx->d_pos = token->pos;
 		token = token->next;
 	} else if (match_op(token, '(') &&
 	    is_nested(token, &next, ctx->prefer_abstract)) {
@@ -1945,6 +1947,7 @@ static struct token *declaration_list(struct token *token, struct symbol_list **
 		struct symbol *decl = alloc_symbol(token->pos, SYM_NODE);
 		ctx.cleanup = NULL;
 		ctx.ident = &decl->ident;
+		ctx.d_pos = &decl->pos;
 
 		token = declarator(token, &ctx);
 		if (match_op(token, ':'))
@@ -2963,6 +2966,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 	}
 
 	saved = ctx.ctype;
+	ctx.d_pos = &decl->pos;
 	token = declarator(token, &ctx);
 	token = handle_asm_name(token, &ctx);
 	token = handle_attributes(token, &ctx);
@@ -3089,6 +3093,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 		decl = alloc_symbol(token->pos, SYM_NODE);
 		ctx.ctype = saved;
 		ctx.cleanup = NULL;
+		ctx.d_pos = &decl->pos;
 		token = handle_attributes(token, &ctx);
 		token = declarator(token, &ctx);
 		token = handle_asm_name(token, &ctx);
diff --git a/symbol.h b/symbol.h
index 3552d439..52f0977a 100644
--- a/symbol.h
+++ b/symbol.h
@@ -107,6 +107,7 @@ struct ctype {
 struct decl_state {
 	struct ctype ctype;
 	struct ident **ident;
+	struct position *d_pos;
 	struct symbol_op *mode;
 	struct expression *cleanup;
 	unsigned long f_modifiers;		// function attributes
diff --git a/validation/function-redecl.c b/validation/function-redecl.c
index d0d844a5..272d4ac9 100644
--- a/validation/function-redecl.c
+++ b/validation/function-redecl.c
@@ -56,14 +56,14 @@ function-redecl.c:9:11: error: symbol 'ret_const' redeclared with different type
 function-redecl.c:9:11:    int extern const [addressable] [signed] [toplevel] ret_const( ... )
 function-redecl.c:8:5: note: previously declared as:
 function-redecl.c:8:5:    int extern [addressable] [signed] [toplevel] ret_const( ... )
-function-redecl.c:13:13: error: symbol 'ret_as' redeclared with different type (different address spaces):
-function-redecl.c:13:13:    void <asn:1> *extern [addressable] [toplevel] ret_as( ... )
-function-redecl.c:12:6: note: previously declared as:
-function-redecl.c:12:6:    void *extern [addressable] [toplevel] ret_as( ... )
-function-redecl.c:17:12: error: symbol 'ret_mod' redeclared with different type (different modifiers):
-function-redecl.c:17:12:    void const *extern [addressable] [toplevel] ret_mod( ... )
-function-redecl.c:16:6: note: previously declared as:
-function-redecl.c:16:6:    void *extern [addressable] [toplevel] ret_mod( ... )
+function-redecl.c:13:14: error: symbol 'ret_as' redeclared with different type (different address spaces):
+function-redecl.c:13:14:    void <asn:1> *extern [addressable] [toplevel] ret_as( ... )
+function-redecl.c:12:7: note: previously declared as:
+function-redecl.c:12:7:    void *extern [addressable] [toplevel] ret_as( ... )
+function-redecl.c:17:13: error: symbol 'ret_mod' redeclared with different type (different modifiers):
+function-redecl.c:17:13:    void const *extern [addressable] [toplevel] ret_mod( ... )
+function-redecl.c:16:7: note: previously declared as:
+function-redecl.c:16:7:    void *extern [addressable] [toplevel] ret_mod( ... )
 function-redecl.c:21:6: error: symbol 'arg_type' redeclared with different type (incompatible argument 1 (different base types)):
 function-redecl.c:21:6:    void extern [addressable] [toplevel] arg_type( ... )
 function-redecl.c:20:6: note: previously declared as:
diff --git a/validation/reserved.c b/validation/reserved.c
index 6a2163e9..73995c6b 100644
--- a/validation/reserved.c
+++ b/validation/reserved.c
@@ -82,77 +82,77 @@ static int (__builtin_va_list);
 /*
  * check-name: const et.al. are reserved identifiers
  * check-error-start
-reserved.c:1:12: error: Trying to use reserved word 'auto' as identifier
-reserved.c:2:12: error: Trying to use reserved word 'break' as identifier
-reserved.c:3:12: error: Trying to use reserved word 'case' as identifier
-reserved.c:4:12: error: Trying to use reserved word 'char' as identifier
-reserved.c:5:12: error: Trying to use reserved word 'const' as identifier
-reserved.c:6:12: error: Trying to use reserved word '__const' as identifier
-reserved.c:7:12: error: Trying to use reserved word '__const__' as identifier
-reserved.c:8:12: error: Trying to use reserved word 'continue' as identifier
-reserved.c:9:12: error: Trying to use reserved word 'default' as identifier
-reserved.c:10:12: error: Trying to use reserved word 'do' as identifier
-reserved.c:11:12: error: Trying to use reserved word 'double' as identifier
-reserved.c:12:12: error: Trying to use reserved word 'else' as identifier
-reserved.c:13:12: error: Trying to use reserved word 'enum' as identifier
-reserved.c:14:12: error: Trying to use reserved word 'extern' as identifier
-reserved.c:15:12: error: Trying to use reserved word 'float' as identifier
-reserved.c:16:12: error: Trying to use reserved word 'for' as identifier
-reserved.c:17:12: error: Trying to use reserved word 'goto' as identifier
-reserved.c:18:12: error: Trying to use reserved word 'if' as identifier
-reserved.c:19:12: error: Trying to use reserved word 'inline' as identifier
-reserved.c:20:12: error: Trying to use reserved word '__inline' as identifier
-reserved.c:21:12: error: Trying to use reserved word '__inline__' as identifier
-reserved.c:22:12: error: Trying to use reserved word 'int' as identifier
-reserved.c:23:12: error: Trying to use reserved word 'long' as identifier
-reserved.c:24:12: error: Trying to use reserved word 'register' as identifier
-reserved.c:25:12: error: Trying to use reserved word 'restrict' as identifier
-reserved.c:26:12: error: Trying to use reserved word '__restrict' as identifier
-reserved.c:27:12: error: Trying to use reserved word '__restrict__' as identifier
-reserved.c:28:12: error: Trying to use reserved word 'return' as identifier
-reserved.c:29:12: error: Trying to use reserved word 'short' as identifier
-reserved.c:30:12: error: Trying to use reserved word 'signed' as identifier
-reserved.c:31:12: error: Trying to use reserved word 'sizeof' as identifier
-reserved.c:32:12: error: Trying to use reserved word 'static' as identifier
-reserved.c:33:12: error: Trying to use reserved word 'struct' as identifier
-reserved.c:34:12: error: Trying to use reserved word 'switch' as identifier
-reserved.c:35:12: error: Trying to use reserved word 'typedef' as identifier
-reserved.c:36:12: error: Trying to use reserved word 'union' as identifier
-reserved.c:37:12: error: Trying to use reserved word 'unsigned' as identifier
-reserved.c:38:12: error: Trying to use reserved word 'void' as identifier
-reserved.c:39:12: error: Trying to use reserved word 'volatile' as identifier
-reserved.c:40:12: error: Trying to use reserved word 'volatile' as identifier
-reserved.c:41:12: error: Trying to use reserved word '__volatile' as identifier
-reserved.c:42:12: error: Trying to use reserved word '__volatile__' as identifier
-reserved.c:43:12: error: Trying to use reserved word 'while' as identifier
-reserved.c:45:12: error: Trying to use reserved word '_Alignas' as identifier
-reserved.c:46:12: error: Trying to use reserved word '_Alignof' as identifier
-reserved.c:47:12: error: Trying to use reserved word '_Atomic' as identifier
-reserved.c:48:12: error: Trying to use reserved word '_Bool' as identifier
-reserved.c:49:12: error: Trying to use reserved word '_Complex' as identifier
-reserved.c:50:12: error: Trying to use reserved word '_Generic' as identifier
-reserved.c:51:12: error: Trying to use reserved word '_Imaginary' as identifier
-reserved.c:52:12: error: Trying to use reserved word '_Noreturn' as identifier
-reserved.c:53:12: error: Trying to use reserved word '_Static_assert' as identifier
-reserved.c:54:12: error: Trying to use reserved word '_Thread_local' as identifier
-reserved.c:57:12: error: Trying to use reserved word '__context__' as identifier
-reserved.c:58:12: error: Trying to use reserved word '__range__' as identifier
-reserved.c:59:12: error: Trying to use reserved word '__sizeof_ptr__' as identifier
-reserved.c:62:12: error: Trying to use reserved word '__alignof' as identifier
-reserved.c:63:12: error: Trying to use reserved word '__alignof__' as identifier
-reserved.c:65:12: error: Trying to use reserved word '__asm' as identifier
-reserved.c:66:12: error: Trying to use reserved word '__asm__' as identifier
-reserved.c:67:12: error: Trying to use reserved word '__label__' as identifier
-reserved.c:68:12: error: Trying to use reserved word '__thread' as identifier
-reserved.c:69:12: error: Trying to use reserved word 'typeof' as identifier
-reserved.c:70:12: error: Trying to use reserved word '__typeof' as identifier
-reserved.c:71:12: error: Trying to use reserved word '__typeof__' as identifier
-reserved.c:73:12: error: Trying to use reserved word '__int128' as identifier
-reserved.c:74:12: error: Trying to use reserved word '__int128_t' as identifier
-reserved.c:75:12: error: Trying to use reserved word '__uint128_t' as identifier
-reserved.c:77:12: error: Trying to use reserved word '__builtin_ms_va_list' as identifier
-reserved.c:78:12: error: Trying to use reserved word '__builtin_offsetof' as identifier
-reserved.c:79:12: error: Trying to use reserved word '__builtin_types_compatible_p' as identifier
-reserved.c:80:12: error: Trying to use reserved word '__builtin_va_list' as identifier
+reserved.c:1:13: error: Trying to use reserved word 'auto' as identifier
+reserved.c:2:13: error: Trying to use reserved word 'break' as identifier
+reserved.c:3:13: error: Trying to use reserved word 'case' as identifier
+reserved.c:4:13: error: Trying to use reserved word 'char' as identifier
+reserved.c:5:13: error: Trying to use reserved word 'const' as identifier
+reserved.c:6:13: error: Trying to use reserved word '__const' as identifier
+reserved.c:7:13: error: Trying to use reserved word '__const__' as identifier
+reserved.c:8:13: error: Trying to use reserved word 'continue' as identifier
+reserved.c:9:13: error: Trying to use reserved word 'default' as identifier
+reserved.c:10:13: error: Trying to use reserved word 'do' as identifier
+reserved.c:11:13: error: Trying to use reserved word 'double' as identifier
+reserved.c:12:13: error: Trying to use reserved word 'else' as identifier
+reserved.c:13:13: error: Trying to use reserved word 'enum' as identifier
+reserved.c:14:13: error: Trying to use reserved word 'extern' as identifier
+reserved.c:15:13: error: Trying to use reserved word 'float' as identifier
+reserved.c:16:13: error: Trying to use reserved word 'for' as identifier
+reserved.c:17:13: error: Trying to use reserved word 'goto' as identifier
+reserved.c:18:13: error: Trying to use reserved word 'if' as identifier
+reserved.c:19:13: error: Trying to use reserved word 'inline' as identifier
+reserved.c:20:13: error: Trying to use reserved word '__inline' as identifier
+reserved.c:21:13: error: Trying to use reserved word '__inline__' as identifier
+reserved.c:22:13: error: Trying to use reserved word 'int' as identifier
+reserved.c:23:13: error: Trying to use reserved word 'long' as identifier
+reserved.c:24:13: error: Trying to use reserved word 'register' as identifier
+reserved.c:25:13: error: Trying to use reserved word 'restrict' as identifier
+reserved.c:26:13: error: Trying to use reserved word '__restrict' as identifier
+reserved.c:27:13: error: Trying to use reserved word '__restrict__' as identifier
+reserved.c:28:13: error: Trying to use reserved word 'return' as identifier
+reserved.c:29:13: error: Trying to use reserved word 'short' as identifier
+reserved.c:30:13: error: Trying to use reserved word 'signed' as identifier
+reserved.c:31:13: error: Trying to use reserved word 'sizeof' as identifier
+reserved.c:32:13: error: Trying to use reserved word 'static' as identifier
+reserved.c:33:13: error: Trying to use reserved word 'struct' as identifier
+reserved.c:34:13: error: Trying to use reserved word 'switch' as identifier
+reserved.c:35:13: error: Trying to use reserved word 'typedef' as identifier
+reserved.c:36:13: error: Trying to use reserved word 'union' as identifier
+reserved.c:37:13: error: Trying to use reserved word 'unsigned' as identifier
+reserved.c:38:13: error: Trying to use reserved word 'void' as identifier
+reserved.c:39:13: error: Trying to use reserved word 'volatile' as identifier
+reserved.c:40:13: error: Trying to use reserved word 'volatile' as identifier
+reserved.c:41:13: error: Trying to use reserved word '__volatile' as identifier
+reserved.c:42:13: error: Trying to use reserved word '__volatile__' as identifier
+reserved.c:43:13: error: Trying to use reserved word 'while' as identifier
+reserved.c:45:13: error: Trying to use reserved word '_Alignas' as identifier
+reserved.c:46:13: error: Trying to use reserved word '_Alignof' as identifier
+reserved.c:47:13: error: Trying to use reserved word '_Atomic' as identifier
+reserved.c:48:13: error: Trying to use reserved word '_Bool' as identifier
+reserved.c:49:13: error: Trying to use reserved word '_Complex' as identifier
+reserved.c:50:13: error: Trying to use reserved word '_Generic' as identifier
+reserved.c:51:13: error: Trying to use reserved word '_Imaginary' as identifier
+reserved.c:52:13: error: Trying to use reserved word '_Noreturn' as identifier
+reserved.c:53:13: error: Trying to use reserved word '_Static_assert' as identifier
+reserved.c:54:13: error: Trying to use reserved word '_Thread_local' as identifier
+reserved.c:57:13: error: Trying to use reserved word '__context__' as identifier
+reserved.c:58:13: error: Trying to use reserved word '__range__' as identifier
+reserved.c:59:13: error: Trying to use reserved word '__sizeof_ptr__' as identifier
+reserved.c:62:13: error: Trying to use reserved word '__alignof' as identifier
+reserved.c:63:13: error: Trying to use reserved word '__alignof__' as identifier
+reserved.c:65:13: error: Trying to use reserved word '__asm' as identifier
+reserved.c:66:13: error: Trying to use reserved word '__asm__' as identifier
+reserved.c:67:13: error: Trying to use reserved word '__label__' as identifier
+reserved.c:68:13: error: Trying to use reserved word '__thread' as identifier
+reserved.c:69:13: error: Trying to use reserved word 'typeof' as identifier
+reserved.c:70:13: error: Trying to use reserved word '__typeof' as identifier
+reserved.c:71:13: error: Trying to use reserved word '__typeof__' as identifier
+reserved.c:73:13: error: Trying to use reserved word '__int128' as identifier
+reserved.c:74:13: error: Trying to use reserved word '__int128_t' as identifier
+reserved.c:75:13: error: Trying to use reserved word '__uint128_t' as identifier
+reserved.c:77:13: error: Trying to use reserved word '__builtin_ms_va_list' as identifier
+reserved.c:78:13: error: Trying to use reserved word '__builtin_offsetof' as identifier
+reserved.c:79:13: error: Trying to use reserved word '__builtin_types_compatible_p' as identifier
+reserved.c:80:13: error: Trying to use reserved word '__builtin_va_list' as identifier
  * check-error-end
  */
-- 
2.52.0



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2025-12-21 14:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-21 14:28 [PATCH] sparse/parse: update decl->pos when direct_declarator() sees TOKEN_IDENT Oleg Nesterov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).