From: Josh Triplett <josh@joshtriplett.org>
To: John Keeping <john@keeping.me.uk>
Cc: linux-sparse@vger.kernel.org
Subject: Re: [PATCH 2/2] Support GCC's transparent unions
Date: Sat, 1 Mar 2014 12:21:39 -0800 [thread overview]
Message-ID: <20140301202139.GC24871@thin> (raw)
In-Reply-To: <303d3e76a8db47a65f2015289cfd5259611723bf.1393674078.git.john@keeping.me.uk>
On Sat, Mar 01, 2014 at 11:41:39AM +0000, John Keeping wrote:
> This stops warnings in code using socket operations with a modern glibc,
> which otherwise result in warnings of the form:
>
> warning: incorrect type in argument 2 (invalid types)
> expected union __CONST_SOCKADDR_ARG [usertype] __addr
> got struct sockaddr *<noident>
>
> Since transparent unions are only applicable to function arguments, we
> create a new function to check that the types are compatible
> specifically in this context.
>
> Signed-off-by: John Keeping <john@keeping.me.uk>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> evaluate.c | 28 +++++++++++++++++++++++++++-
> lib.c | 2 --
> lib.h | 1 -
> parse.c | 6 ++++--
> sparse.1 | 8 --------
> symbol.h | 3 ++-
> validation/transparent-union.c | 25 +++++++++++++++++++++++++
> 7 files changed, 58 insertions(+), 15 deletions(-)
> create mode 100644 validation/transparent-union.c
>
> diff --git a/evaluate.c b/evaluate.c
> index 2e6511b..f36c6c1 100644
> --- a/evaluate.c
> +++ b/evaluate.c
> @@ -1406,6 +1406,32 @@ static int compatible_assignment_types(struct expression *expr, struct symbol *t
> return 1;
> }
>
> +static int compatible_argument_type(struct expression *expr, struct symbol *target,
> + struct expression **rp, const char *where)
> +{
> + const char *typediff;
> + struct symbol *source = degenerate(*rp);
> + struct symbol *t;
> + classify_type(target, &t);
> +
> + if (t->type == SYM_UNION && t->transparent_union) {
> + struct symbol *member;
> + FOR_EACH_PTR(t->symbol_list, member) {
> + if (check_assignment_types(member, rp, &typediff))
> + return 1;
> + } END_FOR_EACH_PTR(member);
> + }
> +
> + if (check_assignment_types(target, rp, &typediff))
> + return 1;
> +
> + warning(expr->pos, "incorrect type in %s (%s)", where, typediff);
> + info(expr->pos, " expected %s", show_typename(target));
> + info(expr->pos, " got %s", show_typename(source));
> + *rp = cast_to(*rp, target);
> + return 0;
> +}
> +
> static void mark_assigned(struct expression *expr)
> {
> struct symbol *sym;
> @@ -2172,7 +2198,7 @@ static int evaluate_arguments(struct symbol *f, struct symbol *fn, struct expres
> static char where[30];
> examine_symbol_type(target);
> sprintf(where, "argument %d", i);
> - compatible_assignment_types(expr, target, p, where);
> + compatible_argument_type(expr, target, p, where);
> }
>
> i++;
> diff --git a/lib.c b/lib.c
> index bf3e91c..a52b88e 100644
> --- a/lib.c
> +++ b/lib.c
> @@ -226,7 +226,6 @@ int Wparen_string = 0;
> int Wptr_subtraction_blows = 0;
> int Wreturn_void = 0;
> int Wshadow = 0;
> -int Wtransparent_union = 0;
> int Wtypesign = 0;
> int Wundef = 0;
> int Wuninitialized = 1;
> @@ -438,7 +437,6 @@ static const struct warning {
> { "ptr-subtraction-blows", &Wptr_subtraction_blows },
> { "return-void", &Wreturn_void },
> { "shadow", &Wshadow },
> - { "transparent-union", &Wtransparent_union },
> { "typesign", &Wtypesign },
> { "undef", &Wundef },
> { "uninitialized", &Wuninitialized },
> diff --git a/lib.h b/lib.h
> index f09b338..197b549 100644
> --- a/lib.h
> +++ b/lib.h
> @@ -120,7 +120,6 @@ extern int Wparen_string;
> extern int Wptr_subtraction_blows;
> extern int Wreturn_void;
> extern int Wshadow;
> -extern int Wtransparent_union;
> extern int Wtypesign;
> extern int Wundef;
> extern int Wuninitialized;
> diff --git a/parse.c b/parse.c
> index 9cc5f65..bf62bdd 100644
> --- a/parse.c
> +++ b/parse.c
> @@ -1207,8 +1207,10 @@ static struct token *attribute_designated_init(struct token *token, struct symbo
>
> static struct token *attribute_transparent_union(struct token *token, struct symbol *attr, struct decl_state *ctx)
> {
> - if (Wtransparent_union)
> - warning(token->pos, "ignoring attribute __transparent_union__");
> + if (ctx->ctype.base_type && ctx->ctype.base_type->type == SYM_UNION)
> + ctx->ctype.base_type->transparent_union = 1;
> + else
> + warning(token->pos, "attribute __transparent_union__ applied to non-union type");
> return token;
> }
>
> diff --git a/sparse.1 b/sparse.1
> index cd6be26..6e79202 100644
> --- a/sparse.1
> +++ b/sparse.1
> @@ -297,14 +297,6 @@ Such declarations can lead to error-prone code.
> Sparse does not issue these warnings by default.
> .
> .TP
> -.B \-Wtransparent\-union
> -Warn about any declaration using the GCC extension
> -\fB__attribute__((transparent_union))\fR.
> -
> -Sparse issues these warnings by default. To turn them off, use
> -\fB\-Wno\-transparent\-union\fR.
> -.
> -.TP
> .B \-Wtypesign
> Warn when converting a pointer to an integer type into a pointer to an integer
> type with different signedness.
> diff --git a/symbol.h b/symbol.h
> index 43c165b..ccb5dcb 100644
> --- a/symbol.h
> +++ b/symbol.h
> @@ -174,7 +174,8 @@ struct symbol {
> evaluated:1,
> string:1,
> designated_init:1,
> - forced_arg:1;
> + forced_arg:1,
> + transparent_union:1;
> struct expression *array_size;
> struct ctype ctype;
> struct symbol_list *arguments;
> diff --git a/validation/transparent-union.c b/validation/transparent-union.c
> new file mode 100644
> index 0000000..149c7d9
> --- /dev/null
> +++ b/validation/transparent-union.c
> @@ -0,0 +1,25 @@
> +struct a {
> + int field;
> +};
> +struct b {
> + int field;
> +};
> +
> +typedef union {
> + struct a *a;
> + struct b *b;
> +} transparent_arg __attribute__((__transparent_union__));
> +
> +static void foo(transparent_arg arg)
> +{
> +}
> +
> +static void bar(void)
> +{
> + struct b arg = { 0 };
> + foo((struct a *) &arg);
> +}
> +
> +/*
> + * check-name: Transparent union attribute.
> + */
> --
> 1.9.0.6.g037df60.dirty
>
> --
> 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
next prev parent reply other threads:[~2014-03-01 20:21 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-01 11:41 [PATCH 1/2] evaluate: split out implementation of compatible_assignment_types John Keeping
2014-03-01 11:41 ` [PATCH 2/2] Support GCC's transparent unions John Keeping
2014-03-01 20:21 ` Josh Triplett [this message]
2014-03-02 12:11 ` Ramsay Jones
2014-03-04 17:21 ` Christopher Li
2014-03-04 17:52 ` John Keeping
2014-03-05 0:58 ` Christopher Li
2014-03-09 1:28 ` Christopher Li
2014-03-01 20:16 ` [PATCH 1/2] evaluate: split out implementation of compatible_assignment_types Josh Triplett
2014-03-04 5:05 ` 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=20140301202139.GC24871@thin \
--to=josh@joshtriplett.org \
--cc=john@keeping.me.uk \
--cc=linux-sparse@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.