Message ID | 4A5131F4.7070007@ramsay1.demon.co.uk (mailing list archive) |
---|---|
State | Rejected, archived |
Headers | show |
On Sun, Jul 5, 2009 at 4:06 PM, Ramsay Jones<ramsay@ramsay1.demon.co.uk> wrote: > > pre-process.c:609 in function expand(): > Â Â Â Â struct arg args[nargs]; That is a known limit of sparse. It does not handle dynamic sized array. In kernel that is not a good thing because kernel stack is very limited. > sparse: > Â Â Â Â cgcc -no-compile $(ALL_CFLAGS) $(SPARSE_FLAGS) $(SRC_C) I think libgit2 should make sparse to compile the file one by one. Do them all at once might overflow your memory. > > this results in the follwing warnings (on cygwin): > > .../byteorder.h:39:1: warning: multiple definitions for function '__ntohl' > .../byteorder.h:39:1: Â the previous one is here > .../byteorder.h:56:1: warning: multiple definitions for function '__ntohs' > .../byteorder.h:56:1: Â the previous one is here GNU C has special treatment for "extern inline". It does not generate the stand alone copy of the function. Sparse does not handle that very well yet. I think the easiest way to fix is just run those source file in sparse one by one. > > The third hunk of the diff to parse.c actually triggers the problem, > but is not the real cause of the regression. I think that is the right thing to do. The problem is that sparse currently does not have way to mark a function as inline only without the standalone copy. > > I think the problem is mainly caused by bind_symbol() binding the > global_scope to some symbols. Indeed, the global_scope/file_scope > seems to be a bit confused and confusing. Note that the global_scope Global scope is for store global visible symbols. File scopes is use for file local symbols like static functions. > is not changed at all once intialised. In particular, each translation > unit keeps adding to the, one and only, global_scope; which is > effectively the same as the builtin_scope! What is wrong with only one global scope? Chris > Hmm, the following diff shows a quick fix: > > --->8--- > diff --git a/scope.c b/scope.c > index 27e38bc..fb4c039 100644 > --- a/scope.c > +++ b/scope.c > @@ -49,6 +49,7 @@ void start_file_scope(void) > Â Â Â Â /* top-level stuff defaults to file scope, "extern" etc will choose global scope */ > Â Â Â Â function_scope = scope; > Â Â Â Â block_scope = scope; > + Â Â Â start_scope(&global_scope); > Â } > > Â void start_symbol_scope(void) > @@ -87,6 +88,7 @@ static void end_scope(struct scope **s) > Â void end_file_scope(void) > Â { > Â Â Â Â end_scope(&file_scope); > + Â Â Â end_scope(&global_scope); > Â } > > Â void new_file_scope(void) > --->8--- > > But this is not the correct fix. In fact it may have broken c2xml > and ctags. I haven't checked, but look at the main() code in c2xml.c > and ctags.c; again the semantics of global_scope vs. file_scope > seems confused and confusing. At least to me. ;-) As you said, that is not the right fix. Ctags needs to use global scope to look for symbol has been define but does not used in the file. Chris -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Can you try the following patch? I move the extern inline function to file scope. Again, I still think it would be better let sparse check one file at a time. Chris
Christopher Li wrote: > Can you try the following patch? I move the extern inline function > to file scope. Again, I still think it would be better let sparse > check one file at a time. > This solves the problem on cygwin. I almost didn't test it on Linux, since it looked like this should work just fine... Unfortunately, the problem persists on Linux and I don't have time tonight to try and debug it; I will look into it further, hopefully tomorrow evening. ATB, Ramsay Jones -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Jul 8, 2009 at 12:32 PM, Ramsay Jones<ramsay@ramsay1.demon.co.uk> wrote: > Unfortunately, the problem persists on Linux and I don't have time > tonight to try and debug it; I will look into it further, hopefully > tomorrow evening. If you can give me a small test case on Linux that will be great. I can pick it up from there. Chris -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Christopher Li wrote: > On Wed, Jul 8, 2009 at 12:32 PM, Ramsay Jones<ramsay@ramsay1.demon.co.uk> wrote: >> Unfortunately, the problem persists on Linux and I don't have time >> tonight to try and debug it; I will look into it further, hopefully >> tomorrow evening. > > If you can give me a small test case on Linux that will be great. > I can pick it up from there. > [sorry for the late reply; something came up!] I forgot to mention that, on Linux, enabling optimization is required to trip this, since the extern inline function definitions are #ifdef'ed out otherwise. That does not affect the following test case, however. I've added to the previous test.c file (Note that the declaration of g() does not include __inline__): $ cat -n test.c 1 2 extern __inline__ int f(int); 3 4 extern __inline__ int 5 f(int x) 6 { 7 return x; 8 } 9 10 11 extern int g(int); 12 13 extern __inline__ int 14 g(int x) 15 { 16 return x; 17 } 18 $ ./sparse test.c $ ./sparse test.c test.c test.c:14:1: warning: multiple definitions for function 'g' test.c:14:1: the previous one is here $ cp test.c test-again.c $ ./sparse test.c test-again.c test-again.c:14:1: warning: multiple definitions for function 'g' test.c:14:1: the previous one is here $ Actually, the following may be closer to the situation on Linux: $ cat -n test.c 1 2 extern __inline__ int f(int); 3 4 extern __inline__ int 5 f(int x) 6 { 7 return x; 8 } 9 10 11 extern int g(int); 12 13 #ifdef __OPTIMIZE__ 14 extern __inline__ int 15 g(int x) 16 { 17 return x; 18 } 19 #endif 20 $ ./sparse test.c test.c $ ./sparse -O2 test.c test.c test.c:15:1: warning: multiple definitions for function 'g' test.c:15:1: the previous one is here HTH ATB Ramsay Jones 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; }
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
Christopher Li wrote: > I attach the patch follows. Can you give it a try? > Yep, this works. Tested on cygwin and Linux. Thanks! ATB, Ramsay Jones -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/scope.c b/scope.c index 27e38bc..fb4c039 100644 --- a/scope.c +++ b/scope.c @@ -49,6 +49,7 @@ void start_file_scope(void) /* top-level stuff defaults to file scope, "extern" etc will choose global scope */ function_scope = scope; block_scope = scope; + start_scope(&global_scope); } void start_symbol_scope(void) @@ -87,6 +88,7 @@ static void end_scope(struct scope **s) void end_file_scope(void) { end_scope(&file_scope); + end_scope(&global_scope); } void new_file_scope(void)