Commit d794ab85 by Nathan Sidwell Committed by Nathan Sidwell

[PR c++/87531] operator= lookup in templates

https://gcc.gnu.org/ml/gcc-patches/2018-11/msg02301.html
	PR c++/87531
	* class.c (finish_struct): In a template, add artificial using
	decl for operator=.

	* g++.dg/lookup/pr87531.C: New.

From-SVN: r266590
parent 410902c3
2018-11-28 Nathan Sidwell <nathan@acm.org>
PR c++/87531
* class.c (finish_struct): In a template, add artificial using
decl for operator=.
2018-11-28 Jan Hubicka <hubicka@ucw.cz>
* except.c (do_allocate_exception): Annotate __cxa_allocate_exception
......
......@@ -7150,6 +7150,19 @@ finish_struct (tree t, tree attributes)
else if (DECL_DECLARES_FUNCTION_P (x))
DECL_IN_AGGR_P (x) = false;
/* Also add a USING_DECL for operator=. We know there'll be (at
least) one, but we don't know the signature(s). We want name
lookup not to fail or recurse into bases. This isn't added
to the template decl list so we drop this at instantiation
time. */
tree ass_op = build_lang_decl (USING_DECL, assign_op_identifier,
NULL_TREE);
USING_DECL_SCOPE (ass_op) = t;
DECL_DEPENDENT_P (ass_op) = true;
DECL_ARTIFICIAL (ass_op) = true;
DECL_CHAIN (ass_op) = TYPE_FIELDS (t);
TYPE_FIELDS (t) = ass_op;
TYPE_SIZE (t) = bitsize_zero_node;
TYPE_SIZE_UNIT (t) = size_zero_node;
/* COMPLETE_TYPE_P is now true. */
......
2018-11-28 Nathan Sidwell <nathan@acm.org>
PR c++/87531
* g++.dg/lookup/pr87531.C: New.
2018-11-28 Jan Hubicka <jh@suse.cz>
* gcc.dg/predict-13.c: Update template.
......
// PR c+/87531 lookup of operator= in templates
// { dg-do run }
struct Base {
void operator= (Base const&);
};
void Base::operator= (Base const &)
{
}
template <typename T>
struct Derived : Base
{
T v;
Derived() : v (0) {}
Derived(T v_) : v (v_) {}
T &assign1 (Derived const& rhs)
{
operator=(rhs); // erroneously bound to Base::operator=
return v;
}
T &assign2 (Derived const& rhs)
{
this->operator=(rhs); // erroneously bound to Base::operator=
return v;
}
};
template <typename T>
struct Single
{
T v;
Single () : v (0) {}
Single (T v_) : v (v_) {}
T &assign1 (Single const& rhs)
{
operator=(rhs); // lookup failed
return v;
}
T &assign2 (Single const& rhs)
{
this->operator=(rhs); // Marked as dependent, happened to work
return v;
}
};
int main()
{
Derived<int> a, b(123);
if (a.assign1 (b) != 123)
return 1;
if (a.assign2 (b) != 123)
return 2;
Single<int> c, d(123);
if (c.assign1 (d) != 123)
return 3;
if (c.assign2 (d) != 123)
return 4;
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment