OSDN Git Service

PR c/32041
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Jan 2009 19:44:33 +0000 (19:44 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Jan 2009 19:44:33 +0000 (19:44 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@143305 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/offsetof9.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr32041.c [new file with mode: 0644]

index a86f009..21c58ec 100644 (file)
@@ -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
index 99c6c18..5cb1982 100644 (file)
@@ -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))
index de7d1ab..c81a1e6 100644 (file)
@@ -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.
index f497d66..bf742ee 100644 (file)
@@ -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;
 
index 3a54a66..6661966 100644 (file)
@@ -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 (file)
index 0000000..efc1038
--- /dev/null
@@ -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 (file)
index 0000000..60837b2
--- /dev/null
@@ -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];
+