Mercurial > hg > CbC > CbC_gcc
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); +}