diff gcc/cp/expr.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
line wrap: on
line diff
--- a/gcc/cp/expr.c	Fri Oct 27 22:46:09 2017 +0900
+++ b/gcc/cp/expr.c	Thu Oct 25 07:37:49 2018 +0900
@@ -1,6 +1,6 @@
 /* Convert language-specific tree expression to rtl instructions,
    for GNU compiler.
-   Copyright (C) 1988-2017 Free Software Foundation, Inc.
+   Copyright (C) 1988-2018 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -89,7 +89,7 @@
 /* We've seen an actual use of EXPR.  Possibly replace an outer variable
    reference inside with its constant value or a lambda capture.  */
 
-static tree
+tree
 mark_use (tree expr, bool rvalue_p, bool read_p,
 	  location_t loc /* = UNKNOWN_LOCATION */,
 	  bool reject_builtin /* = true */)
@@ -111,6 +111,22 @@
     {
     case VAR_DECL:
     case PARM_DECL:
+      if (rvalue_p && is_normal_capture_proxy (expr))
+	{
+	  /* Look through capture by copy.  */
+	  tree cap = DECL_CAPTURED_VARIABLE (expr);
+	  if (TREE_CODE (TREE_TYPE (cap)) == TREE_CODE (TREE_TYPE (expr))
+	      && decl_constant_var_p (cap))
+	    {
+	      tree val = RECUR (cap);
+	      if (!is_capture_proxy (val))
+		{
+		  tree l = current_lambda_expr ();
+		  LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
+		}
+	      return val;
+	    }
+	}
       if (outer_automatic_var_p (expr)
 	  && decl_constant_var_p (expr))
 	{
@@ -123,9 +139,12 @@
 		  break;
 		}
 	    }
+	  temp_override<location_t> l (input_location);
+	  if (loc != UNKNOWN_LOCATION)
+	    input_location = loc;
 	  expr = process_outer_var_ref (expr, tf_warning_or_error, true);
 	  if (!(TREE_TYPE (oexpr)
-		&& TREE_CODE (TREE_TYPE (oexpr)) == REFERENCE_TYPE))
+		&& TYPE_REF_P (TREE_TYPE (oexpr))))
 	    expr = convert_from_reference (expr);
 	}
       break;
@@ -146,11 +165,35 @@
 	{
 	  /* Try to look through the reference.  */
 	  tree ref = TREE_OPERAND (expr, 0);
+	  if (rvalue_p && is_normal_capture_proxy (ref))
+	    {
+	      /* Look through capture by reference.  */
+	      tree cap = DECL_CAPTURED_VARIABLE (ref);
+	      if (!TYPE_REF_P (TREE_TYPE (cap))
+		  && decl_constant_var_p (cap))
+		{
+		  tree val = RECUR (cap);
+		  if (!is_capture_proxy (val))
+		    {
+		      tree l = current_lambda_expr ();
+		      LAMBDA_EXPR_CAPTURE_OPTIMIZED (l) = true;
+		    }
+		  return val;
+		}
+	    }
 	  tree r = mark_rvalue_use (ref, loc, reject_builtin);
 	  if (r != ref)
 	    expr = convert_from_reference (r);
 	}
       break;
+
+    CASE_CONVERT:
+    case VIEW_CONVERT_EXPR:
+      if (location_wrapper_p (expr))
+	loc = EXPR_LOCATION (expr);
+      recurse_op[0] = true;
+      break;
+
     default:
       break;
     }
@@ -183,6 +226,22 @@
   return mark_use (e, true, true, loc, reject_builtin);
 }
 
+/* Called whenever an expression is used in an lvalue context.  */
+
+tree
+mark_lvalue_use (tree expr)
+{
+  return mark_use (expr, false, true, input_location, false);
+}
+
+/* As above, but don't consider this use a read.  */
+
+tree
+mark_lvalue_use_nonread (tree expr)
+{
+  return mark_use (expr, false, false, input_location, false);
+}
+
 /* Called when expr appears as a discarded-value expression.  */
 
 tree
@@ -229,22 +288,6 @@
   return mark_use (expr, true, true, input_location, false);
 }
 
-/* Called whenever an expression is used in an lvalue context.  */
-
-tree
-mark_lvalue_use (tree expr)
-{
-  return mark_use (expr, false, true, input_location, false);
-}
-
-/* As above, but don't consider this use a read.  */
-
-tree
-mark_lvalue_use_nonread (tree expr)
-{
-  return mark_use (expr, false, false, input_location, false);
-}
-
 /* Called whenever an expression is used in a type use context.  */
 
 tree
@@ -299,3 +342,24 @@
     }
 }
 
+/* Fold X for consideration by one of the warning functions when checking
+   whether an expression has a constant value.  */
+
+tree
+fold_for_warn (tree x)
+{
+  /* C++ implementation.  */
+
+  /* It's not generally safe to fully fold inside of a template, so
+     call fold_non_dependent_expr instead.  */
+  if (processing_template_decl)
+    {
+      tree f = fold_non_dependent_expr (x, tf_none);
+      if (f == error_mark_node)
+	return x;
+      else
+	return f;
+    }
+
+  return c_fully_fold (x, /*for_init*/false, /*maybe_constp*/NULL);
+}