This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] Fix second part of PR c++/27601: ICE using offsetof with member functions
Here's the second attempt at fixing the second part of PR27601:
Instead of adding a C++-specific test to fold_offsetof_1 in c-common.c
(as proposed in the first version) this patch adds the check to
the C++ frontend. I.e. it adds the function finish_offsetof to
semantics.c which performs the checks and then calls fold_offsetof.
Both callers of fold_offsetof are modified to call the new function
instead.
Bootstrapped and regtested on x86_64-unknown-linux-gnu.
Ok for mainline, 4.1 branch, and 4.0 branch?
Regards,
Volker
:ADDPATCH C++:
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.
===================================================================
--- gcc/gcc/cp/cp-tree.h (revision 114427)
+++ gcc/gcc/cp/cp-tree.h (working copy)
@@ -4252,6 +4252,7 @@
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);
===================================================================
--- gcc/gcc/cp/semantics.c (revision 114427)
+++ gcc/gcc/cp/semantics.c (working copy)
@@ -2881,6 +2881,23 @@
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. */
===================================================================
--- gcc/gcc/cp/parser.c (revision 114427)
+++ gcc/gcc/cp/parser.c (working copy)
@@ -6053,7 +6053,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;
===================================================================
--- gcc/gcc/cp/pt.c (revision 114427)
+++ gcc/gcc/cp/pt.c (working copy)
@@ -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:
{
===================================================================
2006-06-07 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/27601
* g++.dg/ext/offsetof1.C: Test member functions.
===================================================================
--- gcc/gcc/testsuite/g++.dg/ext/offsetof1.C 2006-06-05 03:50:11 +0200
+++ gcc/gcc/testsuite/g++.dg/ext/offsetof1.C 2006-06-05 03:51:11 +0200
@@ -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" }
===================================================================