[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:
parent
e98a430b85
commit
6d4d7b0eed
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
19
gcc/testsuite/g++.dg/parse/offsetof6.C
Normal file
19
gcc/testsuite/g++.dg/parse/offsetof6.C
Normal 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" } */
|
||||||
|
}
|
18
gcc/testsuite/g++.dg/parse/offsetof7.C
Normal file
18
gcc/testsuite/g++.dg/parse/offsetof7.C
Normal 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" } */
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user