Re: [PATCH v3] handle MEM_REF with void* arguments (PR c++/95768)

2021-01-07 Thread Martin Sebor via Gcc-patches

On 1/7/21 1:26 AM, Jakub Jelinek wrote:

On Sat, Jan 02, 2021 at 03:22:25PM -0700, Martin Sebor via Gcc-patches wrote:

PR c++/95768 - pretty-printer ICE on -Wuninitialized with allocated storage

gcc/c-family/ChangeLog:

PR c++/95768
* c-pretty-print.c (c_pretty_printer::primary_expression): For
SSA_NAMEs print VLA names and GIMPLE defining statements.
(print_mem_ref): New function.
(c_pretty_printer::unary_expression): Call it.


This broke:
+FAIL: gcc.dg/plugin/gil-1.c -fplugin=./analyzer_gil_plugin.so  (test for 
warnings, line 16)
+FAIL: gcc.dg/plugin/gil-1.c -fplugin=./analyzer_gil_plugin.so  (test for 
warnings, line 63)
+FAIL: gcc.dg/plugin/gil-1.c -fplugin=./analyzer_gil_plugin.so (test for excess 
errors)
and
+FAIL: g++.dg/cpp0x/constexpr-trivial2.C  -std=c++11  (test for errors, line 13)
+FAIL: g++.dg/cpp0x/constexpr-trivial2.C  -std=c++11 (test for excess errors)
The former one is just a different printing of the MEM_REF from what the
test expects, but the latter is an ICE (one needs
make check-c++-all RUNTESTFLAGS=dg.exp=constexpr-trivial2.C
to reproduce or GXX_TESTSUITE_STDS=11 or similar as C++11 is not tested by
default).


I saw the gcc.dg/plugin/gil-1.c failure but missed the subtle difference
in the output.  Rerunning the test didn't show any failures so I assumed
it was something transient.  But when I tried gain today and looked more
carefully at the output I saw the test doesn't run at all by itself.
This doesn't work:

 $ nice make -C /ssd/test/build/gcc-95768/gcc check-c 
RUNTESTFLAGS="plugin.exp=gil-1.c"


Is there some special magic to get it to run by itself or do these
tests just not do that?

Running all the plugin tests does work but also shows the failures
below that don't show up in the final summary (or on gcc-testresults).
I assume those are unrelated (I think I've seen this test fail in
a similarly mysterious way before).

FAIL: gcc.dg/plugin/diagnostic-test-expressions-1.c 
-fplugin=./diagnostic_plugin_test_tree_expression_range.so  1 blank 
line(s) in output
FAIL: gcc.dg/plugin/diagnostic-test-expressions-1.c 
-fplugin=./diagnostic_plugin_test_tree_expression_range.so  expected 
multiline pattern lines 550-551 not found: " 
__builtin_types_compatible_p \(long, int\) \+ f \(i\)\);.*\n 
   ~\^~~\n"
FAIL: gcc.dg/plugin/diagnostic-test-expressions-1.c 
-fplugin=./diagnostic_plugin_test_tree_expression_range.so (test for 
excess errors)


Martin

PS I committed a fix for both the ICE and the gil-1.c failure
in r11-6532.


Re: [PATCH v3] handle MEM_REF with void* arguments (PR c++/95768)

2021-01-07 Thread Jakub Jelinek via Gcc-patches
On Sat, Jan 02, 2021 at 03:22:25PM -0700, Martin Sebor via Gcc-patches wrote:
> PR c++/95768 - pretty-printer ICE on -Wuninitialized with allocated storage
> 
> gcc/c-family/ChangeLog:
> 
>   PR c++/95768
>   * c-pretty-print.c (c_pretty_printer::primary_expression): For
>   SSA_NAMEs print VLA names and GIMPLE defining statements.
>   (print_mem_ref): New function.
>   (c_pretty_printer::unary_expression): Call it.

