[PATCH 2/4] sparse/dissect: report the usage of enumerators

Oleg Nesterov <[email protected]> Sun, 4 Jan 2026 16:22:00 +0100
Newsgroups org.kernel.vger.linux-sparse
Message-ID <[email protected]>
Test-case:

	$ cat ENUM_2.c
	enum X { A, B };
	typeof(A) x = B;

	$ ./test-dissect ENUM_2.c

	   2:11                   def   v x                                int
	   2:11                   -w-   v x                                int

With this patch:

	$ ./test-dissect ENUM_2.c

	   1:6                    def   E X                                unsigned int
	   1:10                   def   e X.A                              unsigned int enum X
	   1:13                   def   e X.B                              unsigned int enum X
	   2:8                    ---   e X.A                              unsigned int enum X
	   2:11                   def   v x                                int
	   2:11                   -w-   v x                                int
	   2:15  x                -r-   e X.B                              unsigned int enum X

Signed-off-by: Oleg Nesterov <[email protected]>
---
 dissect.c    | 6 +++++-
 expression.c | 3 +++
 expression.h | 1 +
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/dissect.c b/dissect.c
index abca1805..d36986dd 100644
--- a/dissect.c
+++ b/dissect.c
@@ -345,9 +345,13 @@ again:
 		warning(expr->pos, "bad expr->type: %d", expr->type);
 
 	case EXPR_TYPE:		// [struct T]; Why ???
-	case EXPR_VALUE:
 	case EXPR_FVALUE:
 
+	break; case EXPR_VALUE:
+		if (expr->flags & CEF_ENUM)
+			report_member(mode, &expr->pos,
+				base_type(expr->enum_node), expr->enum_node);
+
 	break; case EXPR_LABEL:
 		ret = &label_ctype;
 
diff --git a/expression.c b/expression.c
index b23107da..573358e3 100644
--- a/expression.c
+++ b/expression.c
@@ -479,6 +479,9 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 			/* we want the right position reported, thus the copy */
 			expr->pos = token->pos;
 			expr->flags = CEF_SET_ENUM;
+			// enum { X = bad } results in EXPR_SYMBOL
+			if (expr->type == EXPR_VALUE)
+				expr->enum_node = sym;
 			token = next;
 			break;
 		}
diff --git a/expression.h b/expression.h
index ce8a29ce..b7abff15 100644
--- a/expression.h
+++ b/expression.h
@@ -167,6 +167,7 @@ struct expression {
 		// EXPR_VALUE
 		struct {
 			unsigned long long value;
+			struct symbol *enum_node;
 			unsigned taint;
 		};
 
-- 
2.52.0