From aa2aaa94b4f8367423913f16a77243394bfb0dcc Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 23 Nov 2015 12:05:41 -0500
Subject: [PATCH 09/35] FIXME: WIP: 2nd part of c++ rewrite

---
 gcc/cp/cp-tree.h                                   |  2 ++
 gcc/cp/parser.c                                    | 41 ++++++++++++++++------
 gcc/cp/semantics.c                                 |  4 +--
 gcc/cp/tree.c                                      |  4 +++
 gcc/cp/typeck.c                                    | 15 ++++++++
 gcc/diagnostic-show-locus.c                        |  2 +-
 .../g++.dg/plugin/diagnostic-test-expressions-1.c  | 36 +++++++++++++++++++
 .../diagnostic_plugin_test_tree_expression_range.c |  6 ++++
 8 files changed, 96 insertions(+), 14 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 160bf1e..30002dd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -271,6 +271,8 @@ struct GTY(()) lang_identifier {
 inline lang_identifier*
 identifier_p (tree t)
 {
+  if (TREE_CODE (t) == NOP_EXPR)
+    t = TREE_OPERAND (t, 0);
   if (TREE_CODE (t) == IDENTIFIER_NODE)
     return (lang_identifier*) t;
   return NULL;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 427641b..845f315 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1414,6 +1414,9 @@ make_id_declarator (tree qualifying_scope, tree unqualified_name,
   if (qualifying_scope && TYPE_P (qualifying_scope))
     qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
 
+  if (TREE_CODE (unqualified_name) == NOP_EXPR)
+    unqualified_name = TREE_OPERAND (unqualified_name, 0);
+
   gcc_assert (identifier_p (unqualified_name)
 	      || TREE_CODE (unqualified_name) == BIT_NOT_EXPR
 	      || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR);
@@ -3665,6 +3668,22 @@ cp_parser_pop_lexer (cp_parser *parser)
   cp_lexer_set_source_position_from_token (parser->lexer->next_token);
 }
 
+/* FIXME.  */
+static tree
+use_as_lvalue (tree value, location_t loc)
+{
+  tree wrapper = build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (value), value);
+  return wrapper;
+}
+
+/* FIXME.  */
+static tree
+use_as_rvalue (tree value, location_t loc)
+{
+  tree nop = build1_loc (loc, NOP_EXPR, TREE_TYPE (value), value);
+  return nop;
+}
+
 /* Lexical conventions [gram.lex]  */
 
 /* Parse an identifier.  Returns an IDENTIFIER_NODE representing the
@@ -3679,7 +3698,7 @@ cp_parser_identifier (cp_parser* parser)
   token = cp_parser_require (parser, CPP_NAME, RT_NAME);
   /* Return the value.  */
   if (token)
-    return cp_expr (token->u.value, token->location);
+    return token->u.value; // FIXME //use_as_rvalue (token->u.value, token->location); // FIXME: what if an lvalue?
   else
     return error_mark_node;
 }
@@ -3879,7 +3898,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
   if (count > 1)
     obstack_free (&str_ob, 0);
 
-  return cp_expr (value, loc);
+  return use_as_lvalue (value, loc);
 }
 
 /* Look up a literal operator with the name and the exact arguments.  */
@@ -4628,7 +4647,7 @@ cp_parser_primary_expression (cp_parser *parser,
 	  if (!cast_p)
 	    cp_parser_non_integral_constant_expression (parser, NIC_FLOAT);
 	}
-      return cp_expr (token->u.value, token->location);
+      return use_as_rvalue (token->u.value, token->location);
 
     case CPP_CHAR_USERDEF:
     case CPP_CHAR16_USERDEF:
