return lk_internal;
}
\f
-/* EXP is an expression that we want to pre-evaluate. Returns via INITP an
- expression to perform the pre-evaluation, and returns directly an
- expression to use the precalculated result. */
+/* EXP is an expression that we want to pre-evaluate. Returns (in
+ *INITP) an expression that will perform the pre-evaluation. The
+ value returned by this function is a side-effect free expression
+ equivalent to the pre-evaluated expression. Callers must ensure
+ that *INITP is evaluated before EXP. */
tree
stabilize_expr (tree exp, tree* initp)
tree init_expr;
if (!TREE_SIDE_EFFECTS (exp))
- {
- init_expr = NULL_TREE;
- }
+ init_expr = NULL_TREE;
else if (!real_lvalue_p (exp)
|| !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
{
exp = TARGET_EXPR_SLOT (init_expr);
exp = build_indirect_ref (exp, 0);
}
-
*initp = init_expr;
+
+ gcc_assert (!TREE_SIDE_EFFECTS (exp));
return exp;
}
return build2 (COMPOUND_EXPR, void_type_node, orig, new);
}
-/* Like stabilize_expr, but for a call whose args we want to
- pre-evaluate. */
+/* Like stabilize_expr, but for a call whose arguments we want to
+ pre-evaluate. CALL is modified in place to use the pre-evaluated
+ arguments, while, upon return, *INITP contains an expression to
+ compute the arguments. */
void
stabilize_call (tree call, tree *initp)
*initp = inits;
}
-/* Like stabilize_expr, but for an initialization. If we are initializing
- an object of class type, we don't want to introduce an extra temporary,
- so we look past the TARGET_EXPR and stabilize the arguments of the call
- instead. */
+/* Like stabilize_expr, but for an initialization.
+
+ If the initialization is for an object of class type, this function
+ takes care not to introduce additional temporaries.
+
+ Returns TRUE iff the expression was successfully pre-evaluated,
+ i.e., if INIT is now side-effect free, except for, possible, a
+ single call to a constructor. */
bool
stabilize_init (tree init, tree *initp)
{
tree t = init;
+ *initp = NULL_TREE;
+
if (t == error_mark_node)
return true;
if (TREE_CODE (t) == INIT_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
- TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
- else
{
- if (TREE_CODE (t) == INIT_EXPR)
- t = TREE_OPERAND (t, 1);
- if (TREE_CODE (t) == TARGET_EXPR)
- t = TARGET_EXPR_INITIAL (t);
- if (TREE_CODE (t) == COMPOUND_EXPR)
- t = expr_last (t);
- if (TREE_CODE (t) == CONSTRUCTOR
- && EMPTY_CONSTRUCTOR_P (t))
- {
- /* Default-initialization. */
- *initp = NULL_TREE;
- return true;
- }
+ TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
+ return true;
+ }
- /* If the initializer is a COND_EXPR, we can't preevaluate
- anything. */
- if (TREE_CODE (t) == COND_EXPR)
- return false;
+ if (TREE_CODE (t) == INIT_EXPR)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == TARGET_EXPR)
+ t = TARGET_EXPR_INITIAL (t);
+ if (TREE_CODE (t) == COMPOUND_EXPR)
+ t = expr_last (t);
+ if (TREE_CODE (t) == CONSTRUCTOR
+ && EMPTY_CONSTRUCTOR_P (t))
+ /* Default-initialization. */
+ return true;
+
+ /* If the initializer is a COND_EXPR, we can't preevaluate
+ anything. */
+ if (TREE_CODE (t) == COND_EXPR)
+ return false;
- /* The TARGET_EXPR might be initializing via bitwise copy from
- another variable; leave that alone. */
- if (TREE_SIDE_EFFECTS (t))
- stabilize_call (t, initp);
+ if (TREE_CODE (t) == CALL_EXPR
+ || TREE_CODE (t) == AGGR_INIT_EXPR)
+ {
+ stabilize_call (t, initp);
+ return true;
}
- return true;
+ /* The initialization is being performed via a bitwise copy -- and
+ the item copied may have side effects. */
+ return TREE_SIDE_EFFECTS (init);
}
/* Like "fold", but should be used whenever we might be processing the