diff mbox

Designated initializers for fields in anonymous structs and unions

Message ID CANeU7QnTx50Hrw3-8vqAc=3e59v7ppnjgS6GVGMwbhOMZvbH9A@mail.gmail.com (mailing list archive)
State Mainlined, archived
Headers show

Commit Message

Christopher Li Aug. 2, 2014, 6:09 p.m. UTC
On Sat, Aug 2, 2014 at 1:27 AM, Christopher Li <sparse@chrisli.org> wrote:
> I just apply that without the "FIXME" part. That two lines are from an incorrect
> fix for the external inline bug. I just remove it for now. Currently
> sparse will fail
> at the external inline test. I will fix that in a separate patch.

This is a follow up change to fix the extern-inline.c validation bug.
Feed back are welcome.

Consider the following case, extern inline declare after
extern declare of the same function.

extern int g(int);
extern __inline__ int g(int x)
{
        return x;
}

Sparse will give the first function global scope and
the second one file scope. Also the first one will get the
function body from the second one. That cause the failure
of the validation/extern-inlien.c

This change rebind the scope of the same_symbol chain to
the new scope. It will pass the extern-inline.c test case.

Chris
diff mbox

Patch

From 7abd8a76b4e07ad60b5262e4c7858e638467fab8 Mon Sep 17 00:00:00 2001
From: Christopher Li <sparse@chrisli.org>
Date: Sat, 2 Aug 2014 10:56:59 -0700
Subject: [PATCH] Make same_symbol list share the same scope

Consider the following case, extern inline declare after
extern declare of the same function.

extern int g(int);
extern __inline__ int g(int x)
{
        return x;
}

Sparse will give the first function global scope and
the second one file scope. Also the first one will get the
function body from the second one. That cause the failure
of the validation/extern-inlien.c

This change rebind the scope of the same_symbol chain to
the new scope. It will pass the extern-inline.c test case.

Signed-off-by: Christopher Li <sparse@chrisli.org>
---
 parse.c |  1 +
 scope.c | 14 ++++++++++++++
 scope.h |  1 +
 3 files changed, 16 insertions(+)

diff --git a/parse.c b/parse.c
index 55a57a7..eaa1883 100644
--- a/parse.c
+++ b/parse.c
@@ -2611,6 +2611,7 @@  static struct token *parse_function_body(struct token *token, struct symbol *dec
 		info(prev->definition->pos, " the previous one is here");
 	} else {
 		while (prev) {
+			rebind_scope(prev, decl->scope);
 			prev->definition = decl;
 			prev = prev->same_symbol;
 		}
diff --git a/scope.c b/scope.c
index b415ace..cbf2fcf 100644
--- a/scope.c
+++ b/scope.c
@@ -46,6 +46,20 @@  void bind_scope(struct symbol *sym, struct scope *scope)
 	add_symbol(&scope->symbols, sym);
 }
 
+
+void rebind_scope(struct symbol *sym, struct scope *new)
+{
+	struct scope *old = sym->scope;
+
+	if (old == new)
+		return;
+
+	if (old)
+		delete_ptr_list_entry((struct ptr_list**) &old->symbols, sym, 1);
+
+	bind_scope(sym, new);
+}
+
 static void start_scope(struct scope **s)
 {
 	struct scope *scope = __alloc_scope(0);
diff --git a/scope.h b/scope.h
index 045c356..9bbb675 100644
--- a/scope.h
+++ b/scope.h
@@ -55,6 +55,7 @@  extern void start_function_scope(void);
 extern void end_function_scope(void);
 
 extern void bind_scope(struct symbol *, struct scope *);
+extern void rebind_scope(struct symbol *, struct scope *);
 
 extern int is_outer_scope(struct scope *);
 #endif
-- 
1.9.3