From a0f51e7d40d08971091b51ee975471b9ef892154 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 23 Nov 2015 23:45:17 -0500
Subject: [PATCH 11/35] FIXME: more WIP

---
 gcc/cp/call.c                                        |  3 +++
 gcc/cp/constexpr.c                                   |  7 ++++++-
 gcc/cp/cp-gimplify.c                                 |  9 ++++++++-
 gcc/cp/cp-objcp-common.c                             |  1 -
 gcc/cp/error.c                                       |  4 ++++
 gcc/cp/parser.c                                      | 20 +++++++++++++++-----
 gcc/cp/tree.c                                        |  1 +
 gcc/cp/typeck.c                                      |  2 ++
 .../g++.dg/plugin/diagnostic-test-expressions-1.c    |  2 +-
 9 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7794a96..623c2ef 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1087,6 +1087,9 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   bool fromref = false;
   tree qualified_to;
 
+  if (expr)
+    STRIP_LOCATION_EXPRS (expr);
+
   to = non_reference (to);
   if (TREE_CODE (from) == REFERENCE_TYPE)
     {
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 9e4da1d..1115403 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1460,6 +1460,9 @@ reduced_constant_expression_p (tree t)
 	  return false;
       return true;
 
+    case LOCATION_EXPR:
+      return reduced_constant_expression_p (TREE_OPERAND (t, 0));
+
     default:
       /* FIXME are we calling this too much?  */
       return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
@@ -1479,6 +1482,8 @@ static bool
 verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
 		 bool *overflow_p)
 {
+  t = cp_fully_fold (t);
+
   if (!*non_constant_p && !reduced_constant_expression_p (t))
     {
       if (!allow_non_constant)
@@ -3590,7 +3595,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	if (op == oldop && tcode != UNARY_PLUS_EXPR)
 	  /* We didn't fold at the top so we could check for ptr-int
 	     conversion.  */
-	  return fold (t);
+	  return cp_fully_fold (t);
 	if (tcode == UNARY_PLUS_EXPR)
 	  r = fold_convert (TREE_TYPE (t), op);
 	else
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 84fd1b7..ca989d4 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -702,6 +702,9 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
     case BREAK_STMT:
       gcc_unreachable ();
 
+    case LOCATION_EXPR:
+      gcc_unreachable ();
+
     case OMP_FOR:
     case OMP_SIMD:
     case OMP_DISTRIBUTE:
@@ -1358,7 +1361,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
     genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
   else if (TREE_CODE (stmt) == LOCATION_EXPR)
     {
-      //inform (EXPR_LOCATION (stmt), "would genericize");
+      /* Strip away LOCATION_EXPR nodes.  */
       *stmt_p = TREE_OPERAND (stmt, 0);
       /* *stmt_p has changed, tail recurse to handle it again.  */
       return cp_genericize_r (stmt_p, walk_subtrees, data);
@@ -2220,6 +2223,10 @@ cp_fold (tree x)
       x = fold (x);
       break;
 
+    case LOCATION_EXPR:
+      x = cp_fold (TREE_OPERAND (x, 0));
+      break;
+
     default:
       return org_x;
     }
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 412957f..816b236 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -306,7 +306,6 @@ cp_common_init_ts (void)
   MARK_TS_TYPED (UNARY_RIGHT_FOLD_EXPR);
   MARK_TS_TYPED (BINARY_LEFT_FOLD_EXPR);
   MARK_TS_TYPED (BINARY_RIGHT_FOLD_EXPR);
-
   MARK_TS_TYPED (LOCATION_EXPR);
 }
 
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 38548c7..8ac6ca1 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2750,6 +2750,10 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
       pp_string (pp, M_("*this"));
       break;
 
+    case LOCATION_EXPR:
+      dump_expr (pp, TREE_OPERAND (t, 0), flags);
+      break;
+
       /*  This list is incomplete, but should suffice for now.
 	  It is very important that `sorry' does not call
 	  `report_error_function'.  That could cause an infinite loop.  */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0cfca35..aea0a75 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3893,7 +3893,11 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
   if (count > 1)
     obstack_free (&str_ob, 0);
 
+#if 0
+  return value;
+#else
   return wrap_with_location (value, loc);
+#endif
 }
 
 /* Look up a literal operator with the name and the exact arguments.  */
