re PR c++/64487 (internal compiler error: in fold_offsetof_1, at c-family/c-common...
authorJason Merrill <jason@redhat.com>
Tue, 6 Jan 2015 20:44:46 +0000 (15:44 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 6 Jan 2015 20:44:46 +0000 (15:44 -0500)
PR c++/64487
* semantics.c (finish_offsetof): Handle templates here.
* parser.c (cp_parser_builtin_offsetof): Not here.

From-SVN: r219267

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/template/offsetof3.C [new file with mode: 0644]

index 67fd50110a2d0d1bd382d9de4aad2c01e55dc663..604b518d6072ba3f233f41d2a684781144c26e70 100644 (file)
@@ -1,5 +1,9 @@
 2015-01-06  Jason Merrill  <jason@redhat.com>
 
+       PR c++/64487
+       * semantics.c (finish_offsetof): Handle templates here.
+       * parser.c (cp_parser_builtin_offsetof): Not here.
+
        PR c++/64496
        * semantics.c (process_outer_var_ref): Diagnose lambda in local
        class NSDMI.
index 52234de5cd43277f48b98b95e84355eea95fcf58..22dff06eb6c7a87b6b6221c41fc5dab76fb96ae4 100644 (file)
@@ -8729,15 +8729,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
     }
 
  success:
-  /* If we're processing a template, we can't finish the semantics yet.
-     Otherwise we can fold the entire expression now.  */
-  if (processing_template_decl)
-    {
-      expr = build1 (OFFSETOF_EXPR, size_type_node, expr);
-      SET_EXPR_LOCATION (expr, loc);
-    }
-  else
-    expr = finish_offsetof (expr, loc);
+  expr = finish_offsetof (expr, loc);
 
  failure:
   parser->integral_constant_expression_p = save_ice_p;
index 551bad132e91b348f38ed56e6c2879d249f70a8f..4365a53acd6cbb7e89909afd8fe8a3a184afe03b 100644 (file)
@@ -3870,6 +3870,15 @@ finish_bases (tree type, bool direct)
 tree
 finish_offsetof (tree expr, location_t loc)
 {
+  /* If we're processing a template, we can't finish the semantics yet.
+     Otherwise we can fold the entire expression now.  */
+  if (processing_template_decl)
+    {
+      expr = build1 (OFFSETOF_EXPR, size_type_node, expr);
+      SET_EXPR_LOCATION (expr, loc);
+      return expr;
+    }
+
   if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
     {
       error ("cannot apply %<offsetof%> to destructor %<~%T%>",
diff --git a/gcc/testsuite/g++.dg/template/offsetof3.C b/gcc/testsuite/g++.dg/template/offsetof3.C
new file mode 100644 (file)
index 0000000..b173746
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/64487
+
+struct foo {
+      int member;
+};
+
+template < int N>
+struct bar {};
+
+template <int N>
+struct qux {
+        static bar<N+__builtin_offsetof(foo,member)> static_member;
+};
+
+template <int N>
+bar<N+__builtin_offsetof(foo,member)> qux<N>::static_member;
+
+int main() { }