diff options
author | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-08-17 07:02:55 +0000 |
---|---|---|
committer | bonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-08-17 07:02:55 +0000 |
commit | d897f7c2662b96117752b1f5c56b547eaa994f5c (patch) | |
tree | a00c91d8a45badf842fef53d1a9a8662c9f6f24b /gcc/c-common.c | |
parent | c5d84873a6273e380ee113e2194610c0da85b04a (diff) | |
download | gcc-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.c | 32 |
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 |