[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
This commit is contained in:
Paolo Bonzini 2006-08-17 07:02:55 +00:00
parent e98a430b85
commit 6d4d7b0eed
10 changed files with 89 additions and 16 deletions

View File

@ -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> 2006-08-16 Zdenek Dvorak <dvorakz@suse.cz>
PR gcov/profile/26570 PR gcov/profile/26570

View File

@ -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 /* Build the result of __builtin_offsetof. EXPR is a nested sequence of
component references, with an INDIRECT_REF at the bottom; much like component references, with STOP_REF, or alternatively an INDIRECT_REF of
the traditional rendering of offsetof as a macro. Returns the folded NULL, at the bottom; much like the traditional rendering of offsetof as a
and properly cast result. */ macro. Returns the folded and properly cast result. */
static tree static tree
fold_offsetof_1 (tree expr) fold_offsetof_1 (tree expr, tree stop_ref)
{ {
enum tree_code code = PLUS_EXPR; enum tree_code code = PLUS_EXPR;
tree base, off, t; tree base, off, t;
if (expr == stop_ref && TREE_CODE (expr) != ERROR_MARK)
return size_zero_node;
switch (TREE_CODE (expr)) switch (TREE_CODE (expr))
{ {
case ERROR_MARK: case ERROR_MARK:
@ -6001,11 +6004,22 @@ fold_offsetof_1 (tree expr)
error ("cannot apply %<offsetof%> to static data member %qD", expr); error ("cannot apply %<offsetof%> to static data member %qD", expr);
return error_mark_node; 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; 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: 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) if (base == error_mark_node)
return base; return base;
@ -6022,7 +6036,7 @@ fold_offsetof_1 (tree expr)
break; break;
case ARRAY_REF: 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) if (base == error_mark_node)
return base; return base;
@ -6044,10 +6058,10 @@ fold_offsetof_1 (tree expr)
} }
tree tree
fold_offsetof (tree expr) fold_offsetof (tree expr, tree stop_ref)
{ {
/* Convert back from the internal sizetype to size_t. */ /* 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 /* Print an error message for an invalid lvalue. USE says

View File

@ -830,7 +830,7 @@ extern void c_warn_unused_result (tree *);
extern void verify_sequence_points (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. /* Places where an lvalue, or modifiable lvalue, may be required.
Used to select diagnostic messages in lvalue_error and Used to select diagnostic messages in lvalue_error and

View File

@ -5203,7 +5203,7 @@ c_parser_postfix_expression (c_parser *parser)
if (type == error_mark_node) if (type == error_mark_node)
offsetof_ref = error_mark_node; offsetof_ref = error_mark_node;
else 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 /* Parse the second argument to __builtin_offsetof. We
must have one identifier, and beyond that we want to must have one identifier, and beyond that we want to
accept sub structure and sub array references. */ 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_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>"); "expected %<)%>");
expr.value = fold_offsetof (offsetof_ref); expr.value = fold_offsetof (offsetof_ref, NULL_TREE);
expr.original_code = ERROR_MARK; expr.original_code = ERROR_MARK;
} }
break; break;

View File

@ -3057,7 +3057,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
if (val && TREE_CODE (val) == INDIRECT_REF if (val && TREE_CODE (val) == INDIRECT_REF
&& TREE_CONSTANT (TREE_OPERAND (val, 0))) && 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)); op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
return fold_build2 (PLUS_EXPR, argtype, op0, op1); return fold_build2 (PLUS_EXPR, argtype, op0, op1);

View File

@ -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> 2006-08-16 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/28302 PR c++/28302
* typeck.c (build_unary_op <case BIT_NOT_EXPR:>): Don't call * 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> 2006-08-16 Jason Merrill <jason@redhat.com>

View File

@ -2904,7 +2904,7 @@ finish_offsetof (tree expr)
error ("cannot apply %<offsetof%> to member function %qD", expr); error ("cannot apply %<offsetof%> to member function %qD", expr);
return error_mark_node; 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 /* Called from expand_body via walk_tree. Replace all AGGR_INIT_EXPRs

View File

@ -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> 2006-08-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR testsuite/28602 PR testsuite/28602
@ -6,7 +13,7 @@
2006-08-16 Andrew Pinski <pinskia@physics.uc.edu> 2006-08-16 Andrew Pinski <pinskia@physics.uc.edu>
PR C++/28302 PR c++/28302
* g++.dg/ext/vector3.C: New test. * g++.dg/ext/vector3.C: New test.
2006-08-16 Zdenek Dvorak <dvorakz@suse.cz> 2006-08-16 Zdenek Dvorak <dvorakz@suse.cz>

View File

@ -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" } */
}

View File

@ -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" } */
}