This broke:
+FAIL: gcc.dg/plugin/gil-1.c -fplugin=./analyzer_gil_plugin.so  (test for 
warnings, line 16)
+FAIL: gcc.dg/plugin/gil-1.c -fplugin=./analyzer_gil_plugin.so  (test for 
warnings, line 63)
+FAIL: gcc.dg/plugin/gil-1.c -fplugin=./analyzer_gil_plugin.so (test for excess 
errors)
and
+FAIL: g++.dg/cpp0x/constexpr-trivial2.C  -std=c++11  (test for errors, line 13)
+FAIL: g++.dg/cpp0x/constexpr-trivial2.C  -std=c++11 (test for excess errors)
The former one is just a different printing of the MEM_REF from what the
test expects, but the latter is an ICE (one needs
make check-c++-all RUNTESTFLAGS=dg.exp=constexpr-trivial2.C
to reproduce or GXX_TESTSUITE_STDS=11 or similar as C++11 is not tested by
default).

Jakub



Re: [PATCH v3] handle MEM_REF with void* arguments (PR c++/95768)

2021-01-05 Thread Jeff Law via Gcc-patches



On 1/2/21 3:22 PM, Martin Sebor via Gcc-patches wrote:
> Attached is another revision of a patch I posted last July to keep
> the pretty-printer from crashing on MEM_REFs with void* arguments:
>   https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549746.html
>
> Besides avoiding the ICE and enhancing the MEM_REF detail and
> improving its format, this revision implements the suggestions
> in that discussion.  To avoid code duplication it moves
> the handling to the C pretty-printer and changes the C++ front
> end to delegate to it.  In addition, it includes a cast to
> the accessed type if it's different from/incompatible with
> (according to GIMPLE) that of the dereferenced pointer, or if
> the object is typeless.  Lastly, it replaces the  in
> the output with either VLA names or the RHS of the GIMPLE
> expression (this improves the output when for dynamically
> allocated objects).
>
> As an aside, In my experience, MEM_REFs in warnings are limited
> to -Wuninitialized.  I think other middle end warnings tend to
> avoid them.  Those that involve invalid/out-of-bounds accesses
> replace them with either the target DECL (e.g., local variable,
> or FIELD_DECL), the allocation call (e.g., malloc), or the DECL
> of the pointer (e.g., PARM_DECL), followed by a note mentioning
> the offset into the object.  I'd like to change -Wuninitialized
> at some point to follow the same style.  So I see the value of
> the MEM_REF formatting enhancement mainly as a transient solution
> until that happens.
>
> Martin
>
> gcc-95768.diff
>
> PR c++/95768 - pretty-printer ICE on -Wuninitialized with allocated storage
>
> gcc/c-family/ChangeLog:
>
>   PR c++/95768
>   * c-pretty-print.c (c_pretty_printer::primary_expression): For
>   SSA_NAMEs print VLA names and GIMPLE defining statements.
>   (print_mem_ref): New function.
>   (c_pretty_printer::unary_expression): Call it.
>
> gcc/cp/ChangeLog:
>
>   PR c++/95768
>   * error.c (dump_expr): Call c_pretty_printer::unary_expression.
>
> gcc/testsuite/ChangeLog:
>
>   PR c++/95768
>   * g++.dg/pr95768.C: New test.
>   * g++.dg/warn/Wuninitialized-12.C: New test.
>   * gcc.dg/uninit-38.c: New test.
OK
jeff



[PATCH v3] handle MEM_REF with void* arguments (PR c++/95768)

2021-01-02 Thread Martin Sebor via Gcc-patches

Attached is another revision of a patch I posted last July to keep
the pretty-printer from crashing on MEM_REFs with void* arguments:
  https://gcc.gnu.org/pipermail/gcc-patches/2020-July/549746.html

Besides avoiding the ICE and enhancing the MEM_REF detail and
improving its format, this revision implements the suggestions
in that discussion.  To avoid code duplication it moves
the handling to the C pretty-printer and changes the C++ front
end to delegate to it.  In addition, it includes a cast to
the accessed type if it's different from/incompatible with
(according to GIMPLE) that of the dereferenced pointer, or if
the object is typeless.  Lastly, it replaces the  in
the output with either VLA names or the RHS of the GIMPLE
expression (this improves the output when for dynamically
allocated objects).

As an aside, In my experience, MEM_REFs in warnings are limited
to -Wuninitialized.  I think other middle end warnings tend to
avoid them.  Those that involve invalid/out-of-bounds accesses
replace them with either the target DECL (e.g., local variable,
or FIELD_DECL), the allocation call (e.g., malloc), or the DECL
of the pointer (e.g., PARM_DECL), followed by a note mentioning
the offset into the object.  I'd like to change -Wuninitialized
at some point to follow the same style.  So I see the value of
the MEM_REF formatting enhancement mainly as a transient solution
until that happens.

