re PR c++/27601 (ICE (in fold_offsetof_1, at c-common.c:5998) on strange offsetof)
authorVolker Reichelt <reichelt@igpm.rwth-aachen.de>
Wed, 7 Jun 2006 16:08:30 +0000 (16:08 +0000)
committerVolker Reichelt <reichelt@gcc.gnu.org>
Wed, 7 Jun 2006 16:08:30 +0000 (16:08 +0000)
PR c++/27601
* cp-tree.h (finish_offsetof): Add prototype.
* semantics.c (finish_offsetof): New function.
* parser.c (cp_parser_builtin_offsetof): Call it instead of
fold_offsetof.
* pt.c (tsubst_copy_and_build): Likewise.

* g++.dg/ext/offsetof1.C: Test member functions.

From-SVN: r114469

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/offsetof1.C

index c63ad8390ef42fac69aee1e4f43740ca4fa1a79a..d401f88d79f4a8492beb0ca14284637f32f68590 100644 (file)
@@ -1,3 +1,12 @@
+2006-06-07  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+
+       PR c++/27601
+       * cp-tree.h (finish_offsetof): Add prototype.
+       * semantics.c (finish_offsetof): New function.
+       * parser.c (cp_parser_builtin_offsetof): Call it instead of
+       fold_offsetof.
+       * pt.c (tsubst_copy_and_build): Likewise.
+
 2006-06-06  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/27177
index 4e83852a304e2790f05a93e20cfdbd668714d603..77b906729eb82239cb69ea3ccb935e3c7b388a8d 100644 (file)
@@ -4252,6 +4252,7 @@ extern tree finish_id_expression          (tree, tree, tree,
                                                 bool, bool, bool, bool,
                                                 const char **);
 extern tree finish_typeof                      (tree);
+extern tree finish_offsetof                    (tree);
 extern void finish_decl_cleanup                        (tree, tree);
 extern void finish_eh_cleanup                  (tree);
 extern void expand_body                                (tree);
index ee807295e6b620d1a10d6271e3bb31c5eb754daa..eaebe191c54ac2b5eab429e04b67ff842a894228 100644 (file)
@@ -6036,7 +6036,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
   if (processing_template_decl)
     expr = build1 (OFFSETOF_EXPR, size_type_node, expr);
   else
-    expr = fold_offsetof (expr);
+    expr = finish_offsetof (expr);
 
  failure:
   parser->integral_constant_expression_p = save_ice_p;
index 8b2f0d3054e45270973e7c99cff96935694175d0..07963d6b37098f16e2f4b03ca8e58faa81add914 100644 (file)
@@ -9126,7 +9126,7 @@ tsubst_copy_and_build (tree t,
                                          in_decl));
 
     case OFFSETOF_EXPR:
-      return fold_offsetof (RECUR (TREE_OPERAND (t, 0)));
+      return finish_offsetof (RECUR (TREE_OPERAND (t, 0)));
 
     case STMT_EXPR:
       {
index b4e9505b75bead02d820be2976b64aca59d1f98f..8b4142316666c42b1c6d9a3aef2e9dd632f83656 100644 (file)
@@ -2881,6 +2881,23 @@ finish_typeof (tree expr)
   return type;
 }
 
+/* Perform C++-specific checks for __builtin_offsetof before calling
+   fold_offsetof.  */
+
+tree
+finish_offsetof (tree expr)
+{
+  if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
+      || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
+      || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE)
+    {
+      error ("cannot apply %<offsetof%> to member function %qD",
+            TREE_OPERAND (expr, 1));
+      return error_mark_node;
+    }
+  return fold_offsetof (expr);
+}
+
 /* Called from expand_body via walk_tree.  Replace all AGGR_INIT_EXPRs
    with equivalent CALL_EXPRs.  */
 
index 0e870df741be143b3e122cd814e486e0e460f766..3e0314552d938bd3d2637d0a608341ce638c923e 100644 (file)
@@ -1,3 +1,8 @@
+2006-06-07  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+
+       PR c++/27601
+       * g++.dg/ext/offsetof1.C: Test member functions.
+
 2006-06-07  Steve Ellcey  <sje@cup.hp.com>
 
        * gcc.dg/pr27095.c: Improve scanning.
index 5d6552f78787215971f7fc9a975e689786a5395d..0cfabf8033c9b2cfdc9ef3de449bd22952f9e485 100644 (file)
@@ -4,6 +4,9 @@
 
 struct bar {
   static int foo;
+  static int baz();
 };
 
 int a = __builtin_offsetof(bar, foo);  // { dg-error "static data member" }
+int b = __builtin_offsetof(bar, baz);  // { dg-error "member function" }
+int c = __builtin_offsetof(bar, ~bar);  // { dg-error "member function" }