Message ID | 20090202073151.GC28946@ZenIV.linux.org.uk (mailing list archive) |
---|---|
State | Mainlined, archived |
Headers | show |
On Sun, Feb 1, 2009 at 11:31 PM, Al Viro <viro@zeniv.linux.org.uk> wrote: > sizeof (typename){initializers}.foo is nice and valid C99 - it's parsed > as sizeof primary.foo <- sizeof postfix.foo <- sizeof postfix <- sizeof unary > <- unary. Current type_info_expression() stops too early. Thanks for the patch. Looks great. > - if (match_op(token, '{')) > - token = initializer(&expr->cast_expression, token); > + if (match_op(token, '{')) { > + struct expression *cast = alloc_expression(p->pos, EXPR_CAST); > + cast->cast_type = expr->cast_type; > + expr->cast_type = NULL; Setting expr->cast_type = NULL here is not straightly necessary right? The expr is EXPR_SIZEOF type, the expr->cast_type is not used in evaluation_sizeof. Of course it doesn't hurt, I just want to get a confirm that I understand it correct.y. 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
On Thu, Feb 05, 2009 at 10:29:19AM -0800, Christopher Li wrote: > Setting expr->cast_type = NULL here is not straightly necessary right? > The expr is EXPR_SIZEOF type, the expr->cast_type is not used in > evaluation_sizeof. Of course it doesn't hurt, I just want to get a confirm > that I understand it correct.y. Take a look at evaluate_type_information(). If ->cast_type is not NULL, it won't even look at ->cast_expression. For sizeof (struct foo){0,1} that's fine (you end with with sizeof(struct foo), essentially), but for sizeof(struct foo){0,1}.x that'll give you the wrong answer. IOW, it is necessary. -- 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 Thu, Feb 5, 2009 at 11:23 AM, Al Viro <viro@zeniv.linux.org.uk> wrote: > On Thu, Feb 05, 2009 at 10:29:19AM -0800, Christopher Li wrote: > Take a look at evaluate_type_information(). If ->cast_type is not NULL, > it won't even look at ->cast_expression. For sizeof (struct foo){0,1} that's > fine (you end with with sizeof(struct foo), essentially), but for > sizeof(struct foo){0,1}.x that'll give you the wrong answer. > > IOW, it is necessary. That is the subtle detail I am looking for. I will apply your patch. Thanks 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
diff --git a/expression.c b/expression.c index f634b07..124a8ec 100644 --- a/expression.c +++ b/expression.c @@ -594,12 +594,14 @@ static struct token *type_info_expression(struct token *token, struct expression **tree, int type) { struct expression *expr = alloc_expression(token->pos, type); + struct token *p; *tree = expr; expr->flags = Int_const_expr; /* XXX: VLA support will need that changed */ token = token->next; if (!match_op(token, '(') || !lookup_type(token->next)) return unary_expression(token, &expr->cast_expression); + p = token; token = typename(token->next, &expr->cast_type, 0); if (!match_op(token, ')')) { @@ -616,8 +618,14 @@ static struct token *type_info_expression(struct token *token, * C99 ambiguity: the typename might have been the beginning * of a typed initializer expression.. */ - if (match_op(token, '{')) - token = initializer(&expr->cast_expression, token); + if (match_op(token, '{')) { + struct expression *cast = alloc_expression(p->pos, EXPR_CAST); + cast->cast_type = expr->cast_type; + expr->cast_type = NULL; + expr->cast_expression = cast; + token = initializer(&cast->cast_expression, token); + token = postfix_expression(token, &expr->cast_expression, cast); + } return token; } diff --git a/validation/sizeof-compound-postfix.c b/validation/sizeof-compound-postfix.c new file mode 100644 index 0000000..3b716fe --- /dev/null +++ b/validation/sizeof-compound-postfix.c @@ -0,0 +1,8 @@ +struct foo {int x, y;}; +static int a(void) +{ + return sizeof (struct foo){0,1}.y; +} +/* + * check-name: Handling of sizeof compound-literal . member + */
sizeof (typename){initializers}.foo is nice and valid C99 - it's parsed as sizeof primary.foo <- sizeof postfix.foo <- sizeof postfix <- sizeof unary <- unary. Current type_info_expression() stops too early. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> --- expression.c | 12 ++++++++++-- validation/sizeof-compound-postfix.c | 8 ++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 validation/sizeof-compound-postfix.c