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
+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
}
/* 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:
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;
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;
}
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
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
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. */
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;
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);
+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>
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
+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
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>
--- /dev/null
+/* { 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" } */
+}
--- /dev/null
+/* { 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" } */
+}