@@ -4780,20 +4799,20 @@ cp_parser_primary_expression (cp_parser *parser,
 	  /* These two are the boolean literals.  */
 	case RID_TRUE:
 	  cp_lexer_consume_token (parser->lexer);
-	  return cp_expr (boolean_true_node, token->location);
+	  return use_as_rvalue (boolean_true_node, token->location);
 	case RID_FALSE:
 	  cp_lexer_consume_token (parser->lexer);
-	  return cp_expr (boolean_false_node, token->location);
+	  return use_as_rvalue (boolean_false_node, token->location);
 
 	  /* The `__null' literal.  */
 	case RID_NULL:
 	  cp_lexer_consume_token (parser->lexer);
-	  return cp_expr (null_node, token->location);
+	  return use_as_rvalue (null_node, token->location);
 
 	  /* The `nullptr' literal.  */
 	case RID_NULLPTR:
 	  cp_lexer_consume_token (parser->lexer);
-	  return cp_expr (nullptr_node, token->location);
+	  return use_as_rvalue (nullptr_node, token->location);
 
 	  /* Recognize the `this' keyword.  */
 	case RID_THIS:
@@ -8987,7 +9006,7 @@ cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
 	  expression = build_x_compound_expr (loc, expression,
 					      assignment_expression,
 					      complain_flags (decltype_p));
-	  expression.set_location (loc);
+	  //expression.set_location (loc);
 	}
       /* If the next token is not a comma, or we're in a fold-expression, then
 	 we are done with the expression.  */
@@ -13485,7 +13504,7 @@ cp_parser_operator (cp_parser* parser)
 
 	location_t loc = make_location (start_loc, start_loc, end_loc);
 
-	return cp_expr (id, loc);
+	return id; // FIXME: what to do about loc
       }
 
     case CPP_PLUS:
@@ -13731,7 +13750,7 @@ cp_parser_operator (cp_parser* parser)
       id = error_mark_node;
     }
 
-  return cp_expr (id, start_loc);
+  return id; // FIXME: cp_expr (id, start_loc);
 }
 
 /* Parse a template-declaration.
@@ -24434,7 +24453,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
 
   maybe_record_typedef_use (decl);
 
-  return cp_expr (decl, name_location);
+  return use_as_rvalue (decl, name_location);
 }
 
 /* Like cp_parser_lookup_name, but for use in the typical case where
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 6b8642e..df95da9 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2590,7 +2590,7 @@ finish_unary_op_expr (location_t op_loc, enum tree_code code, tree expr,
   if (CONSTANT_CLASS_P (result_ovl) && TREE_OVERFLOW_P (result_ovl))
     overflow_warning (combined_loc, result_ovl);
 
-  return cp_expr (result, combined_loc);
+  return result; // cp_expr (result, combined_loc);
 }
 
 /* Finish a compound-literal expression.  TYPE is the type to which
@@ -3676,7 +3676,7 @@ finish_id_expression (tree id_expression,
 	}
     }
 
-  return cp_expr (decl, location);
+  return decl; // return use_as_rvalue (decl); // FIXME: is this neeeded?
 }
 
 /* Implement the __typeof keyword: Return the type of EXPR, suitable for
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d2db31a..3f60b24 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -56,6 +56,10 @@ lvalue_kind (const_tree ref)
   cp_lvalue_kind op1_lvalue_kind = clk_none;
   cp_lvalue_kind op2_lvalue_kind = clk_none;
 
+  /* FIXME.  */
+  if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
+    ref = TREE_OPERAND (ref, 0);
+
   /* Expressions of reference type are sometimes wrapped in
      INDIRECT_REFs.  INDIRECT_REFs are just internal compiler
      representation, not part of the language, so we have to look
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 9c27add..20700fa 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-objc.h"
 #include "c-family/c-ubsan.h"
 #include "params.h"
+//#include "print-tree.h"
 
 static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
 static tree cp_build_function_call (tree, tree, tsubst_flags_t);
@@ -3673,6 +3674,12 @@ convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
       tree type = typetail ? TREE_VALUE (typetail) : 0;
       tree val = (**values)[i];
 
+#if 0
+      fprintf (stderr, "arg %i at start of loop body\n", i);
+      debug_tree (val);
+      inform (EXPR_LOCATION (val), "arg %i at start of loop body", i);
+#endif
+
       if (val == error_mark_node || type == error_mark_node)
 	return -1;
 
@@ -3687,12 +3694,14 @@ convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
             return -1;
 	}
 
+#if 0
       /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
 	 Strip such NOP_EXPRs, since VAL is used in non-lvalue context.  */
       if (TREE_CODE (val) == NOP_EXPR
 	  && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0))
 	  && (type == 0 || TREE_CODE (type) != REFERENCE_TYPE))
 	val = TREE_OPERAND (val, 0);
+#endif
 
       if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)
 	{
@@ -3750,6 +3759,12 @@ convert_arguments (tree typelist, vec<tree, va_gc> **values, tree fndecl,
 
       if (typetail)
 	typetail = TREE_CHAIN (typetail);
+
+#if 0
+      fprintf (stderr, "values[%i] at end of loop body\n", i);
+      debug_tree ((**values)[i]);
+      inform (EXPR_LOCATION ((**values)[i]), "values[%i] at end of loop body", i);
+#endif
     }
 
   if (typetail != 0 && typetail != void_list_node)
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index 9e51b95..072f3a5 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -779,7 +779,7 @@ diagnostic_show_locus (diagnostic_context * context,
 {
   if (!context->show_caret
       || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
-      || diagnostic_location (diagnostic, 0) == context->last_location)
+      /*|| diagnostic_location (diagnostic, 0) == context->last_location*/)
     return;
 
   context->last_location = diagnostic_location (diagnostic, 0);
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 f58cc7f..50dcdbe 100644
--- a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.c
+++ b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.c
@@ -19,6 +19,40 @@ extern void __emit_expression_range (int dummy, ...);
 
 int global;
 
+/* Simple expressions.  ************************************************/
+
+void test_literals (void)
+{
+  __emit_expression_range (0, 1066 ); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, 1066 );
+                               ^~~~
+   { dg-end-multiline-output "" } */
+
+  __emit_expression_range (0, "hello" ); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, "hello" );
+                               ^~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void test_variables (int param)
+{
+  __emit_expression_range (0, param ); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, param );
+                               ^~~~~
+   { dg-end-multiline-output "" } */
+
+  __emit_expression_range (0, global ); /* { dg-warning "range" } */
+/* { dg-begin-multiline-output "" }
+   __emit_expression_range (0, global );
+                               ^~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+#if 0
+
 void test_parentheses (int a, int b)
 {
   __emit_expression_range (0, (a + b) ); /* { dg-warning "range" } */
@@ -530,3 +564,5 @@ void test_new (void)
 
   /* TODO: placement new.  */
 }
+
+#endif
diff --git a/gcc/testsuite/g++.dg/plugin/diagnostic_plugin_test_tree_expression_range.c b/gcc/testsuite/g++.dg/plugin/diagnostic_plugin_test_tree_expression_range.c
index 89cc95a..3f8821d 100644
--- a/gcc/testsuite/g++.dg/plugin/diagnostic_plugin_test_tree_expression_range.c
+++ b/gcc/testsuite/g++.dg/plugin/diagnostic_plugin_test_tree_expression_range.c
@@ -65,6 +65,12 @@ cb_walk_tree_fn (tree * tp, int * walk_subtrees,
   /* Get arg 1; print it! */
   tree arg = CALL_EXPR_ARG (call_expr, 1);
 
+#if 0
+  fprintf (stderr, "call_expr: %p\n", call_expr);
+  fprintf (stderr, "arg: %p\n", arg);
+  debug_tree (arg);
+#endif
+
   emit_warning (EXPR_LOCATION (arg));
 
   return NULL_TREE;
-- 
1.8.5.3