@@ -12626,6 +12630,7 @@ cp_parser_linkage_specification (cp_parser* parser)
 
   /* Look for the string-literal.  */
   linkage = cp_parser_string_literal (parser, false, false);
+  STRIP_LOCATION_EXPRS (linkage);
 
   /* Transform the literal into an identifier.  If the literal is a
      wide-character string, or contains embedded NULs, then we can't
@@ -17488,6 +17493,7 @@ cp_parser_using_declaration (cp_parser* parser,
 	  decl = cp_parser_lookup_name_simple (parser,
 					       identifier,
 					       token->location);
+	  STRIP_LOCATION_EXPRS (decl);
 	  if (decl == error_mark_node)
 	    cp_parser_name_lookup_error (parser, identifier,
 					 decl, NLE_NULL,
@@ -17754,6 +17760,8 @@ cp_parser_asm_definition (cp_parser* parser)
     return;
   /* Look for the string.  */
   string = cp_parser_string_literal (parser, false, false);
+  STRIP_LOCATION_EXPRS (string);
+
   if (string == error_mark_node)
     {
       cp_parser_skip_to_closing_parenthesis (parser, true, false,
@@ -23008,6 +23016,7 @@ cp_parser_asm_specification_opt (cp_parser* parser)
 
   /* Look for the string-literal.  */
   asm_specification = cp_parser_string_literal (parser, false, false);
+  STRIP_LOCATION_EXPRS (asm_specification);
 
   /* Look for the `)'.  */
   cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
@@ -23060,6 +23069,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
 	name = NULL_TREE;
       /* Look for the string-literal.  */
       string_literal = cp_parser_string_literal (parser, false, false);
+      STRIP_LOCATION_EXPRS (string_literal);
 
       /* Look for the `('.  */
       cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
@@ -23108,6 +23118,7 @@ cp_parser_asm_clobber_list (cp_parser* parser)
 
       /* Look for the string literal.  */
       string_literal = cp_parser_string_literal (parser, false, false);
+      STRIP_LOCATION_EXPRS (string_literal);
       /* Add it to the list.  */
       clobbers = tree_cons (NULL_TREE, string_literal, clobbers);
       /* If the next token is not a `,', then the list is
@@ -24449,12 +24460,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
 
   maybe_record_typedef_use (decl);
 
-  if (TREE_CODE (decl) == TYPE_DECL)
-    /* We don't want to wrap DECL_TYPE with a LOCATION_EXPR, as this
-       confuses cp_parser_new_placement.  */
-    return decl;
-  else
+  if (TREE_CODE (decl) == VAR_DECL
+      || TREE_CODE (decl) == PARM_DECL)
     return wrap_with_location (decl, name_location);
+  else
+    return decl;
 }
 
 /* Like cp_parser_lookup_name, but for use in the typical case where
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 92eb511..c68bba0 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3600,6 +3600,7 @@ check_abi_tag_args (tree args, tree name)
   for (tree arg = args; arg; arg = TREE_CHAIN (arg))
     {
       tree elt = TREE_VALUE (arg);
+      STRIP_LOCATION_EXPRS (elt);
       if (TREE_CODE (elt) != STRING_CST
 	  || (!same_type_ignoring_top_level_qualifiers_p
 	      (strip_array_types (TREE_TYPE (elt)),
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 20700fa..27df803 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4043,7 +4043,9 @@ cp_build_binary_op (location_t location,
     }
 
   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
+  STRIP_LOCATION_EXPRS (op0);
   STRIP_TYPE_NOPS (op0);
+  STRIP_LOCATION_EXPRS (op1);
   STRIP_TYPE_NOPS (op1);
 
   /* DTRT if one side is an overloaded function, but complain about it.  */
diff --git a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.c b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.c
index 50dcdbe..e2e801e 100644
--- a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.c
+++ b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.c
@@ -51,7 +51,7 @@ void test_variables (int param)
    { dg-end-multiline-output "" } */
 }
 
-#if 0
+#if 1
 
 void test_parentheses (int a, int b)
 {
-- 
1.8.5.3

