summaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2006-08-17 07:02:55 +0000
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2006-08-17 07:02:55 +0000
commitd897f7c2662b96117752b1f5c56b547eaa994f5c (patch)
treea00c91d8a45badf842fef53d1a9a8662c9f6f24b /gcc/c-common.c
parentc5d84873a6273e380ee113e2194610c0da85b04a (diff)
downloadgcc-d897f7c2662b96117752b1f5c56b547eaa994f5c.tar.gz
2006-08-17 Paolo Bonzini <bonzini@gnu.org>
PR c++/28573 * c-common.c (fold_offsetof_1): Add an argument and recurse down to it or the INTEGER_CST. Fail on a CALL_EXPR. (fold_offsetof): Pass new argument to fold_offsetof_1. * c-parser.c (c_parser_postfix_expression): Don't include a NULL operand into an INDIRECT_REF. * c-typeck.c (build_unary_op): Adjust call to fold_offsetof. cp: 2006-08-17 Paolo Bonzini <bonzini@gnu.org> PR c++/28573 * semantics.c (finish_offsetof): Add new argument to fold_offsetof. testsuite: 2006-08-17 Paolo Bonzini <bonzini@gnu.org> PR c++/28573 * g++.dg/parse/offsetof6.C: New test. * g++.dg/parse/offsetof7.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116208 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 167d04b81ff..17643f0b5ab 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -5982,16 +5982,19 @@ c_common_to_target_charset (HOST_WIDE_INT c)
}
/* Build the result of __builtin_offsetof. EXPR is a nested sequence of
- component references, with an INDIRECT_REF at the bottom; much like
- the traditional rendering of offsetof as a macro. Returns the folded
- and properly cast result. */
+ component references, with STOP_REF, or alternatively an INDIRECT_REF of
+ NULL, at the bottom; much like the traditional rendering of offsetof as a
+ macro. Returns the folded and properly cast result. */
static tree
-fold_offsetof_1 (tree expr)
+fold_offsetof_1 (tree expr, tree stop_ref)
{
enum tree_code code = PLUS_EXPR;
tree base, off, t;
+ if (expr == stop_ref && TREE_CODE (expr) != ERROR_MARK)
+ return size_zero_node;
+
switch (TREE_CODE (expr))
{
case ERROR_MARK:
@@ -6001,11 +6004,22 @@ fold_offsetof_1 (tree expr)
error ("cannot apply %<offsetof%> to static data member %qD", expr);
return error_mark_node;
- case INDIRECT_REF:
+ case CALL_EXPR:
+ error ("cannot apply %<offsetof%> when %<operator[]%> is overloaded");
+ return error_mark_node;
+
+ case INTEGER_CST:
+ gcc_assert (integer_zerop (expr));
return size_zero_node;
+ case NOP_EXPR:
+ case INDIRECT_REF:
+ base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
+ gcc_assert (base == error_mark_node || base == size_zero_node);
+ return base;
+
case COMPONENT_REF:
- base = fold_offsetof_1 (TREE_OPERAND (expr, 0));
+ base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
if (base == error_mark_node)
return base;
@@ -6022,7 +6036,7 @@ fold_offsetof_1 (tree expr)
break;
case ARRAY_REF:
- base = fold_offsetof_1 (TREE_OPERAND (expr, 0));
+ base = fold_offsetof_1 (TREE_OPERAND (expr, 0), stop_ref);
if (base == error_mark_node)
return base;
@@ -6044,10 +6058,10 @@ fold_offsetof_1 (tree expr)
}
tree
-fold_offsetof (tree expr)
+fold_offsetof (tree expr, tree stop_ref)
{
/* Convert back from the internal sizetype to size_t. */
- return convert (size_type_node, fold_offsetof_1 (expr));
+ return convert (size_type_node, fold_offsetof_1 (expr, stop_ref));
}
/* Print an error message for an invalid lvalue. USE says