c-family: Improve MEM_REF printing for diagnostics [PR98597]
authorJakub Jelinek <jakub@redhat.com>
Fri, 15 Jan 2021 18:20:29 +0000 (19:20 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 15 Jan 2021 18:21:58 +0000 (19:21 +0100)
commitadb520606ce3e1e1f8aa8c5d0c59a5f3196fc545
treeca46d32785edc12fda0caeed41757b29e56f73ac
parent50dbced2f37ba9c4b9756c523a7a06b036151d2d
c-family: Improve MEM_REF printing for diagnostics [PR98597]

Ok, here is an updated patch which fixes what I found, and implements what
has been discussed on the mailing list and on IRC, i.e. if the types
are compatible as well as alias sets are same, then it prints
what c_fold_indirect_ref_for_warn managed to create, otherwise it uses
that info for printing offsets using offsetof (except when it starts
with ARRAY_REFs, because one can't have offsetof (struct T[2][2], [1][0].x.y)

The uninit-38.c test (which was the only one I believe which had tests on the
exact spelling of MEM_REF printing) contains mainly changes to have space
before * for pointer types (as that is how the C pretty-printers normally
print types, int * rather than int*), plus what might be considered a
regression from what Martin printed, but it is actually a correctness fix.

When the arg is a pointer with type pointer to VLA with char element type
(let's say the pointer is p), which is what happens in several of the
uninit-38.c tests, omitting the (char *) cast is incorrect, as p + 1
is not the 1 byte after p, but pointer to the end of the VLA.
It only happened to work because of the hacks (which I don't like at all
and are dangerous, DECL_ARTIFICIAL var names with dot inside can be pretty
much anything, e.g. a lot of passes construct their helper vars from some
prefix that designates intended use of the var plus numeric suffix), where
the a.1 pointer to VLA is printed as a which if one is lucky happens to be
a variable with VLA type (rather than pointer to it), and for such vars
a + 1 is indeed &a[0] + 1 rather than &a + 1.  But if we want to do this
reliably, we'd need to make sure it comes from VLA (e.g. verify that the
SSA_NAME is defined to __builtin_alloca_with_align and that there exists
a corresponding VAR_DECL with DECL_VALUE_EXPR that has the a.1 variable
in it).

2021-01-15  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/98597
* c-pretty-print.c: Include options.h.
(c_fold_indirect_ref_for_warn): New function.
(print_mem_ref): Use it.  If it returns something that has compatible
type and is TBAA compatible with zero offset, print it and return,
otherwise print it using offsetof syntax or array ref syntax.  Fix up
printing if MEM_REFs first operand is ADDR_EXPR, or when the first
argument has pointer to array type.  Print pointers using the standard
formatting.

* gcc.dg/uninit-38.c: Expect a space in between type name and asterisk.
Expect for now a (char *) cast for VLAs.
* gcc.dg/uninit-40.c: New test.
gcc/c-family/c-pretty-print.c
gcc/testsuite/gcc.dg/uninit-38.c
gcc/testsuite/gcc.dg/uninit-40.c [new file with mode: 0644]