+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
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.
--- /dev/null
+// 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;
+}