aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-05-28 23:34:39 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-05-28 23:34:39 +0000
commitb3dd05b10a8318c7af07941d3b13b75b5c4f5683 (patch)
treefc43bc68b07b9156872a885e6b8eb0ad184a0c72
parent5182fafe486b98e95bd51d2d665a2a18f397fbe4 (diff)
downloadgcc-b3dd05b10a8318c7af07941d3b13b75b5c4f5683.zip
gcc-b3dd05b10a8318c7af07941d3b13b75b5c4f5683.tar.gz
gcc-b3dd05b10a8318c7af07941d3b13b75b5c4f5683.tar.bz2
re PR c++/15471 (Incorrect member pointer offsets in anonymous structs/unions)
PR c++/15471 * typeck.c (unary_complex_lvalue): Use context_for_name_lookup when determining the scope to use for a pointer to member. (lookup_anon_field): Give it external linkage. * cp-tree.h (lookup_anon_field): Declare it. * expr.c (cplus_expand_constant): Use it. From-SVN: r82401
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/expr.c17
-rw-r--r--gcc/cp/typeck.c3
4 files changed, 20 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6fe8517..73d34b8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -16,6 +16,9 @@
PR c++/15471
* typeck.c (unary_complex_lvalue): Use context_for_name_lookup
when determining the scope to use for a pointer to member.
+ (lookup_anon_field): Give it external linkage.
+ * cp-tree.h (lookup_anon_field): Declare it.
+ * expr.c (cplus_expand_constant): Use it.
2004-05-28 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9fc83d5..8b4e7f7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4243,6 +4243,7 @@ extern tree build_ptrmemfunc_access_expr (tree, tree);
extern tree build_address (tree);
extern tree build_nop (tree, tree);
extern tree non_reference (tree);
+extern tree lookup_anon_field (tree, tree);
/* in typeck2.c */
extern void require_complete_eh_spec_types (tree, tree);
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index e12c6a4..466d984 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -51,8 +51,21 @@ cplus_expand_constant (tree cst)
member = PTRMEM_CST_MEMBER (cst);
if (TREE_CODE (member) == FIELD_DECL)
- /* Find the offset for the field. */
- cst = fold (build_nop (type, byte_position (member)));
+ {
+ /* Find the offset for the field. */
+ cst = byte_position (member);
+ while (!same_type_p (DECL_CONTEXT (member),
+ TYPE_PTRMEM_CLASS_TYPE (type)))
+ {
+ /* The MEMBER must have been nestled within an
+ anonymous aggregate contained in TYPE. Find the
+ anonymous aggregate. */
+ member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
+ DECL_CONTEXT (member));
+ cst = size_binop (PLUS_EXPR, cst, byte_position (member));
+ }
+ cst = fold (build_nop (type, cst));
+ }
else
{
tree delta;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 2570868..527134d 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -54,7 +54,6 @@ static int comp_ptr_ttypes_const (tree, tree);
static bool comp_except_types (tree, tree, bool);
static bool comp_array_types (tree, tree, bool);
static tree common_base_type (tree, tree);
-static tree lookup_anon_field (tree, tree);
static tree pointer_diff (tree, tree, tree);
static tree get_delta_difference (tree, tree, int);
static void casts_away_constness_r (tree *, tree *);
@@ -1517,7 +1516,7 @@ rationalize_conditional_expr (enum tree_code code, tree t)
anonymous unions can nest, we must also search all anonymous unions
that are directly reachable. */
-static tree
+tree
lookup_anon_field (tree t, tree type)
{
tree field;