https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113599

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem is in that typeck2.cc change:
-      datum = fold_build_pointer_plus (fold_convert (ptype, datum),
component);
+      datum = cp_convert (ptype, datum, complain);
+      if (!processing_template_decl)
+       datum = build2 (POINTER_PLUS_EXPR, ptype,
+                       datum, convert_to_ptrofftype (component));
datum is &d and ptype is A * from the #c1 testcase.
So, previously, we would correctly build (and fold) a POINTER_PLUS_EXPR of
(A *) &d and (sizetype) e (where e is 16, offsetof C::c in C).
But, because C has A base, cp_convert of &d to A * doesn't create (A *) &d, but
returns &d.D.2800 where D.2800 is the A base in C, which is at offset 8 in the
structure.  If we add to that 16, we get something at offset 24 rather than the
offset 16.
I understand the desire to get some error checking on the pointer to pointer
conversion, but cp_convert in this case calls cp_convert_pointer which does the
base lookups and build_base_path etc.
If no checking is needed, then it could be just datum = build_nop (ptype,
datum);
if we don't want folding.

Reply via email to