Fix declaration_specifiers() handling of typedef name shadowed by NS_SYMBOL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Doing lookup_symbol() with NS_TYPEDEF will happily skip the redeclarations
of the same identifier with NS_SYMBOL.  We need to check that we are not
dealing with something like
typedef int T;
void f(int T)
{
	static T a; /* not a valid declaration - T is not a typedef name */
or similar (e.g. enum member shadowing a typedef, etc.).

While we are at it, microoptimize similar code in lookup_type() - instead
of sym->namespace == NS_TYPEDEF we can do sym->namespace & NS_TYPEDEF;
the former will turn into "fetch 32bit value, mask all but 9 bits, compare
with NS_TYPEDEF", the latter - "check that one bit in 32bit value is set".
We never mix NS_TYPEDEF with anything in whatever->namespace, so the
tests are equivalent.

Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
---
 expression.h                |    2 +-
 parse.c                     |    5 +++--
 validation/typedef_shadow.c |   12 ++++++++++++
 3 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 validation/typedef_shadow.c

diff --git a/expression.h b/expression.h
index 5136b9b..2e12b12 100644
--- a/expression.h
+++ b/expression.h
@@ -199,7 +199,7 @@ static inline int lookup_type(struct token *token)
 {
 	if (token->pos.type == TOKEN_IDENT) {
 		struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
-		return sym && sym->namespace == NS_TYPEDEF;
+		return sym && (sym->namespace & NS_TYPEDEF);
 	}
 	return 0;
 }
diff --git a/parse.c b/parse.c
index c19822c..00469b2 100644
--- a/parse.c
+++ b/parse.c
@@ -1321,8 +1321,9 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta
 	int size = 0;
 
 	while (token_type(token) == TOKEN_IDENT) {
-		struct symbol *s = lookup_symbol(token->ident, NS_TYPEDEF);
-		if (!s)
+		struct symbol *s = lookup_symbol(token->ident,
+						 NS_TYPEDEF | NS_SYMBOL);
+		if (!s || !(s->namespace & NS_TYPEDEF))
 			break;
 		if (s->type != SYM_KEYWORD) {
 			if (seen & Set_Any)
diff --git a/validation/typedef_shadow.c b/validation/typedef_shadow.c
new file mode 100644
index 0000000..c72cec7
--- /dev/null
+++ b/validation/typedef_shadow.c
@@ -0,0 +1,12 @@
+typedef int T;
+static void f(int T)
+{
+	static T a;
+}
+/*
+ * check-name: typedef shadowing
+ * check-error-start:
+typedef_shadow.c:4:18: error: Expected ; at end of declaration
+typedef_shadow.c:4:18: error: got a
+ * check-error-end:
+ */
-- 
1.5.6.5


--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux