Message ID | 20220624164601.99527-1-lucvoo@kernel.org (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
Series | fix "unreplaced" warnings caused by using typeof() on inline functions | expand |
On Fri, Jun 24, 2022 at 06:46:01PM +0200, Luc Van Oostenryck wrote: > From: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> > > Currently, sparse do all its inlining at the tree level, during > constant expansion. To not mix-up the evaluation of the original > function body in case the address of an inline function is taken or > when the function can't otherwise be inlined, the statements and > symbols lists of inline functions are kept in separated fields. > Then, if the original body must be evaluated it must first be > 'uninlined' to have a copy in the usual fields. > > This make sense when dealing with the definition of the function. > But, when using typeof() on functions, the resulting type doesn't > refer to this definition, it's just a copy of the type and only > of the type. There shouldn't be any reasons to uninline anything. > However, the distinction between 'full function' and 'type only' > is not made during evaluation and the uninlining attempt produce > a lot of "warning: unreplaced symbol '...'" because of the lack > of a corresponding definition. > > Fix this by not doing the uninlining if the symbol lack a definition. > > Note: It would maybe be more appropriate for EXPR_TYPE to use > a stripped-own version of evaluate_symbol() doing only the > examination of the return and argument types, bypassing the > attempt to uninline the body and evaluate the initializer and > the statements since there is none of those for an EXPR_TYPE. Uwe, can we get a Debian package with this fix, it's really a tons of such messages when compile kernel with C=1?
On 7/1/22 14:10, Andy Shevchenko wrote: > On Fri, Jun 24, 2022 at 06:46:01PM +0200, Luc Van Oostenryck wrote: >> From: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> >> >> Currently, sparse do all its inlining at the tree level, during >> constant expansion. To not mix-up the evaluation of the original >> function body in case the address of an inline function is taken or >> when the function can't otherwise be inlined, the statements and >> symbols lists of inline functions are kept in separated fields. >> Then, if the original body must be evaluated it must first be >> 'uninlined' to have a copy in the usual fields. >> >> This make sense when dealing with the definition of the function. >> But, when using typeof() on functions, the resulting type doesn't >> refer to this definition, it's just a copy of the type and only >> of the type. There shouldn't be any reasons to uninline anything. >> However, the distinction between 'full function' and 'type only' >> is not made during evaluation and the uninlining attempt produce >> a lot of "warning: unreplaced symbol '...'" because of the lack >> of a corresponding definition. >> >> Fix this by not doing the uninlining if the symbol lack a definition. >> >> Note: It would maybe be more appropriate for EXPR_TYPE to use >> a stripped-own version of evaluate_symbol() doing only the >> examination of the return and argument types, bypassing the >> attempt to uninline the body and evaluate the initializer and >> the statements since there is none of those for an EXPR_TYPE. > > Uwe, can we get a Debian package with this fix, it's really a tons of such > messages when compile kernel with C=1? Luc, do you consider it sensible to create a 0.6.4 variant of sparse that includes this fix? Are there any more patches that you'd deem sensible to inlucde? Does that mean it's time for a 0.6.5 release? Best regards Uwe
On Fri, Jul 01, 2022 at 03:10:36PM +0300, Andy Shevchenko wrote: > On Fri, Jun 24, 2022 at 06:46:01PM +0200, Luc Van Oostenryck wrote: > > From: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> > > > > Currently, sparse do all its inlining at the tree level, during > > constant expansion. To not mix-up the evaluation of the original > > function body in case the address of an inline function is taken or > > when the function can't otherwise be inlined, the statements and > > symbols lists of inline functions are kept in separated fields. > > Then, if the original body must be evaluated it must first be > > 'uninlined' to have a copy in the usual fields. > > > > This make sense when dealing with the definition of the function. > > But, when using typeof() on functions, the resulting type doesn't > > refer to this definition, it's just a copy of the type and only > > of the type. There shouldn't be any reasons to uninline anything. > > However, the distinction between 'full function' and 'type only' > > is not made during evaluation and the uninlining attempt produce > > a lot of "warning: unreplaced symbol '...'" because of the lack > > of a corresponding definition. > > > > Fix this by not doing the uninlining if the symbol lack a definition. > > > > Note: It would maybe be more appropriate for EXPR_TYPE to use > > a stripped-own version of evaluate_symbol() doing only the > > examination of the return and argument types, bypassing the > > attempt to uninline the body and evaluate the initializer and > > the statements since there is none of those for an EXPR_TYPE. > > Uwe, can we get a Debian package with this fix, it's really a tons of such > messages when compile kernel with C=1? As of today it seems Debian still has old sparse version...
diff --git a/evaluate.c b/evaluate.c index 61f59ee3908e..fe716f631987 100644 --- a/evaluate.c +++ b/evaluate.c @@ -3555,7 +3555,7 @@ static struct symbol *evaluate_symbol(struct symbol *sym) current_fn = sym; examine_fn_arguments(base_type); - if (!base_type->stmt && base_type->inline_stmt) + if (!base_type->stmt && base_type->inline_stmt && sym->definition) uninline(sym); if (base_type->stmt) evaluate_statement(base_type->stmt); diff --git a/validation/inline-early/unreplaced-abstract.c b/validation/inline-early/unreplaced-abstract.c new file mode 100644 index 000000000000..e38cd6681f14 --- /dev/null +++ b/validation/inline-early/unreplaced-abstract.c @@ -0,0 +1,28 @@ +static inline void f0(void) { } +static inline long f1(long a) { return a + 1;} + +_Static_assert([typeof(f0)] != [typeof(f1)]); + + +static inline void g0(void) { } +static inline long g1(long a) { return a + 1;} + +extern long goo(long a); +long goo(long a) +{ + g0(); + return g1(a); +} + +_Static_assert([typeof(g0)] != [typeof(g1)]); + +extern long moo(long a); +long moo(long a) +{ + typeof(f1) *f = g1; + return f(a); +} + +/* + * check-name: unreplaced-abstract + */ diff --git a/validation/optim/devirtualize0.c b/validation/optim/devirtualize0.c new file mode 100644 index 000000000000..7079e79072fe --- /dev/null +++ b/validation/optim/devirtualize0.c @@ -0,0 +1,17 @@ +static inline long f1(long x) { return x + 1;} + +extern long foo(long a); +long foo(long a) +{ + typeof(f1) *f = f1; + return f(a); +} + +/* + * check-name: devirtualize0 + * check-command: test-linearize -Wno-decl $file + * check-known-to-fail + * + * check-output-ignore + * check-output-excludes: call\\. + */