diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-parser.c | 15 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/parser.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/offsetof9.C | 32 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr32041.c | 12 |
7 files changed, 83 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a86f009..21c58ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-01-12 Jakub Jelinek <jakub@redhat.com> + + 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 <dave.anglin@nrc-cnrc.gc.ca> * 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 99c6c18..5cb1982 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 de7d1ab..c81a1e6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2009-01-12 Jakub Jelinek <jakub@redhat.com> + 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 f497d66..bf742eea 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 <mark@codesourcery.com>. 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 3a54a66..6661966 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-01-12 Jakub Jelinek <jakub@redhat.com> + + PR c/32041 + * gcc.dg/pr32041.c: New test. + * g++.dg/parse/offsetof9.C: New test. + 2009-01-12 Daniel Jacobowitz <dan@codesourcery.com> Nathan Froyd <froydnj@codesourcery.com> diff --git a/gcc/testsuite/g++.dg/parse/offsetof9.C b/gcc/testsuite/g++.dg/parse/offsetof9.C new file mode 100644 index 0000000..efc1038 --- /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 <int N> +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 0000000..60837b2 --- /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]; + |