{
/* Retain the type if we know the operand is a pointer. */
if (TREE_TYPE (expr) && INDIRECT_TYPE_P (TREE_TYPE (expr)))
- return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
+ {
+ if (expr == current_class_ptr
+ || (TREE_CODE (expr) == NOP_EXPR
+ && TREE_OPERAND (expr, 0) == current_class_ptr
+ && (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (expr), TREE_TYPE (current_class_ptr)))))
+ return current_class_ref;
+ return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
+ }
if (type_dependent_expression_p (expr))
return build_min_nt_loc (loc, INDIRECT_REF, expr);
expr = build_non_dependent_expr (expr);
--- /dev/null
+// PR c++/98841
+// { dg-do compile }
+// { dg-options "-Weffc++" }
+
+struct S {
+ template <typename T>
+ S& operator=(const T&) { return *this; } // { dg-bogus "should return a reference to" }
+ S& operator=(const S&) { return *this; }
+};
+
+void
+foo ()
+{
+ S s, t;
+ s = 1;
+ s = t;
+}