Martin
PR c++/95768 - pretty-printer ICE on -Wuninitialized with allocated storage

gcc/c-family/ChangeLog:

	PR c++/95768
	* c-pretty-print.c (c_pretty_printer::primary_expression): For
	SSA_NAMEs print VLA names and GIMPLE defining statements.
	(print_mem_ref): New function.
	(c_pretty_printer::unary_expression): Call it.

gcc/cp/ChangeLog:

	PR c++/95768
	* error.c (dump_expr): Call c_pretty_printer::unary_expression.

gcc/testsuite/ChangeLog:

	PR c++/95768
	* g++.dg/pr95768.C: New test.
	* g++.dg/warn/Wuninitialized-12.C: New test.
	* gcc.dg/uninit-38.c: New test.

diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 3027703056b..3a3f2f7bdcc 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "c-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "diagnostic.h"
 #include "stor-layout.h"
 #include "stringpool.h"
@@ -1334,6 +1335,34 @@ c_pretty_printer::primary_expression (tree e)
   pp_c_right_paren (this);
   break;
 
+case SSA_NAME:
+  if (SSA_NAME_VAR (e))
+	{
+	  tree var = SSA_NAME_VAR (e);
+	  const char *name = IDENTIFIER_POINTER (SSA_NAME_IDENTIFIER (e));
+	  const char *dot;
+	  if (DECL_ARTIFICIAL (var) && (dot = strchr (name, '.')))
+	{
+	  /* Print the name without the . suffix (such as in VLAs).
+		 Use pp_c_identifier so that it can be converted into
+		 the appropriate encoding.  */
+	  size_t size = dot - name;
+	  char *ident = XALLOCAVEC (char, size + 1);
+	  memcpy (ident, name, size);
+	  ident[size] = '\0';
+	  pp_c_identifier (this, ident);
+	}
+	  else
+	primary_expression (var);
+	}
+  else
+	{
+	  /* Print only the right side of the GIMPLE assignment.  */
+	  gimple *def_stmt = SSA_NAME_DEF_STMT (e);
+	  pp_gimple_stmt_1 (this, def_stmt, 0, TDF_RHS_ONLY);
+	}
+  break;
+
 default:
   /* FIXME:  Make sure we won't get into an infinite loop.  */
   if (location_wrapper_p (e))
@@ -1780,6 +1809,139 @@ pp_c_call_argument_list (c_pretty_printer *pp, tree t)
   pp_c_right_paren (pp);
 }
 
+/* Print the MEM_REF expression REF, including its type and offset.
+   Apply casts as necessary if the type of the access is different
+   from the type of the accessed object.  Produce compact output
+   designed to include both the element index as well as any
+   misalignment by preferring
+ ((int*)((char*)p + 1))[2]
+   over
+ *(int*)((char*)p + 9)
+   The former is more verbose but makes it clearer that the access
+   to the third element of the array is misaligned by one byte.  */
+
+static void
+print_mem_ref (c_pretty_printer *pp, tree e)
+{
+  tree arg = TREE_OPERAND (e, 0);
+
+  /* The byte offset.  Initially equal to the MEM_REF offset, then
+ adjusted to the remainder of the division by the byte size of
+ the access.  */
+  offset_int byte_off = wi::to_offset (TREE_OPERAND (e, 1));
+  /* The result of dividing BYTE_OFF by the size of the access.  */
+  offset_int elt_idx = 0;
+  /* True to include a cast to char* (for a nonzero final BYTE_OFF).  */
+  bool char_cast = false;
+  const bool addr = TREE_CODE (arg) == ADDR_EXPR;
+  if (addr)
+{
+  arg = TREE_OPERAND (arg, 0);
+  if (byte_off == 0)
+	{
+	  pp->expression (arg);
+	  return;
+	}
+}
+
+  const tree access_type = TREE_TYPE (e);
+  tree arg_type = TREE_TYPE (TREE_TYPE (arg));
+  if (TREE_CODE (arg_type) == ARRAY_TYPE)
+arg_type = TREE_TYPE (arg_type);
+
+