From: Christopher Li <sparse@chrisli.org>
To: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
Junio C Hamano <gitster@pobox.com>, Andreas Ericsson <ae@op5.se>,
Sparse Mailing-list <linux-sparse@vger.kernel.org>
Subject: Re: Multiple translation unit regression
Date: Fri, 10 Jul 2009 16:27:14 -0700 [thread overview]
Message-ID: <70318cbf0907101627w1b9760a4oc7d13969751e3d00@mail.gmail.com> (raw)
In-Reply-To: <4A57AA66.4080305@ramsay1.demon.co.uk>
[-- Attachment #1: Type: text/plain, Size: 927 bytes --]
On Fri, Jul 10, 2009 at 1:53 PM, Ramsay Jones<ramsay@ramsay1.demon.co.uk> wrote:
> 11 extern int g(int);
> 12
> 13 extern __inline__ int
> 14 g(int x)
> 15 {
> 16 return x;
> 17 }
> 18
Err, that is ugly. I just find out what happen there.
The none inline version picks up the function definition
from the inline version because they are both "extern".
Sparse only has one global extern scope.
Later even the inline version get remove from the
filescope, the second file still conflict with the non-inline
version of the function body, which steal from the inline
version.
I add two lines to distinguish the "extern inline" vs "extern".
They are not the same_symbol any more. Because effectly
the "extern inline" is not visiable in the global "extern" scope.
Any one see problem using this approach?
I attach the patch follows. Can you give it a try?
Chris
[-- Attachment #2: extern-inline-1 --]
[-- Type: application/octet-stream, Size: 2942 bytes --]
move extern inline function to file scope
In gcc extern inline function has special meaning. The inline
function will never emit stand alone copy of the function. It also
allow multiple implementations cross different file. That effectively
makes the extern inline has file scope.
Index: sparse.chrisl/symbol.h
===================================================================
--- sparse.chrisl.orig/symbol.h
+++ sparse.chrisl/symbol.h
@@ -340,6 +340,18 @@ static inline int is_void_type(struct sy
return type == &void_ctype;
}
+static inline int is_function(struct symbol *type)
+{
+ return type && type->type == SYM_FN;
+}
+
+static inline int is_extern_inline(struct symbol *sym)
+{
+ return (sym->ctype.modifiers & MOD_EXTERN) &&
+ (sym->ctype.modifiers & MOD_INLINE) &&
+ is_function(sym->ctype.base_type);
+}
+
static inline int get_sym_type(struct symbol *type)
{
if (type->type == SYM_NODE)
Index: sparse.chrisl/evaluate.c
===================================================================
--- sparse.chrisl.orig/evaluate.c
+++ sparse.chrisl/evaluate.c
@@ -536,11 +536,6 @@ static inline int lvalue_expression(stru
return expr->type == EXPR_PREOP && expr->op == '*';
}
-static inline int is_function(struct symbol *type)
-{
- return type && type->type == SYM_FN;
-}
-
static struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *itype)
{
struct expression *index = expr->right;
Index: sparse.chrisl/symbol.c
===================================================================
--- sparse.chrisl.orig/symbol.c
+++ sparse.chrisl/symbol.c
@@ -522,6 +522,8 @@ void check_declaration(struct symbol *sy
return;
}
if (sym->ctype.modifiers & next->ctype.modifiers & MOD_EXTERN) {
+ if ((sym->ctype.modifiers ^ next->ctype.modifiers) & MOD_INLINE)
+ continue;
sym->same_symbol = next;
return;
}
@@ -558,8 +560,10 @@ void bind_symbol(struct symbol *sym, str
scope = block_scope;
if (ns == NS_SYMBOL && toplevel(scope)) {
unsigned mod = MOD_ADDRESSABLE | MOD_TOPLEVEL;
+
scope = global_scope;
- if (sym->ctype.modifiers & MOD_STATIC) {
+ if (sym->ctype.modifiers & MOD_STATIC ||
+ is_extern_inline(sym)) {
scope = file_scope;
mod = MOD_TOPLEVEL;
}
Index: sparse.chrisl/scope.c
===================================================================
Index: sparse.chrisl/validation/extern-inline.c
===================================================================
--- sparse.chrisl.orig/validation/extern-inline.c
+++ sparse.chrisl/validation/extern-inline.c
@@ -0,0 +1,22 @@
+extern __inline__ int f(int);
+
+extern __inline__ int
+f(int x)
+{
+ return x;
+}
+
+extern int g(int);
+
+extern __inline__ int
+g(int x)
+{
+ return x;
+}
+
+
+/*
+ * check-name: extern inline function
+ * check-description: Extern inline function never emits stand alone copy
+ * of the function. It allows multiple such definitions in different file.
+ */
next prev parent reply other threads:[~2009-07-10 23:27 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-05 23:06 Multiple translation unit regression Ramsay Jones
2009-07-06 9:32 ` Christopher Li
2009-07-07 6:27 ` Christopher Li
2009-07-08 19:32 ` Ramsay Jones
2009-07-08 20:15 ` Christopher Li
2009-07-10 20:53 ` Ramsay Jones
2009-07-10 23:27 ` Christopher Li [this message]
2009-07-13 17:43 ` Ramsay Jones
2009-07-18 20:26 ` Ramsay Jones
2009-07-18 21:53 ` Christopher Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=70318cbf0907101627w1b9760a4oc7d13969751e3d00@mail.gmail.com \
--to=sparse@chrisli.org \
--cc=ae@op5.se \
--cc=gitster@pobox.com \
--cc=linux-sparse@vger.kernel.org \
--cc=ramsay@ramsay1.demon.co.uk \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).