@@ -1,4 +1,4 @@
-2031f0be9c0b5fda6421d290a0261eb6bd1c8205
+616ee658a6238e7de53592ebda5997f6de6a00de
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
@@ -2325,19 +2325,55 @@ Escape_analysis_assign::assign(Node* dst, Node* src)
}
break;
+ case Expression::EXPRESSION_SLICE_INFO:
+ {
+ Slice_info_expression* sie = e->slice_info_expression();
+ if (sie->info() == Expression::SLICE_INFO_VALUE_POINTER)
+ {
+ Node* slice = Node::make_node(sie->slice());
+ this->assign(dst, slice);
+ }
+ }
+ break;
+
case Expression::EXPRESSION_CALL:
{
Call_expression* call = e->call_expression();
if (call->is_builtin())
{
Builtin_call_expression* bce = call->builtin_call_expression();
- if (bce->code() == Builtin_call_expression::BUILTIN_APPEND)
+ switch (bce->code())
{
- // Append returns the first argument.
- // The subsequent arguments are already leaked because
- // they are operands to append.
- Node* appendee = Node::make_node(call->args()->front());
- this->assign(dst, appendee);
+ case Builtin_call_expression::BUILTIN_APPEND:
+ {
+ // Append returns the first argument.
+ // The subsequent arguments are already leaked because
+ // they are operands to append.
+ Node* appendee = Node::make_node(call->args()->front());
+ this->assign(dst, appendee);
+ }
+ break;
+
+ case Builtin_call_expression::BUILTIN_ADD:
+ {
+ // unsafe.Add(p, off).
+ // Flow p to result.
+ Node* arg = Node::make_node(call->args()->front());
+ this->assign(dst, arg);
+ }
+ break;
+
+ case Builtin_call_expression::BUILTIN_SLICE:
+ {
+ // unsafe.Slice(p, len).
+ // The resulting slice has the same backing store as p. Flow p to result.
+ Node* arg = Node::make_node(call->args()->front());
+ this->assign(dst, arg);
+ }
+ break;
+
+ default:
+ break;
}
break;
}
@@ -2592,6 +2628,21 @@ Escape_analysis_assign::assign(Node* dst, Node* src)
}
break;
+ case Expression::EXPRESSION_CONDITIONAL:
+ {
+ Conditional_expression* ce = e->conditional_expression();
+ this->assign(dst, Node::make_node(ce->then_expr()));
+ this->assign(dst, Node::make_node(ce->else_expr()));
+ }
+ break;
+
+ case Expression::EXPRESSION_COMPOUND:
+ {
+ Compound_expression* ce = e->compound_expression();
+ this->assign(dst, Node::make_node(ce->expr()));
+ }
+ break;
+
default:
// TODO(cmang): Add debug info here; this should not be reachable.
// For now, just to be conservative, we'll just say dst flows to src.
@@ -18009,49 +18009,7 @@ Expression::make_type_info(Type* type, Type_info type_info)
return new Type_info_expression(type, type_info);
}
-// An expression that evaluates to some characteristic of a slice.
-// This is used when indexing, bound-checking, or nil checking a slice.
-
-class Slice_info_expression : public Expression
-{
- public:
- Slice_info_expression(Expression* slice, Slice_info slice_info,
- Location location)
- : Expression(EXPRESSION_SLICE_INFO, location),
- slice_(slice), slice_info_(slice_info)
- { }
-
- protected:
- Type*
- do_type();
-
- void
- do_determine_type(const Type_context*)
- { }
-
- Expression*
- do_copy()
- {
- return new Slice_info_expression(this->slice_->copy(), this->slice_info_,
- this->location());
- }
-
- Bexpression*
- do_get_backend(Translate_context* context);
-
- void
- do_dump_expression(Ast_dump_context*) const;
-
- void
- do_issue_nil_check()
- { this->slice_->issue_nil_check(); }
-
- private:
- // The slice for which we are getting information.
- Expression* slice_;
- // What information we want.
- Slice_info slice_info_;
-};
+// Slice_info_expression.
// Return the type of the slice info.
@@ -62,6 +62,7 @@ class Type_guard_expression;
class Heap_expression;
class Receive_expression;
class Slice_value_expression;
+class Slice_info_expression;
class Conditional_expression;
class Compound_expression;
class Numeric_constant;
@@ -900,6 +901,14 @@ class Expression
compound_expression()
{ return this->convert<Compound_expression, EXPRESSION_COMPOUND>(); }
+ // If this is a slice info expression, return the
+ // Slice_info_expression structure. Otherwise, return NULL.
+ Slice_info_expression*
+ slice_info_expression()
+ {
+ return this->convert<Slice_info_expression, EXPRESSION_SLICE_INFO>();
+ }
+
// Return true if this is a composite literal.
bool
is_composite_literal() const;
@@ -4262,6 +4271,60 @@ class Slice_value_expression : public Expression
Expression* cap_;
};
+// An expression that evaluates to some characteristic of a slice.
+// This is used when indexing, bound-checking, or nil checking a slice.
+
+class Slice_info_expression : public Expression
+{
+ public:
+ Slice_info_expression(Expression* slice, Slice_info slice_info,
+ Location location)
+ : Expression(EXPRESSION_SLICE_INFO, location),
+ slice_(slice), slice_info_(slice_info)
+ { }
+
+ // The slice operand of this slice info expression.
+ Expression*
+ slice() const
+ { return this->slice_; }
+
+ // The info this expression is about.
+ Slice_info
+ info() const
+ { return this->slice_info_; }
+
+ protected:
+ Type*
+ do_type();
+
+ void
+ do_determine_type(const Type_context*)
+ { }
+
+ Expression*
+ do_copy()
+ {
+ return new Slice_info_expression(this->slice_->copy(), this->slice_info_,
+ this->location());
+ }
+
+ Bexpression*
+ do_get_backend(Translate_context* context);
+
+ void
+ do_dump_expression(Ast_dump_context*) const;
+
+ void
+ do_issue_nil_check()
+ { this->slice_->issue_nil_check(); }
+
+ private:
+ // The slice for which we are getting information.
+ Expression* slice_;
+ // What information we want.
+ Slice_info slice_info_;
+};
+
// Conditional expressions.
class Conditional_expression : public Expression
@@ -4277,6 +4340,14 @@ class Conditional_expression : public Expression
condition() const
{ return this->cond_; }
+ Expression*
+ then_expr() const
+ { return this->then_; }
+
+ Expression*
+ else_expr() const
+ { return this->else_; }
+
protected:
int
do_traverse(Traverse*);
@@ -4322,6 +4393,10 @@ class Compound_expression : public Expression
init() const
{ return this->init_; }
+ Expression*
+ expr() const
+ { return this->expr_; }
+
protected:
int
do_traverse(Traverse*);