From 2eea0b952ee983bad04e646794eaafe6cfc7ba71 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 9 Nov 2017 14:31:31 -0500
Subject: [PATCH 22/25] {[14/14], approved} pp_c_cast_expression: don't print
 casts for location wrappers

This patch suppresses the user-visible printing of location wrappers
for "%E" (and "%qE"), adding test coverage via selftests.

Seen via a failure of g++.dg/parse/error34.C and g++.dg/parse/error35.C.

gcc/c-family/ChangeLog:
	* c-common.c (selftest::c_family_tests): Call
	selftest::c_pretty_print_c_tests.
	* c-common.h (selftest::c_pretty_print_c_tests): New decl.
	* c-pretty-print.c: Include "selftest.h".
	(pp_c_cast_expression): Don't print casts for location wrappers.
	(selftest::assert_c_pretty_printer_output): New function.
	(ASSERT_C_PRETTY_PRINTER_OUTPUT): New macro.
	(selftest::test_location_wrappers): New function.
	(selftest::c_pretty_print_c_tests): New function.
---
 gcc/c-family/c-common.c       |  1 +
 gcc/c-family/c-common.h       |  1 +
 gcc/c-family/c-pretty-print.c | 66 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index dc4aa17..3438b87 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -8179,6 +8179,7 @@ void
 c_family_tests (void)
 {
   c_format_c_tests ();
+  c_pretty_print_c_tests ();
   c_spellcheck_cc_tests ();
 }
 
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index d9bf8d0..df68913 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1450,6 +1450,7 @@ namespace selftest {
   /* Declarations for specific families of tests within c-family,
      by source file, in alphabetical order.  */
   extern void c_format_c_tests (void);
+  extern void c_pretty_print_c_tests (void);
   extern void c_spellcheck_cc_tests (void);
 
   /* The entrypoint for running all of the above tests.  */
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index de5ab4b..53d33af 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "intl.h"
 #include "tree-pretty-print.h"
+#include "selftest.h"
 
 /* The pretty-printer code is primarily designed to closely follow
    (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
@@ -1808,7 +1809,8 @@ pp_c_cast_expression (c_pretty_printer *pp, tree e)
     case FIX_TRUNC_EXPR:
     CASE_CONVERT:
     case VIEW_CONVERT_EXPR:
-      pp_c_type_cast (pp, TREE_TYPE (e));
+      if (!location_wrapper_p (e))
+	pp_c_type_cast (pp, TREE_TYPE (e));
       pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
       break;
 
@@ -2399,3 +2401,65 @@ pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
 
   pp_c_identifier (pp, name);
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Selftests for pretty-printing trees.  */
+
+/* Verify that EXPR printed by c_pretty_printer is EXPECTED, using
+   LOC as the effective location for any failures.  */
+
+static void
+assert_c_pretty_printer_output (const location &loc, const char *expected,
+				tree expr)
+{
+  c_pretty_printer pp;
+  pp.expression (expr);
+  ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
+}
+
+/* Helper function for calling assert_c_pretty_printer_output.
+   This is to avoid having to write SELFTEST_LOCATION.  */
+
+#define ASSERT_C_PRETTY_PRINTER_OUTPUT(EXPECTED, EXPR) \
+  SELFTEST_BEGIN_STMT						\
+    assert_c_pretty_printer_output ((SELFTEST_LOCATION),	\
+				    (EXPECTED),		\
+				    (EXPR));			\
+  SELFTEST_END_STMT
+
+/* Verify that location wrappers don't show up in pretty-printed output.  */
+
+static void
+test_location_wrappers ()
+{
+  /* VAR_DECL.  */
+  tree id = get_identifier ("foo");
+  tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+			  integer_type_node);
+  tree wrapped_decl = maybe_wrap_with_location (decl, BUILTINS_LOCATION);
+  ASSERT_NE (wrapped_decl, decl);
+  ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", decl);
+  ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", wrapped_decl);
+
+  /* INTEGER_CST.  */
+  tree int_cst = build_int_cst (integer_type_node, 42);
+  tree wrapped_cst = maybe_wrap_with_location (int_cst, BUILTINS_LOCATION);
+  ASSERT_NE (wrapped_cst, int_cst);
+  ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", int_cst);
+  ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", wrapped_cst);
+}
+
+/* Run all of the selftests within this file.  */
+
+void
+c_pretty_print_c_tests ()
+{
+  test_location_wrappers ();
+}
+
+} // namespace selftest
+
+#endif /* CHECKING_P */
-- 
1.8.5.3

