On Apr 11, 2018, Jason Merrill <ja...@redhat.com> wrote:

> I raised this issue with the C++ committee, and it seems that nobody
> expects defining a type here to work.  So let's go back to your first
> patch, removing the offending part of semicolon3.C.

All right, here's the adjusted patch.  Retested on i686- and
x86_64-linux-gnu.  Ok to install?


[PR c++/85039] no type definitions in builtin offsetof

Types defined within a __builtin_offsetof argument don't always get
properly recorded as members of their context types, so if they're
anonymous, we may fail to assign them an anon type index for mangling
and ICE.

We shouldn't allow types to be introduced in __builtin_offsetof, I
think, and Jason says the std committee agrees, so I've arranged for
us to reject them.

Even then, we still parse the definitions and attempt to assign
mangled names to its member functions, so the ICE remains.  Since
we've already reported an error, we might as well complete the name
assignment with an arbitrary index, thus avoiding the ICE.

We used to have a test that expected to be able to define types in
__builtin_offsetof; this patch removes that specific test.


for  gcc/cp/ChangeLog

        PR c++/85039
        * parser.c (cp_parser_builtin_offset): Reject type definitions.
        * mangle.c (nested_anon_class_index): Avoid crash returning -1
        if we've seen errors.

for  gcc/testsuite/ChangeLog

        PR c++/85039
        * g++.dg/pr85039-1.C: New.
        * g++.dg/pr85039-2.C: New.
        * g++.dg/parse/semicolon3.C: Remove test_offsetof.
---
 gcc/cp/mangle.c                         |    3 +++
 gcc/cp/parser.c                         |    8 +++++++-
 gcc/testsuite/g++.dg/parse/semicolon3.C |    7 -------
 gcc/testsuite/g++.dg/pr85039-1.C        |   17 +++++++++++++++++
 gcc/testsuite/g++.dg/pr85039-2.C        |   10 ++++++++++
 5 files changed, 37 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pr85039-1.C
 create mode 100644 gcc/testsuite/g++.dg/pr85039-2.C

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 94c4bed28486..a7f9d686345d 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1623,6 +1623,9 @@ nested_anon_class_index (tree type)
          ++index;
       }
 
+  if (seen_error ())
+    return -1;
+
   gcc_unreachable ();
 }
 
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 8b1b271b53d1..bf46165f5ae1 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -9823,7 +9823,13 @@ cp_parser_builtin_offsetof (cp_parser *parser)
   parens.require_open (parser);
   /* Parse the type-id.  */
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
-  type = cp_parser_type_id (parser);
+  {
+    const char *saved_message = parser->type_definition_forbidden_message;
+    parser->type_definition_forbidden_message
+      = G_("types may not be defined within __builtin_offsetof");
+    type = cp_parser_type_id (parser);
+    parser->type_definition_forbidden_message = saved_message;
+  }
   /* Look for the `,'.  */
   cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   token = cp_lexer_peek_token (parser->lexer);
diff --git a/gcc/testsuite/g++.dg/parse/semicolon3.C 
b/gcc/testsuite/g++.dg/parse/semicolon3.C
index 8a2b1ac46301..0d46be9ed654 100644
--- a/gcc/testsuite/g++.dg/parse/semicolon3.C
+++ b/gcc/testsuite/g++.dg/parse/semicolon3.C
@@ -20,13 +20,6 @@ struct OK3
 } // no complaints
   (s7);
 
-__SIZE_TYPE__
-test_offsetof (void)
-{
-  // no complaints about a missing semicolon
-  return __builtin_offsetof (struct OK4 { int a; int b; }, b);
-}
-
 struct OK5
 {
   int a;
diff --git a/gcc/testsuite/g++.dg/pr85039-1.C b/gcc/testsuite/g++.dg/pr85039-1.C
new file mode 100644
index 000000000000..f57c8a261dee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr85039-1.C
@@ -0,0 +1,17 @@
+// { dg-do compile { target c++14 } }
+
+constexpr int a() {
+ return
+  __builtin_offsetof(struct { // { dg-error "types may not be defined" }
+    int i;
+    short b {
+      __builtin_offsetof(struct { // { dg-error "types may not be defined" }
+       int j;
+        struct c { // { dg-error "types may not be defined" }
+          void d() {
+          }
+        };
+      }, j)
+    };
+  }, i);
+}
diff --git a/gcc/testsuite/g++.dg/pr85039-2.C b/gcc/testsuite/g++.dg/pr85039-2.C
new file mode 100644
index 000000000000..e6d16325105b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr85039-2.C
@@ -0,0 +1,10 @@
+// { dg-do compile }
+
+struct d {
+  static d *b;
+} * d::b(__builtin_offsetof(struct { // { dg-error "types may not be defined" }
+  int i;
+  struct a { // { dg-error "types may not be defined" }
+    int c() { return .1f; }
+  };
+}, i));


-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer

Reply via email to