aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2009-03-09 23:32:26 +0000
committerChristopher Li <sparse@chrisli.org>2009-07-18 05:30:09 +0000
commit2be16aeb8ccd4b05819a3036962010af0c5745d1 (patch)
tree9e0c48f920bc97773bead30e18e70e6485a3f9cb
parentc14911db43a7229ba7a28ac23f4d1e569a2586ab (diff)
downloadsparse-2be16aeb8ccd4b05819a3036962010af0c5745d1.tar.gz
Fix declaration_specifiers() handling of typedef name shadowed by NS_SYMBOL
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@zeniv.linux.org.uk> Signed-off-by: Christopher Li <sparse@chrisli.org>
-rw-r--r--expression.h2
-rw-r--r--parse.c5
-rw-r--r--validation/typedef_shadow.c12
3 files changed, 16 insertions, 3 deletions
diff --git a/expression.h b/expression.h
index 5136b9b4..2e12b12c 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 9fb606ab..8e18d546 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 00000000..c72cec72
--- /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:
+ */