This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: CVS head build breakage for target sh-elf
- From: Jason Merrill <jason at redhat dot com>
- To: Hans-Peter Nilsson <hp at bitrange dot com>
- Cc: tm <tm at mail dot kloo dot net>, <gcc-bugs at gcc dot gnu dot org>,Mark Mitchell <mark at codesourcery dot com>,Jason Merrill <jason at redhat dot com>
- Date: Tue, 06 Aug 2002 23:43:16 +0100
- Subject: Re: CVS head build breakage for target sh-elf
- References: <Pine.BSF.4.30.0208051817020.85052-100000@dair.pair.com>
On Mon, 5 Aug 2002 18:40:09 -0400 (EDT), Hans-Peter Nilsson <hp@bitrange.com> wrote:
> On Mon, 5 Aug 2002, tm wrote:
>> It looks like some change within the last week has broken the sh-elf
>> target for C++?
>
> I see this on mmix-knuth-mmixware too; the abort in the newly
> introduced cp_expr_size trigs. I thought this would be seen on
> all newlib targets (and soon fixed), but the regression checker
> doesn't seem to mind. I haven't tried the regression checker
> targets myself due to insufficient resources at the moment.
>
> Jason, as the cp_expr_size author, could you please have a look?
> I have trouble grokking those C++-trees.
Interesting. The problem seems to be as follows:
C++ uses TARGET_EXPR to represent creating a new temporary object. When
expanding the TARGET_EXPR, we call store_expr to store the value of the
initializer into the slot we've chosen for the temporary. store_expr deals
with this in general by expanding the initializer, and then, if it didn't
expand directly into the target slot, copying it over.
In C++, types with copy constructors must not be copied by the backend; any
copies must go through a constructor. We set TREE_ADRESSABLE on the type
to indicate this. So the initializer for a TARGET_EXPR of such a type must
expand directly into the target slot.
In this case, the initializer is an inlined call to a function which
returns a value of the appropriate type. The tree inliner expands the
function into something like ({ ....; slot; }). The result of this
statement-expression is the result of just expanding "slot", indicating to
store_expr that no extra copying is necessary.
Except that this doesn't work if DECL_RTL (slot) isn't a valid MEM, as can
happen on targets with limited base-offset addressing, such as the SH. In
the testcase below, the rtl for the slot is
(mem/s:BLK (plus:SI (reg/f:SI 154 virtual-stack-vars)
(const_int 400 [0x190])) [0 A32])
but the return value from expand_expr is
(mem/s:BLK (reg/f:SI 164) [0 A32])
These two forms happen to be equivalent, but store_expr doesn't know this,
so it tries to copy between them. This triggers the abort in cp_expr_size,
as the backend isn't supposed to copy this type. In this case the copy
wouldn't do any harm, since the source and target are equivalent, but we
have no way of knowing that.
I'm thinking to tweak c_expand_expr to just return target in this case; I
have a patch in testing now.
Here's a much smaller testcase:
struct A {
A();
A(const A&);
A& operator=(const A&);
};
inline A f () { return A(); }
void g (const A&);
int main ()
{
int pad[20];
g (f ());
}
Jason