[PATCH] Accept -> in offsetof member-designator (the same as `[0].', PR c/32084)

Jakub Jelinek jakub@redhat.com
Wed Jan 7 21:37:00 GMT 2009


Hi!

For struct S { struct T { int i; } t[2]; } is
offsetof (struct S, t->i) valid, as with static struct S s;
&s.t->i is a valid address constant.  The following patch parses
it in both C and C++ FEs as [0].  Bootstrapped/regtested on x86_64-linux,
ok for trunk?

2009-01-07  Jakub Jelinek  <jakub@redhat.com>

	PR c/32084
	* 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/pr32084.c: New test.
	* g++.dg/parse/offsetof9.C: New test.

--- gcc/c-parser.c.jj	2009-01-02 09:32:56.000000000 +0100
+++ gcc/c-parser.c	2009-01-07 16:07:13.000000000 +0100
@@ -5273,10 +5273,21 @@ c_parser_postfix_expression (c_parser *p
 		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))
--- gcc/cp/parser.c.jj	2009-01-02 09:32:55.000000000 +0100
+++ gcc/cp/parser.c	2009-01-07 16:20:08.000000000 +0100
@@ -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
    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 *p
 	  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;
 
--- gcc/testsuite/gcc.dg/pr32084.c.jj	2009-01-07 16:23:55.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr32084.c	2009-01-07 16:11:54.000000000 +0100
@@ -0,0 +1,12 @@
+/* PR c/32084 */
+/* { 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];
+
--- gcc/testsuite/g++.dg/parse/offsetof9.C.jj	2009-01-07 16:31:23.000000000 +0100
+++ gcc/testsuite/g++.dg/parse/offsetof9.C	2009-01-07 16:34:48.000000000 +0100
@@ -0,0 +1,32 @@
+/* PR c/32084 */
+/* { 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 ();
+}

	Jakub



More information about the Gcc-patches mailing list