From 634b5df5d5c0ccfaa523ca0f9a737df3c0f28372 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 12 Jan 2009 20:44:33 +0100 Subject: [PATCH] re PR c/32041 (offsetof buglet) PR c/32041 * c-parser.c (c_parser_postfix_expression): Allow `->' in offsetof member-designator, handle it as `[0].'. * parser.c (cp_parser_builtin_offsetof): Allow `->' in offsetof member-designator, handle it as `[0].'. * gcc.dg/pr32041.c: New test. * g++.dg/parse/offsetof9.C: New test. From-SVN: r143305 --- gcc/ChangeLog | 6 +++++ gcc/c-parser.c | 15 ++++++++++-- gcc/cp/ChangeLog | 4 ++++ gcc/cp/parser.c | 14 +++++++---- gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/g++.dg/parse/offsetof9.C | 32 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr32041.c | 12 ++++++++++ 7 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/offsetof9.C create mode 100644 gcc/testsuite/gcc.dg/pr32041.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a86f0095cc9..21c58ec6f1d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-01-12 Jakub Jelinek + + PR c/32041 + * c-parser.c (c_parser_postfix_expression): Allow `->' in + offsetof member-designator, handle it as `[0].'. + 2009-01-12 John David Anglin * pa.c (pa_asm_output_mi_thunk): Use pc-relative branch to thunk diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 99c6c187a1e..5cb1982a544 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -5273,10 +5273,21 @@ c_parser_postfix_expression (c_parser *parser) c_parser_consume_token (parser); while (c_parser_next_token_is (parser, CPP_DOT) || c_parser_next_token_is (parser, - CPP_OPEN_SQUARE)) + CPP_OPEN_SQUARE) + || c_parser_next_token_is (parser, + CPP_DEREF)) { - if (c_parser_next_token_is (parser, CPP_DOT)) + if (c_parser_next_token_is (parser, CPP_DEREF)) + { + loc = c_parser_peek_token (parser)->location; + offsetof_ref = build_array_ref (offsetof_ref, + integer_zero_node, + loc); + goto do_dot; + } + else if (c_parser_next_token_is (parser, CPP_DOT)) { + do_dot: c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_NAME)) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index de7d1ab0684..c81a1e63881 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2009-01-12 Jakub Jelinek + PR c/32041 + * parser.c (cp_parser_builtin_offsetof): Allow `->' in + offsetof member-designator, handle it as `[0].'. + PR c++/38794 * decl.c (start_function): If grokdeclarator hasn't returned FUNCTION_DECL nor error_mark_node, issue diagnostics. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f497d664783..bf742eea079 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1,6 +1,6 @@ /* C++ Parser. Copyright (C) 2000, 2001, 2002, 2003, 2004, - 2005, 2007, 2008 Free Software Foundation, Inc. + 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Mark Mitchell . This file is part of GCC. @@ -6627,7 +6627,8 @@ cp_parser_constant_expression (cp_parser* parser, offsetof-member-designator: id-expression | offsetof-member-designator "." id-expression - | offsetof-member-designator "[" expression "]" */ + | offsetof-member-designator "[" expression "]" + | offsetof-member-designator "->" id-expression */ static tree cp_parser_builtin_offsetof (cp_parser *parser) @@ -6670,11 +6671,16 @@ cp_parser_builtin_offsetof (cp_parser *parser) expr = cp_parser_postfix_open_square_expression (parser, expr, true); break; + case CPP_DEREF: + /* offsetof-member-designator "->" identifier */ + expr = grok_array_decl (expr, integer_zero_node); + /* FALLTHRU */ + case CPP_DOT: /* offsetof-member-designator "." identifier */ cp_lexer_consume_token (parser->lexer); - expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, expr, - true, &dummy, + expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT, + expr, true, &dummy, token->location); break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a54a665a58..66619662faa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-01-12 Jakub Jelinek + + PR c/32041 + * gcc.dg/pr32041.c: New test. + * g++.dg/parse/offsetof9.C: New test. + 2009-01-12 Daniel Jacobowitz Nathan Froyd diff --git a/gcc/testsuite/g++.dg/parse/offsetof9.C b/gcc/testsuite/g++.dg/parse/offsetof9.C new file mode 100644 index 00000000000..efc103837f9 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/offsetof9.C @@ -0,0 +1,32 @@ +/* PR c/32041 */ +/* { dg-do run } */ + +struct S +{ + int c; + struct { float f; } sa[2]; +}; + +char a[__builtin_offsetof (S, sa->f) + == __builtin_offsetof (S, sa[0].f) ? 1 : -1]; + +template +struct T +{ + int c[N]; + struct { float f; } sa[N]; + static int foo () { return __builtin_offsetof (T, sa->f); } + static int bar () { return __builtin_offsetof (T, sa[0].f); } +}; + +char b[__builtin_offsetof (T<5>, sa->f) + == __builtin_offsetof (T<5>, sa[0].f) ? 1 : -1]; + +int +main () +{ + if (T<1>::foo () != T<1>::bar ()) + __builtin_abort (); + if (T<7>::foo () != T<7>::bar ()) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/pr32041.c b/gcc/testsuite/gcc.dg/pr32041.c new file mode 100644 index 00000000000..60837b20436 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr32041.c @@ -0,0 +1,12 @@ +/* PR c/32041 */ +/* { dg-do compile } */ + +struct S +{ + int c; + struct { float f; } sa[2]; +}; + +char a[__builtin_offsetof (struct S, sa->f) + == __builtin_offsetof (struct S, sa[0].f) ? 1 : -1]; + -- 2.30.2