From: Jason Merrill Date: Sun, 31 May 2015 20:36:26 +0000 (-0400) Subject: * constexpr.c (cxx_eval_indirect_ref): Try folding first. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=255a48d6419c185cd9daac578a97b22e2c71b596;p=gcc.git * constexpr.c (cxx_eval_indirect_ref): Try folding first. From-SVN: r223902 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5029f8320b9..467449c5fbd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,7 @@ 2015-05-31 Jason Merrill + * constexpr.c (cxx_eval_indirect_ref): Try folding first. + PR c++/66320 * constexpr.c (cxx_eval_constant_expression): Treat a placeholder with the wrong type as non-constant. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index f343ea7eae0..ff5489fe029 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2427,42 +2427,55 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, bool *non_constant_p, bool *overflow_p) { tree orig_op0 = TREE_OPERAND (t, 0); - tree op0 = cxx_eval_constant_expression (ctx, orig_op0, - /*lval*/false, non_constant_p, - overflow_p); bool empty_base = false; - tree r; - - /* Don't VERIFY_CONSTANT here. */ - if (*non_constant_p) - return t; - - r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0, - &empty_base); - if (r) - r = cxx_eval_constant_expression (ctx, r, - lval, non_constant_p, overflow_p); - else + /* First try to simplify it directly. */ + tree r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), orig_op0, + &empty_base); + if (!r) { - tree sub = op0; - STRIP_NOPS (sub); - if (TREE_CODE (sub) == ADDR_EXPR) + /* If that didn't work, evaluate the operand first. */ + tree op0 = cxx_eval_constant_expression (ctx, orig_op0, + /*lval*/false, non_constant_p, + overflow_p); + /* Don't VERIFY_CONSTANT here. */ + if (*non_constant_p) + return t; + + r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0, + &empty_base); + if (r == NULL_TREE) { /* We couldn't fold to a constant value. Make sure it's not something we should have been able to fold. */ - gcc_assert (!same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t))); - /* DR 1188 says we don't have to deal with this. */ - if (!ctx->quiet) - error ("accessing value of %qE through a %qT glvalue in a " - "constant expression", build_fold_indirect_ref (sub), - TREE_TYPE (t)); - *non_constant_p = true; + tree sub = op0; + STRIP_NOPS (sub); + if (TREE_CODE (sub) == ADDR_EXPR) + { + gcc_assert (!same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t))); + /* DR 1188 says we don't have to deal with this. */ + if (!ctx->quiet) + error ("accessing value of %qE through a %qT glvalue in a " + "constant expression", build_fold_indirect_ref (sub), + TREE_TYPE (t)); + *non_constant_p = true; + return t; + } + + if (lval && op0 != orig_op0) + return build1 (INDIRECT_REF, TREE_TYPE (t), op0); + if (!lval) + VERIFY_CONSTANT (t); return t; } } + r = cxx_eval_constant_expression (ctx, r, + lval, non_constant_p, overflow_p); + if (*non_constant_p) + return t; + /* If we're pulling out the value of an empty base, make sure that the whole object is constant and then return an empty CONSTRUCTOR. */ @@ -2473,14 +2486,6 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t, TREE_CONSTANT (r) = true; } - if (r == NULL_TREE) - { - if (lval && op0 != orig_op0) - return build1 (INDIRECT_REF, TREE_TYPE (t), op0); - if (!lval) - VERIFY_CONSTANT (t); - return t; - } return r; }