On 3/15/22 08:32, Jakub Jelinek wrote:
On Fri, Feb 11, 2022 at 12:27:49PM -0500, Jason Merrill wrote:
Yes, that's what the above code would correctly do if TYPE were the
pointer-to-method type. It's wrong for this case because TYPE is unrelated
to TREE_TYPE (field).
I think the problem is just this line:
if (tree ret = c_fold_indirect_ref_for_warn (loc, type, cop,
off))
return ret;
return cop;
^^^^^^^^^^
The recursive call does the proper type checking, but then the "return cop"
line returns the COMPONENT_REF even though the type check failed. The
parallel code in cxx_fold_indirect_ref_1 doesn't have this line, and
removing it fixes the testcase, so I see
warning: ‘*(ptrmemfunc*)&x.ptrmemfunc::ptr’ is used uninitialized
The intent of r11-6729 is that it prints something that helps user to figure
out what exactly is being accessed.
When we find a unique non-static data member that is being accessed, even
when we can't fold it nicely, IMNSHO it is better to print
((sometype *)&var)->field
or
(*(sometype *)&var).field
instead of
*(fieldtype *)((char *)&var + 56)
because the user doesn't know what is at offset 56, we shouldn't ask user
to decipher structure layout etc.
The problem is that the reference is *not* to any non-static data
member, it's to the PMF as a whole. But c_fold_indirect_ref_for_warn
wrongly turns it into a reference to the first non-static data member.
We asked c_fold_indirect_ref_warn to fold a MEM_REF with RECORD_TYPE,
and it gave us back a COMPONENT_REF with POINTER_TYPE. That seems
clearly wrong.
One question is if we could return something better for the TYPE_PTRMEMFUNC_FLAG
RECORD_TYPE members here (something that would print it more naturally/readably
in a C++ way), though the fact that the routine is in c-family makes it
harder.
Another one is whether we shouldn't punt for FIELD_DECLs that don't have
nicely printable name of its containing scope, something like:
if (tree scope = get_containing_scope (field))
if (TYPE_P (scope) && TYPE_NAME (scope) == NULL_TREE)
break;
return cop;
or so.
Note the returned cop is a COMPONENT_REF where the first argument has a
nicely printable type name (x with type sp), but sp's TYPE_MAIN_VARIANT
is the unnamed TYPE_PTRMEMFUNC_FLAG. So another possibility would be if
we see such a problem for the FIELD_DECL's scope, check if TYPE_MAIN_VARIANT
of the first COMPONENT_REF's argument is equal to that scope and in that
case use TREE_TYPE of the first COMPONENT_REF's argument as the scope
instead.
Jakub