aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gcc.gnu.org>2006-08-17 07:02:55 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2006-08-17 07:02:55 +0000
commit6d4d7b0eed1846e13f5dd75765696b2b6854af44 (patch)
treea00c91d8a45badf842fef53d1a9a8662c9f6f24b /gcc
parente98a430b854487d164b042b9a1ab0cb6dba0ca25 (diff)
downloadgcc-6d4d7b0eed1846e13f5dd75765696b2b6854af44.zip
gcc-6d4d7b0eed1846e13f5dd75765696b2b6854af44.tar.gz
gcc-6d4d7b0eed1846e13f5dd75765696b2b6854af44.tar.bz2
[multiple changes]
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. From-SVN: r116208
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-common.c32
-rw-r--r--gcc/c-common.h2
-rw-r--r--gcc/c-parser.c4
-rw-r--r--gcc/c-typeck.c2
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/parse/offsetof6.C19
-rw-r--r--gcc/testsuite/g++.dg/parse/offsetof7.C18
10 files changed, 89 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f4c0ff4..d2bc8c5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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.
+
2006-08-16 Zdenek Dvorak <dvorakz@suse.cz>
PR gcov/profile/26570
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 167d04b..17643f0 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
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 4f4919e..633990a 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -830,7 +830,7 @@ extern void c_warn_unused_result (tree *);
extern void verify_sequence_points (tree);
-extern tree fold_offsetof (tree);
+extern tree fold_offsetof (tree, tree);
/* Places where an lvalue, or modifiable lvalue, may be required.
Used to select diagnostic messages in lvalue_error and
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 6e243df..9031e5b 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -5203,7 +5203,7 @@ c_parser_postfix_expression (c_parser *parser)
if (type == error_mark_node)
offsetof_ref = error_mark_node;
else
- offsetof_ref = build1 (INDIRECT_REF, type, NULL);
+ offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
/* Parse the second argument to __builtin_offsetof. We
must have one identifier, and beyond that we want to
accept sub structure and sub array references. */
@@ -5245,7 +5245,7 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- expr.value = fold_offsetof (offsetof_ref);
+ expr.value = fold_offsetof (offsetof_ref, NULL_TREE);
expr.original_code = ERROR_MARK;
}
break;
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index dee7414..c55bcad 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -3057,7 +3057,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
if (val && TREE_CODE (val) == INDIRECT_REF
&& TREE_CONSTANT (TREE_OPERAND (val, 0)))
{
- tree op0 = fold_convert (argtype, fold_offsetof (arg)), op1;
+ tree op0 = fold_convert (argtype, fold_offsetof (arg, val)), op1;
op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
return fold_build2 (PLUS_EXPR, argtype, op0, op1);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cde739d..7048c5f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,8 +1,13 @@
+2006-08-17 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c++/28573
+ * semantics.c (finish_offsetof): Add new argument to fold_offsetof.
+
2006-08-16 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/28302
* typeck.c (build_unary_op <case BIT_NOT_EXPR:>): Don't call
- perform_integral_promotions for non integral type
+ perform_integral_promotions for non integral type.
2006-08-16 Jason Merrill <jason@redhat.com>
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index d36eba76..fb4ea0a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2904,7 +2904,7 @@ finish_offsetof (tree expr)
error ("cannot apply %<offsetof%> to member function %qD", expr);
return error_mark_node;
}
- return fold_offsetof (expr);
+ return fold_offsetof (expr, NULL_TREE);
}
/* Called from expand_body via walk_tree. Replace all AGGR_INIT_EXPRs
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3da59b8..624a2f2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2006-08-17 Paolo Bonzini <bonzini@gnu.org>
+
+ * PR c++/28573
+ * g++.dg/parse/offsetof6.C: New test.
+ * g++.dg/parse/offsetof6.C: New test.
+ * g++.dg/parse/offsetof7.C: New test.
+
2006-08-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR testsuite/28602
@@ -6,7 +13,7 @@
2006-08-16 Andrew Pinski <pinskia@physics.uc.edu>
- PR C++/28302
+ PR c++/28302
* g++.dg/ext/vector3.C: New test.
2006-08-16 Zdenek Dvorak <dvorakz@suse.cz>
diff --git a/gcc/testsuite/g++.dg/parse/offsetof6.C b/gcc/testsuite/g++.dg/parse/offsetof6.C
new file mode 100644
index 0000000..0e07a53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/offsetof6.C
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+// From PR28573
+
+struct A
+{
+ char d[44];
+ char &operator [] ( int indx ) { return d[indx]; }
+};
+
+struct B
+{
+ A a;
+};
+
+int main()
+{
+ return __builtin_offsetof(B, a[0]); /* { dg-error "cannot apply.*offsetof" } */
+}
diff --git a/gcc/testsuite/g++.dg/parse/offsetof7.C b/gcc/testsuite/g++.dg/parse/offsetof7.C
new file mode 100644
index 0000000..113a795
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/offsetof7.C
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+// From PR28573
+
+struct A
+{
+ int operator [] ( int indx ) { return indx; }
+};
+
+struct B
+{
+ A a;
+};
+
+int main()
+{
+ return __builtin_offsetof(B, a[0]); /* { dg-error "cannot apply.*offsetof" } */
+}