[PR c++/85039] no type definitions in builtin offsetof
authorAlexandre Oliva <aoliva@redhat.com>
Mon, 16 Apr 2018 21:35:34 +0000 (21:35 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Mon, 16 Apr 2018 21:35:34 +0000 (21:35 +0000)
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.

From-SVN: r259423

gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/semicolon3.C
gcc/testsuite/g++.dg/pr85039-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/pr85039-2.C [new file with mode: 0644]

index 5f29b0c82502713032893bfe10ef2a4cf19e79de..954127f3c28c5226d075a67029d3d671d73a9a04 100644 (file)
@@ -1,3 +1,10 @@
+2018-04-16  Alexandre Oliva <aoliva@redhat.com>
+
+       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.
+
 2018-04-12  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/85385
index 94c4bed2848690352ad9308794c8bfd9c9ccf2bf..a7f9d686345d2cff9558e5cd5d77c98f647f2178 100644 (file)
@@ -1623,6 +1623,9 @@ nested_anon_class_index (tree type)
          ++index;
       }
 
+  if (seen_error ())
+    return -1;
+
   gcc_unreachable ();
 }
 
index 8b1b271b53d17205e547299bdc4074fb590354ef..bf46165f5ae1a4d468e7c77750b4fab2e75f5027 100644 (file)
@@ -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);
index 31c576bf024870129ffb45a58d54daaad91d5885..33258e6f4fc3a7c17f5fd980817d08c3462cbe2d 100644 (file)
@@ -1,3 +1,10 @@
+2018-04-16  Alexandre Oliva <aoliva@redhat.com>
+
+       PR c++/85039
+       * g++.dg/pr85039-1.C: New.
+       * g++.dg/pr85039-2.C: New.
+       * g++.dg/parse/semicolon3.C: Remove test_offsetof.
+
 2018-04-16  Bill Schmidt  <wschmidt@linux.ibm.com>
 
        PR target/85080
index 8a2b1ac46301f6a0ee7f18cfff3b391f0f58db5d..0d46be9ed65415588b6f17d3f2a56c5a3c2893a4 100644 (file)
@@ -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 (file)
index 0000000..f57c8a2
--- /dev/null
@@ -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 (file)
index 0000000..e6d1632
--- /dev/null
@@ -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));