aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorAl Viro <viro@zeniv.linux.org.uk>2007-07-27 10:19:50 -0400
committerJosh Triplett <josh@freedesktop.org>2007-07-29 00:44:25 -0700
commitc716828bf2ba59af73f4eb058e6f131b1fb7d498 (patch)
treef6f1ddc8db72d1cbf326b530484a3e7a34cc8c04
parent321ad07c0d299690e4a7b9e9386e1acf844f8404 (diff)
downloadsparse-dev-c716828bf2ba59af73f4eb058e6f131b1fb7d498.tar.gz
[PATCH] file and global scopes are the same for purposes of struct redefining
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--parse.c2
-rw-r--r--scope.c10
-rw-r--r--scope.h1
-rw-r--r--validation/outer-scope.c19
4 files changed, 31 insertions, 1 deletions
diff --git a/parse.c b/parse.c
index dfb922f0..f4520428 100644
--- a/parse.c
+++ b/parse.c
@@ -481,7 +481,7 @@ static struct token *struct_union_enum_specifier(enum type type,
if (token_type(token) == TOKEN_IDENT) {
sym = lookup_symbol(token->ident, NS_STRUCT);
if (!sym ||
- (sym->scope != block_scope &&
+ (is_outer_scope(sym->scope) &&
(match_op(token->next,';') || match_op(token->next,'{')))) {
// Either a new symbol, or else an out-of-scope
// symbol being redefined.
diff --git a/scope.c b/scope.c
index 1f14feb3..f09c8e95 100644
--- a/scope.c
+++ b/scope.c
@@ -106,3 +106,13 @@ void end_function_scope(void)
end_scope(&block_scope);
end_scope(&function_scope);
}
+
+int is_outer_scope(struct scope *scope)
+{
+ if (scope == block_scope)
+ return 0;
+ if (scope == &builtin_scope && block_scope->next == &builtin_scope)
+ return 0;
+ return 1;
+}
+
diff --git a/scope.h b/scope.h
index ce430c8e..5f1f2324 100644
--- a/scope.h
+++ b/scope.h
@@ -38,4 +38,5 @@ extern void end_function_scope(void);
extern void bind_scope(struct symbol *, struct scope *);
+extern int is_outer_scope(struct scope *);
#endif
diff --git a/validation/outer-scope.c b/validation/outer-scope.c
new file mode 100644
index 00000000..2ce05051
--- /dev/null
+++ b/validation/outer-scope.c
@@ -0,0 +1,19 @@
+#ifndef FOO
+struct st { int len; };
+#define FOO
+#else
+struct st;
+static int test(struct st *s);
+static int test(struct st *s)
+{
+ return s->len;
+}
+#endif
+/*
+ * check-name: There is no scope boundary between global and file scope
+ * check-description: Used to mess scopes with -include
+ * check-command: sparse -include $file $file
+ *
+ * check-output-start
+ * check-output-end
+ */