re PR c++/13009 (Implicitly-defined assignment operator writes to wrong memory)
PR c++/13009 * call.c (build_special_member_call): Do not assume that we have a pointer to the complete object in an assignment operator. PR c++/13009 * g++.dg/init/assign1.C: New test. From-SVN: r75189
This commit is contained in:
parent
6c5d63c80b
commit
4c2a4b907d
@ -1,3 +1,9 @@
|
||||
2003-12-28 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/13009
|
||||
* call.c (build_special_member_call): Do not assume that we have a
|
||||
pointer to the complete object in an assignment operator.
|
||||
|
||||
2003-12-28 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR c++/13070
|
||||
|
@ -4865,14 +4865,23 @@ build_special_member_call (tree instance, tree name, tree args,
|
||||
|| name == deleting_dtor_identifier)
|
||||
my_friendly_assert (args == NULL_TREE, 20020712);
|
||||
|
||||
/* We must perform the conversion here so that we do not
|
||||
subsequently check to see whether BINFO is an accessible
|
||||
base. (It is OK for a constructor to call a constructor in
|
||||
an inaccessible base as long as the constructor being called
|
||||
is accessible.) */
|
||||
/* Convert to the base class, if necessary. */
|
||||
if (!same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (instance), BINFO_TYPE (binfo)))
|
||||
instance = convert_to_base_statically (instance, binfo);
|
||||
{
|
||||
if (name != ansi_assopname (NOP_EXPR))
|
||||
/* For constructors and destructors, either the base is
|
||||
non-virtual, or it is virtual but we are doing the
|
||||
conversion from a constructor or destructor for the
|
||||
complete object. In either case, we can convert
|
||||
statically. */
|
||||
instance = convert_to_base_statically (instance, binfo);
|
||||
else
|
||||
/* However, for assignment operators, we must convert
|
||||
dynamically if the base is virtual. */
|
||||
instance = build_base_path (PLUS_EXPR, instance,
|
||||
binfo, /*nonnull=*/1);
|
||||
}
|
||||
}
|
||||
|
||||
my_friendly_assert (instance != NULL_TREE, 20020712);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-12-28 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/13009
|
||||
* g++.dg/init/assign1.C: New test.
|
||||
|
||||
2003-12-28 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR c++/13070
|
||||
|
30
gcc/testsuite/g++.dg/init/assign1.C
Normal file
30
gcc/testsuite/g++.dg/init/assign1.C
Normal file
@ -0,0 +1,30 @@
|
||||
// PR c++/13009
|
||||
// { dg-do run }
|
||||
|
||||
struct A {
|
||||
char a;
|
||||
};
|
||||
|
||||
struct B: public virtual A {
|
||||
#if 0 // this piece of code works around the problem
|
||||
B& operator= (const B& other)
|
||||
{
|
||||
A::operator= (other);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct C: public B {
|
||||
char c;
|
||||
};
|
||||
|
||||
int main() {
|
||||
B b;
|
||||
b.a = 'b';
|
||||
C c;
|
||||
c.a = c.c = 'c';
|
||||
|
||||
c.B::operator= (b);
|
||||
if (c.a != 'b' || c.c != 'c')
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user