[PATCH 07/21] make expand_has_...() responsible for expanding its argument
Al Viro <[email protected]> Mon, 16 Mar 2026 07:04:01 +0000
| Newsgroups | org.kernel.vger.linux-sparse |
|---|---|
| Message-ID | <[email protected]> |
If we want to make expansion of arguments on-demand, we need to adjust ->expand() calling conventions first, passing it unexpanded arguments. Switch create_arglist() to setting argcounts from normal=1 to quoted=1, provide a helper (first_arg()) that does actual expansion and make ->expand() instances use it. After that these fake arglists are used only for two things: they indicate that these macros are function-like and they short-circuit expand_arguments(). Once we switch to on-demand argument expansion, the second role will disappear and we can just use &eof_token_entry as ->arglist for those. Signed-off-by: Al Viro <[email protected]> --- pre-process.c | 17 ++++++++++++----- validation/preprocessor/has-attribute.c | 3 +++ validation/preprocessor/has-builtin.c | 3 +++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/pre-process.c b/pre-process.c index 17ed7f85..85662365 100644 --- a/pre-process.c +++ b/pre-process.c @@ -2000,9 +2000,16 @@ static int handle_nondirective(struct stream *stream, struct token **line, struc return 1; } +static struct token *first_arg(struct arg *args) +{ + struct token *arg = args[0].arg; + expand_list(&arg); + return arg; +} + static bool expand_has_attribute(struct token *token, struct arg *args) { - struct token *arg = args[0].expanded; + struct token *arg = first_arg(args); struct symbol *sym; if (token_type(arg) != TOKEN_IDENT) { @@ -2017,7 +2024,7 @@ static bool expand_has_attribute(struct token *token, struct arg *args) static bool expand_has_builtin(struct token *token, struct arg *args) { - struct token *arg = args[0].expanded; + struct token *arg = first_arg(args); struct symbol *sym; if (token_type(arg) != TOKEN_IDENT) { @@ -2032,7 +2039,7 @@ static bool expand_has_builtin(struct token *token, struct arg *args) static bool expand_has_extension(struct token *token, struct arg *args) { - struct token *arg = args[0].expanded; + struct token *arg = first_arg(args); struct ident *ident; bool val = false; @@ -2057,7 +2064,7 @@ static bool expand_has_extension(struct token *token, struct arg *args) static bool expand_has_feature(struct token *token, struct arg *args) { - struct token *arg = args[0].expanded; + struct token *arg = first_arg(args); struct ident *ident; bool val = false; @@ -2103,7 +2110,7 @@ static void create_arglist(struct symbol *sym, int count) token_type(id) = TOKEN_IDENT; uses = __alloc_token(0); token_type(uses) = TOKEN_ARG_COUNT; - uses->count.normal = 1; + uses->count.quoted = 1; *next = id; id->next = uses; diff --git a/validation/preprocessor/has-attribute.c b/validation/preprocessor/has-attribute.c index 3149cbfa..dd0f275e 100644 --- a/validation/preprocessor/has-attribute.c +++ b/validation/preprocessor/has-attribute.c @@ -6,6 +6,8 @@ __has_attribute()??? Quesako? #endif 123 __has_attribute(nothinx) def +#define A packed +456 __has_attribute(A) #if __has_attribute(nothinx) #error "not a attribute!" @@ -49,6 +51,7 @@ __has_attribute()??? Quesako? "has __has_attribute(), yeah!" 123 0 def +456 1 "ok gcc" "ok gcc ignore" "ok sparse specific" diff --git a/validation/preprocessor/has-builtin.c b/validation/preprocessor/has-builtin.c index 03272fc9..010d44bd 100644 --- a/validation/preprocessor/has-builtin.c +++ b/validation/preprocessor/has-builtin.c @@ -28,6 +28,8 @@ constant_p #endif 123 __has_builtin(abc) def +#define A __builtin_constant_p +456 __has_builtin(A) /* * check-name: has-builtin @@ -39,5 +41,6 @@ constant_p abs constant_p 123 0 def +456 1 * check-output-end */ -- 2.47.3