* noreturn attribute doesn't work in smatch
@ 2019-08-15 0:53 John Levon
2019-08-15 11:12 ` John Levon
0 siblings, 1 reply; 6+ messages in thread
From: John Levon @ 2019-08-15 0:53 UTC (permalink / raw)
To: smatch, linux-sparse; +Cc: yuri.pankov
./smatch: a.c:20 main() error: double free of 'str'
given:
```
#include <stdlib.h>
#include <string.h>
__attribute__((__noreturn__)) void
die(void)
{
exit(1);
}
int
main(void)
{
char *str = strdup("test");
if (str != NULL) {
free(str);
die();
}
free(str);
return (0);
}
```
As far as I can figure out, this looks like a sparse problem: an
'inline' or 'extern' specifier in this position gets marked as the
relevant MOD_* flag for the function, but the noreturn doesn't bubble
up in the same way. Some quick lame attempts to add ctx->is_noreturn did
not go well.
I think this might be the underlying issue behind sparse's failing test
validation/function-redecl2.c but I'm not positive.
We can do:
```
#ifdef __CHECKER__
#define SMATCH_NORETURN __attribute__((__noreturn__))
#else
#define SMATCH_NORETURN /* would break gcc otherwise */
#endif
__attribute__((__noreturn__)) void
die(void) SMATCH_NORETURN
{
```
but it's ... unlovely.
Any thoughts?
thanks
john
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: noreturn attribute doesn't work in smatch
2019-08-15 0:53 noreturn attribute doesn't work in smatch John Levon
@ 2019-08-15 11:12 ` John Levon
2019-08-22 13:30 ` Dan Carpenter
0 siblings, 1 reply; 6+ messages in thread
From: John Levon @ 2019-08-15 11:12 UTC (permalink / raw)
To: smatch, linux-sparse; +Cc: yuri.pankov
I took another pass, and this works for me:
diff --git a/parse.c b/parse.c
index ca4726b8..44c59707 100644
--- a/parse.c
+++ b/parse.c
@@ -2859,6 +2859,7 @@ struct token *external_declaration(struct token
*token, struct symbol_list **lis
/* Parse declaration-specifiers, if any */
token = declaration_specifiers(token, &ctx);
mod = storage_modifiers(&ctx);
+ mod |= ctx.ctype.modifiers & MOD_NORETURN;
decl = alloc_symbol(token->pos, SYM_NODE);
/* Just a type declaration? */
if (match_op(token, ';')) {
(I suppose a proper fix would collate all function-level attributes
but...)
However, it seems like smatch is still not quite passing its knowledge
along: if I have:
extern void die() __attribute((__noreturn__));
void mydie()
{
die();
}
then the die() call is nullified, but smatch doesn't realise that means
all paths of mydie() are __noreturn__ too.
regards
john
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: noreturn attribute doesn't work in smatch
2019-08-15 11:12 ` John Levon
@ 2019-08-22 13:30 ` Dan Carpenter
2019-08-22 13:46 ` John Levon
0 siblings, 1 reply; 6+ messages in thread
From: Dan Carpenter @ 2019-08-22 13:30 UTC (permalink / raw)
To: John Levon; +Cc: smatch, linux-sparse, yuri.pankov
On Thu, Aug 15, 2019 at 12:12:37PM +0100, John Levon wrote:
>
> I took another pass, and this works for me:
>
> diff --git a/parse.c b/parse.c
> index ca4726b8..44c59707 100644
> --- a/parse.c
> +++ b/parse.c
> @@ -2859,6 +2859,7 @@ struct token *external_declaration(struct token
> *token, struct symbol_list **lis
> /* Parse declaration-specifiers, if any */
> token = declaration_specifiers(token, &ctx);
> mod = storage_modifiers(&ctx);
> + mod |= ctx.ctype.modifiers & MOD_NORETURN;
> decl = alloc_symbol(token->pos, SYM_NODE);
> /* Just a type declaration? */
> if (match_op(token, ';')) {
>
> (I suppose a proper fix would collate all function-level attributes
> but...)
>
This patch seems like a hack, but I will apply it...
>
> However, it seems like smatch is still not quite passing its knowledge
> along: if I have:
>
> extern void die() __attribute((__noreturn__));
>
> void mydie()
> {
> die();
> }
>
> then the die() call is nullified, but smatch doesn't realise that means
> all paths of mydie() are __noreturn__ too.
The code to handle that is really ancient. You need to do:
./smatch --info test.c | tee warns.txt
grep no_return_funcs warns.txt || echo FAIL
./smatch_scripts/gen_no_return_funcs.sh warns.txt -p=levon
mv levon.no_return_funcs smatch_data/
Then pass -p=levon to smatch on the next run.
regards,
dan carpenter
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: noreturn attribute doesn't work in smatch
2019-08-22 13:30 ` Dan Carpenter
@ 2019-08-22 13:46 ` John Levon
2019-08-22 15:05 ` Dan Carpenter
0 siblings, 1 reply; 6+ messages in thread
From: John Levon @ 2019-08-22 13:46 UTC (permalink / raw)
To: Dan Carpenter; +Cc: smatch, linux-sparse, yuri.pankov
On Thu, Aug 22, 2019 at 04:30:34PM +0300, Dan Carpenter wrote:
> On Thu, Aug 15, 2019 at 12:12:37PM +0100, John Levon wrote:
> >
> > I took another pass, and this works for me:
> >
> > diff --git a/parse.c b/parse.c
> > index ca4726b8..44c59707 100644
> > --- a/parse.c
> > +++ b/parse.c
> > @@ -2859,6 +2859,7 @@ struct token *external_declaration(struct token
> > *token, struct symbol_list **lis
> > /* Parse declaration-specifiers, if any */
> > token = declaration_specifiers(token, &ctx);
> > mod = storage_modifiers(&ctx);
> > + mod |= ctx.ctype.modifiers & MOD_NORETURN;
> > decl = alloc_symbol(token->pos, SYM_NODE);
> > /* Just a type declaration? */
> > if (match_op(token, ';')) {
> >
> > (I suppose a proper fix would collate all function-level attributes
> > but...)
>
> This patch seems like a hack, but I will apply it...
I agree, it would be nice to see this cleaned up properly, but as the
above is sufficient for us, it'll do for us! Thanks!
> > However, it seems like smatch is still not quite passing its knowledge
> > along: if I have:
> >
> > extern void die() __attribute((__noreturn__));
> >
> > void mydie()
> > {
> > die();
> > }
> >
> > then the die() call is nullified, but smatch doesn't realise that means
> > all paths of mydie() are __noreturn__ too.
>
> The code to handle that is really ancient. You need to do:
> ./smatch --info test.c | tee warns.txt
> grep no_return_funcs warns.txt || echo FAIL
> ./smatch_scripts/gen_no_return_funcs.sh warns.txt -p=levon
> mv levon.no_return_funcs smatch_data/
>
> Then pass -p=levon to smatch on the next run.
OK, thanks. That doesn't match too well with the way we use smatch, but
this is much less of a big deal (I only needed to annotate this in a
couple of places).
regards
john
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: noreturn attribute doesn't work in smatch
2019-08-22 13:46 ` John Levon
@ 2019-08-22 15:05 ` Dan Carpenter
2019-08-22 15:29 ` John Levon
0 siblings, 1 reply; 6+ messages in thread
From: Dan Carpenter @ 2019-08-22 15:05 UTC (permalink / raw)
To: John Levon; +Cc: smatch, linux-sparse, yuri.pankov
On Thu, Aug 22, 2019 at 02:46:03PM +0100, John Levon wrote:
> On Thu, Aug 22, 2019 at 04:30:34PM +0300, Dan Carpenter wrote:
> > The code to handle that is really ancient. You need to do:
> > ./smatch --info test.c | tee warns.txt
> > grep no_return_funcs warns.txt || echo FAIL
> > ./smatch_scripts/gen_no_return_funcs.sh warns.txt -p=levon
> > mv levon.no_return_funcs smatch_data/
> >
> > Then pass -p=levon to smatch on the next run.
>
> OK, thanks. That doesn't match too well with the way we use smatch, but
> this is much less of a big deal (I only needed to annotate this in a
> couple of places).
It should be the the DB, right? Would that work for you?
It's sort of an awkward thing because I publish the list of no return
functions used in the kernel, but I don't publish the DB. So I probably
have to keep both methods...
regards,
dan carpenter
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: noreturn attribute doesn't work in smatch
2019-08-22 15:05 ` Dan Carpenter
@ 2019-08-22 15:29 ` John Levon
0 siblings, 0 replies; 6+ messages in thread
From: John Levon @ 2019-08-22 15:29 UTC (permalink / raw)
To: Dan Carpenter; +Cc: smatch, linux-sparse, yuri.pankov
On Thu, Aug 22, 2019 at 06:05:29PM +0300, Dan Carpenter wrote:
> On Thu, Aug 22, 2019 at 02:46:03PM +0100, John Levon wrote:
> > On Thu, Aug 22, 2019 at 04:30:34PM +0300, Dan Carpenter wrote:
> > > The code to handle that is really ancient. You need to do:
> > > ./smatch --info test.c | tee warns.txt
> > > grep no_return_funcs warns.txt || echo FAIL
> > > ./smatch_scripts/gen_no_return_funcs.sh warns.txt -p=levon
> > > mv levon.no_return_funcs smatch_data/
> > >
> > > Then pass -p=levon to smatch on the next run.
> >
> > OK, thanks. That doesn't match too well with the way we use smatch, but
> > this is much less of a big deal (I only needed to annotate this in a
> > couple of places).
>
> It should be the the DB, right? Would that work for you?
There's few enough that it's preferable to just explicitly mark the
source as noreturn too, rather than keep a separate list.
regards
john
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-08-22 15:29 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-15 0:53 noreturn attribute doesn't work in smatch John Levon
2019-08-15 11:12 ` John Levon
2019-08-22 13:30 ` Dan Carpenter
2019-08-22 13:46 ` John Levon
2019-08-22 15:05 ` Dan Carpenter
2019-08-22 15:29 ` John Levon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox