comparison gcc/go/gofrontend/escape.cc @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
13 #include "gogo.h" 13 #include "gogo.h"
14 #include "types.h" 14 #include "types.h"
15 #include "expressions.h" 15 #include "expressions.h"
16 #include "statements.h" 16 #include "statements.h"
17 #include "escape.h" 17 #include "escape.h"
18 #include "lex.h"
18 #include "ast-dump.h" 19 #include "ast-dump.h"
19 #include "go-optimize.h" 20 #include "go-optimize.h"
20 #include "go-diagnostics.h" 21 #include "go-diagnostics.h"
22 #include "go-sha1.h"
21 23
22 // class Node. 24 // class Node.
23 25
24 // Return the node's type, if it makes sense for it to have one. 26 // Return the node's type, if it makes sense for it to have one.
25 27
32 else if (this->object() != NULL 34 else if (this->object() != NULL
33 && this->object()->is_function()) 35 && this->object()->is_function())
34 return this->object()->func_value()->type(); 36 return this->object()->func_value()->type();
35 else if (this->expr() != NULL) 37 else if (this->expr() != NULL)
36 return this->expr()->type(); 38 return this->expr()->type();
39 else if (this->is_indirect())
40 {
41 if (this->child()->type()->deref()->is_void_type())
42 // This is a void*. The referred type can be actually any type,
43 // which may also be pointer. We model it as another void*, so
44 // we don't lose pointer-ness.
45 return this->child()->type();
46 else if (this->child()->type()->is_slice_type())
47 // We model "indirect" of a slice as dereferencing its pointer
48 // field (to get element). Use element type here.
49 return this->child()->type()->array_type()->element_type();
50 else if (this->child()->type()->is_string_type())
51 return Type::lookup_integer_type("uint8");
52 else
53 return this->child()->type()->deref();
54 }
55 else if (this->statement() != NULL
56 && this->statement()->temporary_statement() != NULL)
57 return this->statement()->temporary_statement()->type();
37 else 58 else
38 return NULL; 59 return NULL;
39 } 60 }
40 61
41 // A helper for reporting; return this node's location. 62 // A helper for reporting; return this node's location.
47 return this->object()->location(); 68 return this->object()->location();
48 else if (this->expr() != NULL) 69 else if (this->expr() != NULL)
49 return this->expr()->location(); 70 return this->expr()->location();
50 else if (this->statement() != NULL) 71 else if (this->statement() != NULL)
51 return this->statement()->location(); 72 return this->statement()->location();
73 else if (this->is_indirect())
74 return this->child()->location();
52 else 75 else
53 return Linemap::unknown_location(); 76 return Linemap::unknown_location();
77 }
78
79 // A helper for reporting; return the location where the underlying
80 // object is defined.
81
82 Location
83 Node::definition_location() const
84 {
85 if (this->object() != NULL && !this->object()->is_sink())
86 {
87 Named_object* no = this->object();
88 if (no->is_variable() || no->is_result_variable())
89 return no->location();
90 }
91 else if (this->expr() != NULL)
92 {
93 Var_expression* ve = this->expr()->var_expression();
94 if (ve != NULL)
95 {
96 Named_object* no = ve->named_object();
97 if (no->is_variable() || no->is_result_variable())
98 return no->location();
99 }
100 Enclosed_var_expression* eve = this->expr()->enclosed_var_expression();
101 if (eve != NULL)
102 {
103 Named_object* no = eve->variable();
104 if (no->is_variable() || no->is_result_variable())
105 return no->location();
106 }
107 }
108 return this->location();
54 } 109 }
55 110
56 // To match the cmd/gc debug output, strip away the packed prefixes on functions 111 // To match the cmd/gc debug output, strip away the packed prefixes on functions
57 // and variable/expressions. 112 // and variable/expressions.
58 113
80 else if (this->object() != NULL) 135 else if (this->object() != NULL)
81 { 136 {
82 Named_object* no = this->object(); 137 Named_object* no = this->object();
83 if (no->is_function() && no->func_value()->enclosing() != NULL) 138 if (no->is_function() && no->func_value()->enclosing() != NULL)
84 return "func literal"; 139 return "func literal";
85 ss << no->name(); 140 ss << no->message_name();
86 } 141 }
87 else if (this->expr() != NULL) 142 else if (this->expr() != NULL)
88 { 143 {
89 Expression* e = this->expr(); 144 Expression* e = this->expr();
90 bool is_call = e->call_expression() != NULL; 145 bool is_call = e->call_expression() != NULL;
99 return "(func literal)()"; 154 return "(func literal)()";
100 return "func literal"; 155 return "func literal";
101 } 156 }
102 Ast_dump_context::dump_to_stream(this->expr(), &ss); 157 Ast_dump_context::dump_to_stream(this->expr(), &ss);
103 } 158 }
104 else 159 else if (this->statement() != NULL)
105 { 160 {
106 Statement* s = this->statement(); 161 Statement* s = this->statement();
107 Goto_unnamed_statement* unnamed = s->goto_unnamed_statement(); 162 Goto_unnamed_statement* unnamed = s->goto_unnamed_statement();
108 if (unnamed != NULL) 163 if (unnamed != NULL)
109 { 164 {
128 default: 183 default:
129 break; 184 break;
130 } 185 }
131 } 186 }
132 } 187 }
133 Ast_dump_context::dump_to_stream(s, &ss); 188 Temporary_statement* tmp = s->temporary_statement();
134 } 189 if (tmp != NULL)
135 190 {
136 return strip_packed_prefix(gogo, ss.str()); 191 // Temporary's format can never match gc's output, and
192 // temporaries are inserted differently anyway. We just
193 // print something convenient.
194 ss << "tmp." << (uintptr_t) tmp;
195 if (tmp->init() != NULL)
196 {
197 ss << " [ = ";
198 Ast_dump_context::dump_to_stream(tmp->init(), &ss);
199 ss << " ]";
200 }
201 }
202 else
203 Ast_dump_context::dump_to_stream(s, &ss);
204 }
205 else if (this->is_indirect())
206 return "*(" + this->child()->ast_format(gogo) + ")";
207
208 std::string s = strip_packed_prefix(gogo, ss.str());
209
210 // trim trailing space
211 return s.substr(0, s.find_last_not_of(' ') + 1);
137 } 212 }
138 213
139 // A helper for debugging; return this node's detailed format string. 214 // A helper for debugging; return this node's detailed format string.
140 // This is an implementation of gc's Jconv with obj.FmtShort. 215 // This is an implementation of gc's Jconv with obj.FmtShort.
141 216
142 std::string 217 std::string
143 Node::details() const 218 Node::details()
144 { 219 {
145 std::stringstream details; 220 std::stringstream details;
146 221
147 if (!this->is_sink()) 222 if (!this->is_sink())
148 details << " l(" << Linemap::location_to_line(this->location()) << ")"; 223 details << " l(" << Linemap::location_to_line(this->location()) << ")";
221 296
222 case Node::ESCAPE_HEAP: 297 case Node::ESCAPE_HEAP:
223 details << " esc(h)"; 298 details << " esc(h)";
224 break; 299 break;
225 300
226 case Node::ESCAPE_SCOPE:
227 details << " esc(s)";
228 break;
229
230 case Node::ESCAPE_NONE: 301 case Node::ESCAPE_NONE:
231 details << " esc(no)"; 302 details << " esc(no)";
232 break; 303 break;
233 304
234 case Node::ESCAPE_NEVER: 305 case Node::ESCAPE_NEVER:
293 case Runtime::TYPEDSLICECOPY: 364 case Runtime::TYPEDSLICECOPY:
294 op << "copy"; 365 op << "copy";
295 break; 366 break;
296 367
297 case Runtime::MAKECHAN: 368 case Runtime::MAKECHAN:
369 case Runtime::MAKECHAN64:
298 case Runtime::MAKEMAP: 370 case Runtime::MAKEMAP:
299 case Runtime::MAKESLICE: 371 case Runtime::MAKESLICE:
300 case Runtime::MAKESLICE64: 372 case Runtime::MAKESLICE64:
301 op << "make"; 373 op << "make";
302 break; 374 break;
346 418
347 default: 419 default:
348 break; 420 break;
349 } 421 }
350 } 422 }
423 if (this->is_indirect())
424 op << "*";
351 return op.str(); 425 return op.str();
352 } 426 }
353 427
354 // Return this node's state, creating it if has not been initialized. 428 // Return this node's state, creating it if has not been initialized.
355 429
376 } 450 }
377 go_assert(this->state_ != NULL); 451 go_assert(this->state_ != NULL);
378 return this->state_; 452 return this->state_;
379 } 453 }
380 454
455 Node::~Node()
456 {
457 if (this->state_ != NULL)
458 {
459 if (this->expr() == NULL || this->expr()->var_expression() == NULL)
460 // Var expression Node is excluded since it shares state with the
461 // underlying var Node.
462 delete this->state_;
463 }
464 }
465
466 int
467 Node::encoding()
468 {
469 if (this->expr() != NULL
470 && this->expr()->var_expression() != NULL)
471 {
472 // Get the underlying object's encoding.
473 Named_object* no = this->expr()->var_expression()->named_object();
474 int enc = Node::make_node(no)->encoding();
475 this->encoding_ = enc;
476 }
477 return this->encoding_;
478 }
479
381 void 480 void
382 Node::set_encoding(int enc) 481 Node::set_encoding(int enc)
383 { 482 {
384 this->encoding_ = enc; 483 this->encoding_ = enc;
385 if (this->expr() != NULL 484 if (this->expr() != NULL)
386 && this->expr()->var_expression() != NULL) 485 {
387 { 486 if (this->expr()->var_expression() != NULL)
388 // Set underlying object as well. 487 {
389 Named_object* no = this->expr()->var_expression()->named_object(); 488 // Set underlying object as well.
390 Node::make_node(no)->set_encoding(enc); 489 Named_object* no = this->expr()->var_expression()->named_object();
490 Node::make_node(no)->set_encoding(enc);
491 }
492 else if (this->expr()->func_expression() != NULL)
493 {
494 // Propagate the escape state to the underlying
495 // closure (heap expression).
496 Expression* closure = this->expr()->func_expression()->closure();
497 if (closure != NULL)
498 Node::make_node(closure)->set_encoding(enc);
499 }
391 } 500 }
392 } 501 }
393 502
394 bool 503 bool
395 Node::is_big(Escape_context* context) const 504 Node::is_big(Escape_context* context) const
424 { 533 {
425 // Second argument is length. 534 // Second argument is length.
426 Expression_list::iterator p = call->args()->begin(); 535 Expression_list::iterator p = call->args()->begin();
427 ++p; 536 ++p;
428 537
538 Expression* e = *p;
539 if (e->temporary_reference_expression() != NULL)
540 {
541 Temporary_reference_expression* tre = e->temporary_reference_expression();
542 if (tre->statement() != NULL && tre->statement()->init() != NULL)
543 e = tre->statement()->init();
544 }
545
429 Numeric_constant nc; 546 Numeric_constant nc;
430 unsigned long v; 547 unsigned long v;
431 if ((*p)->numeric_constant_value(&nc) 548 if (e->numeric_constant_value(&nc)
432 && nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_VALID) 549 && nc.to_unsigned_long(&v) == Numeric_constant::NC_UL_VALID)
433 big = big || v >= (1 << 16); 550 big = big || v >= (1 << 16);
434 } 551 }
435 } 552 }
436 } 553 }
451 } 568 }
452 569
453 std::map<Named_object*, Node*> Node::objects; 570 std::map<Named_object*, Node*> Node::objects;
454 std::map<Expression*, Node*> Node::expressions; 571 std::map<Expression*, Node*> Node::expressions;
455 std::map<Statement*, Node*> Node::statements; 572 std::map<Statement*, Node*> Node::statements;
573 std::vector<Node*> Node::indirects;
456 574
457 // Make a object node or return a cached node for this object. 575 // Make a object node or return a cached node for this object.
458 576
459 Node* 577 Node*
460 Node::make_node(Named_object* no) 578 Node::make_node(Named_object* no)
494 std::pair<Statement*, Node*> val(s, n); 612 std::pair<Statement*, Node*> val(s, n);
495 Node::statements.insert(val); 613 Node::statements.insert(val);
496 return n; 614 return n;
497 } 615 }
498 616
617 // Make an indirect node with given child.
618
619 Node*
620 Node::make_indirect_node(Node* child)
621 {
622 Node* n = new Node(child);
623 Node::indirects.push_back(n);
624 return n;
625 }
626
499 // Returns the maximum of an exisiting escape value 627 // Returns the maximum of an exisiting escape value
500 // (and its additional parameter flow flags) and a new escape type. 628 // (and its additional parameter flow flags) and a new escape type.
501 629
502 int 630 int
503 Node::max_encoding(int e, int etype) 631 Node::max_encoding(int e, int etype)
504 { 632 {
505 if ((e & ESCAPE_MASK) >= etype) 633 if ((e & ESCAPE_MASK) > etype)
506 return e; 634 return e;
507 if (etype == Node::ESCAPE_NONE || etype == Node::ESCAPE_RETURN) 635 if (etype == Node::ESCAPE_NONE || etype == Node::ESCAPE_RETURN)
508 return (e & ~ESCAPE_MASK) | etype; 636 return (e & ~ESCAPE_MASK) | etype;
509 return etype; 637 return etype;
510 } 638 }
550 sink_(Node::make_node(Named_object::make_sink())), loop_depth_(0), 678 sink_(Node::make_node(Named_object::make_sink())), loop_depth_(0),
551 flood_id_(0), pdepth_(0) 679 flood_id_(0), pdepth_(0)
552 { 680 {
553 // The sink always escapes to heap and strictly lives outside of the 681 // The sink always escapes to heap and strictly lives outside of the
554 // current function i.e. loop_depth == -1. 682 // current function i.e. loop_depth == -1.
555 this->sink_->set_encoding(Node::ESCAPE_HEAP);
556 Node::Escape_state* state = this->sink_->state(this, NULL); 683 Node::Escape_state* state = this->sink_->state(this, NULL);
557 state->loop_depth = -1; 684 state->loop_depth = -1;
558 } 685 }
559 686
560 std::string 687 std::string
561 debug_function_name(Named_object* fn) 688 debug_function_name(Named_object* fn)
562 { 689 {
563 if (fn == NULL) 690 if (fn == NULL)
564 return "<S>"; 691 return "<S>";
565 692
566 if (!fn->is_function() 693 if (!fn->is_function())
567 || fn->func_value()->enclosing() == NULL)
568 return Gogo::unpack_hidden_name(fn->name()); 694 return Gogo::unpack_hidden_name(fn->name());
569 695
570 // Closures are named ".$nested#" where # starts from 0 to distinguish 696 std::string fnname = Gogo::unpack_hidden_name(fn->name());
571 // between closures. The cmd/gc closures are named in the format 697 if (fn->func_value()->is_method())
572 // "enclosing.func#" where # starts from 1. If this is a closure, format 698 {
573 // its name to match cmd/gc. 699 // Methods in gc compiler are named "T.m" or "(*T).m" where
574 Named_object* enclosing = fn->func_value()->enclosing(); 700 // T is the receiver type. Add the receiver here.
575 701 Type* rt = fn->func_value()->type()->receiver()->type();
576 // Extract #. 702 switch (rt->classification())
577 std::string name = Gogo::unpack_hidden_name(fn->name()); 703 {
578 int closure_num = Gogo::nested_function_num(fn->name()); 704 case Type::TYPE_NAMED:
579 closure_num++; 705 fnname = rt->named_type()->name() + "." + fnname;
580 706 break;
581 name = Gogo::unpack_hidden_name(enclosing->name()); 707
582 char buf[200]; 708 case Type::TYPE_POINTER:
583 snprintf(buf, sizeof buf, "%s.func%d", name.c_str(), closure_num); 709 {
584 return buf; 710 Named_type* nt = rt->points_to()->named_type();
711 if (nt != NULL)
712 fnname = "(*" + nt->name() + ")." + fnname;
713 break;
714 }
715
716 default:
717 break;
718 }
719 }
720
721 return fnname;
585 } 722 }
586 723
587 // Return the name of the current function. 724 // Return the name of the current function.
588 725
589 std::string 726 std::string
600 { 737 {
601 if (fntype == NULL || fntype->results() == NULL) 738 if (fntype == NULL || fntype->results() == NULL)
602 return; 739 return;
603 740
604 Node::Escape_state* state = n->state(this, NULL); 741 Node::Escape_state* state = n->state(this, NULL);
742 state->retvals.clear();
605 Location loc = n->location(); 743 Location loc = n->location();
606 744
607 int i = 0; 745 int i = 0;
608 char buf[50]; 746 char buf[50];
609 for (Typed_identifier_list::const_iterator p = fntype->results()->begin(); 747 for (Typed_identifier_list::const_iterator p = fntype->results()->begin();
616 dummy_var->set_is_used(); 754 dummy_var->set_is_used();
617 Named_object* dummy_no = 755 Named_object* dummy_no =
618 Named_object::make_variable(buf, NULL, dummy_var); 756 Named_object::make_variable(buf, NULL, dummy_var);
619 Node* dummy_node = Node::make_node(dummy_no); 757 Node* dummy_node = Node::make_node(dummy_no);
620 // Initialize the state of the dummy output node. 758 // Initialize the state of the dummy output node.
621 dummy_node->state(this, NULL); 759 Node::Escape_state* dummy_node_state = dummy_node->state(this, NULL);
760 dummy_node_state->loop_depth = this->loop_depth_;
622 761
623 // Add dummy node to the retvals of n. 762 // Add dummy node to the retvals of n.
624 state->retvals.push_back(dummy_node); 763 state->retvals.push_back(dummy_node);
625 } 764 }
626 } 765 }
627 766
628 767
629 // Apply an indirection to N and return the result. 768 // Apply an indirection to N and return the result.
630 // This really only works if N is an expression node; it essentially becomes
631 // Node::make_node(n->expr()->deref()). We need the escape context to set the
632 // correct loop depth, however.
633 769
634 Node* 770 Node*
635 Escape_context::add_dereference(Node* n) 771 Escape_context::add_dereference(Node* n)
636 { 772 {
637 // Just return the original node if we can't add an indirection. 773 Expression* e = n->expr();
638 if (n->object() != NULL || n->statement() != NULL) 774 Location loc = n->location();
639 return n; 775 Node* ind;
640 776 if (e != NULL
641 Node* ind = Node::make_node(n->expr()->deref()); 777 && e->type()->points_to() != NULL
642 // Initialize the state if this node doesn't already exist. 778 && !e->type()->points_to()->is_void_type())
643 ind->state(this, NULL); 779 {
780 // We don't dereference void*, which can be actually any pointer type.
781 Expression* deref_expr = Expression::make_unary(OPERATOR_MULT, e, loc);
782 ind = Node::make_node(deref_expr);
783 }
784 else
785 // The gc compiler simply makes an OIND node. We can't do it
786 // for non-pointer type because that will result in a type error.
787 // Instead, we model this by making a node with a special flavor.
788 ind = Node::make_indirect_node(n);
789
790 // Initialize the state.
791 Node::Escape_state* state = ind->state(this, NULL);
792 state->loop_depth = n->state(this, NULL)->loop_depth;
644 return ind; 793 return ind;
645 } 794 }
646 795
647 void 796 void
648 Escape_context::track(Node* n) 797 Escape_context::track(Node* n)
680 } 829 }
681 830
682 831
683 // The -fgo-optimize-alloc flag activates this escape analysis. 832 // The -fgo-optimize-alloc flag activates this escape analysis.
684 833
685 Go_optimize optimize_allocation_flag("allocs"); 834 Go_optimize optimize_allocation_flag("allocs", true);
835
836 // A helper function to compute whether a function name has a
837 // matching hash value.
838
839 static bool
840 escape_hash_match(std::string suffix, std::string name)
841 {
842 if (suffix.empty())
843 return true;
844 if (suffix.at(0) == '-')
845 return !escape_hash_match(suffix.substr(1), name);
846
847 const char* p = name.c_str();
848 Go_sha1_helper* sha1_helper = go_create_sha1_helper();
849 sha1_helper->process_bytes(p, strlen(p));
850 std::string s = sha1_helper->finish();
851 delete sha1_helper;
852
853 int j = suffix.size() - 1;
854 for (int i = s.size() - 1; i >= 0; i--)
855 {
856 char c = s.at(i);
857 for (int k = 0; k < 8; k++, j--, c>>=1)
858 {
859 if (j < 0)
860 return true;
861 char bit = suffix.at(j) - '0';
862 if ((c&1) != bit)
863 return false;
864 }
865 }
866 return false;
867 }
686 868
687 // Analyze the program flow for escape information. 869 // Analyze the program flow for escape information.
688 870
689 void 871 void
690 Gogo::analyze_escape() 872 Gogo::analyze_escape()
691 { 873 {
692 if (!optimize_allocation_flag.is_enabled() || saw_errors()) 874 if (saw_errors())
875 return;
876
877 if (!optimize_allocation_flag.is_enabled()
878 && !this->compiling_runtime())
879 // We always run escape analysis when compiling runtime.
693 return; 880 return;
694 881
695 // Discover strongly connected groups of functions to analyze for escape 882 // Discover strongly connected groups of functions to analyze for escape
696 // information in this package. 883 // information in this package.
697 this->discover_analysis_sets(); 884 this->discover_analysis_sets();
698 885
886 if (!this->debug_escape_hash().empty())
887 std::cerr << "debug-escape-hash " << this->debug_escape_hash() << "\n";
888
699 for (std::vector<Analysis_set>::iterator p = this->analysis_sets_.begin(); 889 for (std::vector<Analysis_set>::iterator p = this->analysis_sets_.begin();
700 p != this->analysis_sets_.end(); 890 p != this->analysis_sets_.end();
701 ++p) 891 ++p)
702 { 892 {
703 std::vector<Named_object*> stack = p->first; 893 std::vector<Named_object*> stack = p->first;
894
895 if (!this->debug_escape_hash().empty())
896 {
897 bool match = false;
898 for (std::vector<Named_object*>::const_iterator fn = stack.begin();
899 fn != stack.end();
900 ++fn)
901 match = match || escape_hash_match(this->debug_escape_hash(), (*fn)->message_name());
902 if (!match)
903 {
904 // Escape analysis won't run on these functions, but still
905 // need to tag them, so the caller knows.
906 for (std::vector<Named_object*>::iterator fn = stack.begin();
907 fn != stack.end();
908 ++fn)
909 if ((*fn)->is_function())
910 {
911 Function_type* fntype = (*fn)->func_value()->type();
912 fntype->set_is_tagged();
913
914 std::cerr << "debug-escape-hash disables " << debug_function_name(*fn) << "\n";
915 }
916
917 continue;
918 }
919 for (std::vector<Named_object*>::const_iterator fn = stack.begin();
920 fn != stack.end();
921 ++fn)
922 if ((*fn)->is_function())
923 std::cerr << "debug-escape-hash triggers " << debug_function_name(*fn) << "\n";
924 }
925
704 Escape_context* context = new Escape_context(this, p->second); 926 Escape_context* context = new Escape_context(this, p->second);
705 927
706 // Analyze the flow of each function; build the connection graph. 928 // Analyze the flow of each function; build the connection graph.
707 // This is the assign phase. 929 // This is the assign phase.
708 for (std::vector<Named_object*>::reverse_iterator fn = stack.rbegin(); 930 for (std::vector<Named_object*>::reverse_iterator fn = stack.rbegin();
713 this->assign_connectivity(context, *fn); 935 this->assign_connectivity(context, *fn);
714 } 936 }
715 937
716 // Propagate levels across each dst. This is the flood phase. 938 // Propagate levels across each dst. This is the flood phase.
717 std::set<Node*> dsts = context->dsts(); 939 std::set<Node*> dsts = context->dsts();
940 Unordered_map(Node*, int) escapes;
718 for (std::set<Node*>::iterator n = dsts.begin(); 941 for (std::set<Node*>::iterator n = dsts.begin();
719 n != dsts.end(); 942 n != dsts.end();
720 ++n) 943 ++n)
721 this->propagate_escape(context, *n); 944 {
945 escapes[*n] = (*n)->encoding();
946 this->propagate_escape(context, *n);
947 }
948 for (;;)
949 {
950 // Reflood if the roots' escape states increase. Run until fix point.
951 // This is rare.
952 bool done = true;
953 for (std::set<Node*>::iterator n = dsts.begin();
954 n != dsts.end();
955 ++n)
956 {
957 if ((*n)->object() == NULL
958 && ((*n)->expr() == NULL
959 || ((*n)->expr()->var_expression() == NULL
960 && (*n)->expr()->enclosed_var_expression() == NULL
961 && (*n)->expr()->func_expression() == NULL)))
962 continue;
963 if (escapes[*n] != (*n)->encoding())
964 {
965 done = false;
966 if (this->debug_escape_level() > 2)
967 go_inform((*n)->location(), "Reflooding %s %s",
968 debug_function_name((*n)->state(context, NULL)->fn).c_str(),
969 (*n)->ast_format(this).c_str());
970 escapes[*n] = (*n)->encoding();
971 this->propagate_escape(context, *n);
972 }
973 }
974 if (done)
975 break;
976 }
722 977
723 // Tag each exported function's parameters with escape information. 978 // Tag each exported function's parameters with escape information.
724 for (std::vector<Named_object*>::iterator fn = stack.begin(); 979 for (std::vector<Named_object*>::iterator fn = stack.begin();
725 fn != stack.end(); 980 fn != stack.end();
726 ++fn) 981 ++fn)
732 for (std::vector<Node*>::const_iterator n = noesc.begin(); 987 for (std::vector<Node*>::const_iterator n = noesc.begin();
733 n != noesc.end(); 988 n != noesc.end();
734 ++n) 989 ++n)
735 { 990 {
736 Node::Escape_state* state = (*n)->state(context, NULL); 991 Node::Escape_state* state = (*n)->state(context, NULL);
737 if (((*n)->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE)) 992 if ((*n)->encoding() == Node::ESCAPE_NONE)
738 go_inform((*n)->location(), "%s %s does not escape", 993 go_inform((*n)->location(), "%s %s does not escape",
739 strip_packed_prefix(this, debug_function_name(state->fn)).c_str(), 994 strip_packed_prefix(this, debug_function_name(state->fn)).c_str(),
740 (*n)->ast_format(this).c_str()); 995 (*n)->ast_format(this).c_str());
741 } 996 }
742 // TODO(cmang): Which objects in context->noesc actually don't escape.
743 } 997 }
744 delete context; 998 delete context;
745 } 999 }
746 } 1000 }
747 1001
751 1005
752 class Escape_analysis_discover : public Traverse 1006 class Escape_analysis_discover : public Traverse
753 { 1007 {
754 public: 1008 public:
755 Escape_analysis_discover(Gogo* gogo) 1009 Escape_analysis_discover(Gogo* gogo)
756 : Traverse(traverse_functions), 1010 : Traverse(traverse_functions | traverse_func_declarations),
757 gogo_(gogo), component_ids_() 1011 gogo_(gogo), component_ids_()
758 { } 1012 { }
759 1013
760 int 1014 int
761 function(Named_object*); 1015 function(Named_object*);
1016
1017 int
1018 function_declaration(Named_object*);
762 1019
763 int 1020 int
764 visit(Named_object*); 1021 visit(Named_object*);
765 1022
766 int 1023 int
785 1042
786 // Visit each function. 1043 // Visit each function.
787 1044
788 int 1045 int
789 Escape_analysis_discover::function(Named_object* fn) 1046 Escape_analysis_discover::function(Named_object* fn)
1047 {
1048 this->visit(fn);
1049 return TRAVERSE_CONTINUE;
1050 }
1051
1052 int
1053 Escape_analysis_discover::function_declaration(Named_object* fn)
790 { 1054 {
791 this->visit(fn); 1055 this->visit(fn);
792 return TRAVERSE_CONTINUE; 1056 return TRAVERSE_CONTINUE;
793 } 1057 }
794 1058
831 int min = this->id; 1095 int min = this->id;
832 1096
833 this->stack_.push(fn); 1097 this->stack_.push(fn);
834 min = this->visit_code(fn, min); 1098 min = this->visit_code(fn, min);
835 if ((min == id || min == id + 1) 1099 if ((min == id || min == id + 1)
836 && fn->is_function() 1100 && ((fn->is_function() && fn->func_value()->enclosing() == NULL)
837 && fn->func_value()->enclosing() == NULL) 1101 || fn->is_function_declaration()))
838 { 1102 {
839 bool recursive = min == id; 1103 bool recursive = min == id;
840 std::vector<Named_object*> group; 1104 std::vector<Named_object*> group;
841 1105
842 for (; !this->stack_.empty(); this->stack_.pop()) 1106 for (; !this->stack_.empty(); this->stack_.pop())
1010 Escape_context* context_; 1274 Escape_context* context_;
1011 // The current function being analyzed. 1275 // The current function being analyzed.
1012 Named_object* fn_; 1276 Named_object* fn_;
1013 }; 1277 };
1014 1278
1279 // Helper function to detect self assignment like the following.
1280 //
1281 // func (b *Buffer) Foo() {
1282 // n, m := ...
1283 // b.buf = b.buf[n:m]
1284 // }
1285
1286 static bool
1287 is_self_assignment(Expression* lhs, Expression* rhs)
1288 {
1289 Unary_expression* lue =
1290 (lhs->field_reference_expression() != NULL
1291 ? lhs->field_reference_expression()->expr()->unary_expression()
1292 : lhs->unary_expression());
1293 Var_expression* lve =
1294 (lue != NULL && lue->op() == OPERATOR_MULT ? lue->operand()->var_expression() : NULL);
1295 Array_index_expression* raie = rhs->array_index_expression();
1296 String_index_expression* rsie = rhs->string_index_expression();
1297 Expression* rarray =
1298 (raie != NULL && raie->end() != NULL && raie->array()->type()->is_slice_type()
1299 ? raie->array()
1300 : (rsie != NULL && rsie->type()->is_string_type() ? rsie->string() : NULL));
1301 Unary_expression* rue =
1302 (rarray != NULL && rarray->field_reference_expression() != NULL
1303 ? rarray->field_reference_expression()->expr()->unary_expression()
1304 : (rarray != NULL ? rarray->unary_expression() : NULL));
1305 Var_expression* rve =
1306 (rue != NULL && rue->op() == OPERATOR_MULT ? rue->operand()->var_expression() : NULL);
1307 return lve != NULL && rve != NULL
1308 && lve->named_object() == rve->named_object();
1309 }
1310
1015 // Model statements within a function as assignments and flows between nodes. 1311 // Model statements within a function as assignments and flows between nodes.
1016 1312
1017 int 1313 int
1018 Escape_analysis_assign::statement(Block*, size_t*, Statement* s) 1314 Escape_analysis_assign::statement(Block*, size_t*, Statement* s)
1019 { 1315 {
1055 if (var->is_variable() 1351 if (var->is_variable()
1056 && var->var_value()->init() != NULL) 1352 && var->var_value()->init() != NULL)
1057 { 1353 {
1058 Node* init_node = Node::make_node(var->var_value()->init()); 1354 Node* init_node = Node::make_node(var->var_value()->init());
1059 this->assign(var_node, init_node); 1355 this->assign(var_node, init_node);
1356 }
1357 }
1358 break;
1359
1360 case Statement::STATEMENT_TEMPORARY:
1361 {
1362 Expression* init = s->temporary_statement()->init();
1363 if (init != NULL)
1364 {
1365 Node* n = Node::make_node(init);
1366 if (s->temporary_statement()->value_escapes())
1367 this->assign(this->context_->sink(), n);
1368 else
1369 this->assign(Node::make_node(s), n);
1060 } 1370 }
1061 } 1371 }
1062 break; 1372 break;
1063 1373
1064 case Statement::STATEMENT_LABEL: 1374 case Statement::STATEMENT_LABEL:
1082 case Statement::STATEMENT_SWITCH: 1392 case Statement::STATEMENT_SWITCH:
1083 case Statement::STATEMENT_TYPE_SWITCH: 1393 case Statement::STATEMENT_TYPE_SWITCH:
1084 // Want to model the assignment of each case variable to the switched upon 1394 // Want to model the assignment of each case variable to the switched upon
1085 // variable. This should be lowered into assignment statements; nothing 1395 // variable. This should be lowered into assignment statements; nothing
1086 // to here if that's the case. 1396 // to here if that's the case.
1087 // TODO(cmang): Verify.
1088 break; 1397 break;
1089 1398
1090 case Statement::STATEMENT_ASSIGNMENT: 1399 case Statement::STATEMENT_ASSIGNMENT:
1091 { 1400 {
1092 Assignment_statement* assn = s->assignment_statement(); 1401 Assignment_statement* assn = s->assignment_statement();
1093 Node* lhs = Node::make_node(assn->lhs()); 1402 Expression* lhs = assn->lhs();
1094 Node* rhs = Node::make_node(assn->rhs()); 1403 Expression* rhs = assn->rhs();
1095 1404 Node* lhs_node = Node::make_node(lhs);
1096 // TODO(cmang): Add special case for escape analysis no-op: 1405 Node* rhs_node = Node::make_node(rhs);
1097 // func (b *Buffer) Foo() { 1406
1098 // n, m := ... 1407 // Filter out the following special case.
1099 // b.buf = b.buf[n:m] 1408 //
1100 // } 1409 // func (b *Buffer) Foo() {
1101 // This is okay for now, it just means b escapes; it is conservative. 1410 // n, m := ...
1102 this->assign(lhs, rhs); 1411 // b.buf = b.buf[n:m]
1412 // }
1413 //
1414 // This assignment is a no-op for escape analysis,
1415 // it does not store any new pointers into b that were not already there.
1416 // However, without this special case b will escape.
1417 if (is_self_assignment(lhs, rhs))
1418 {
1419 if (debug_level != 0)
1420 go_inform(s->location(), "%s ignoring self-assignment to %s",
1421 strip_packed_prefix(gogo, this->context_->current_function_name()).c_str(),
1422 lhs_node->ast_format(gogo).c_str());
1423 break;
1424 }
1425
1426 this->assign(lhs_node, rhs_node);
1103 } 1427 }
1104 break; 1428 break;
1105 1429
1106 case Statement::STATEMENT_SEND: 1430 case Statement::STATEMENT_SEND:
1107 { 1431 {
1110 } 1434 }
1111 break; 1435 break;
1112 1436
1113 case Statement::STATEMENT_DEFER: 1437 case Statement::STATEMENT_DEFER:
1114 if (this->context_->loop_depth() == 1) 1438 if (this->context_->loop_depth() == 1)
1115 break; 1439 {
1440 // Defer statement may need to allocate a thunk. When it is
1441 // not inside a loop, this can be stack allocated, as it
1442 // runs before the function finishes.
1443 Node* n = Node::make_node(s);
1444 n->set_encoding(Node::ESCAPE_NONE);
1445 break;
1446 }
1116 // fallthrough 1447 // fallthrough
1117 1448
1118 case Statement::STATEMENT_GO: 1449 case Statement::STATEMENT_GO:
1119 { 1450 {
1120 // Defer f(x) or go f(x). 1451 // Defer f(x) or go f(x).
1137 } 1468 }
1138 } 1469 }
1139 } 1470 }
1140 break; 1471 break;
1141 1472
1142 // TODO(cmang): Associate returned values with dummy return nodes.
1143
1144 default: 1473 default:
1145 break; 1474 break;
1146 } 1475 }
1147 return TRAVERSE_SKIP_COMPONENTS; 1476 return TRAVERSE_SKIP_COMPONENTS;
1477 }
1478
1479 // Helper function to emit moved-to-heap diagnostics.
1480
1481 static void
1482 move_to_heap(Gogo* gogo, Expression *expr)
1483 {
1484 Named_object* no;
1485 if (expr->var_expression() != NULL)
1486 no = expr->var_expression()->named_object();
1487 else if (expr->enclosed_var_expression() != NULL)
1488 no = expr->enclosed_var_expression()->variable();
1489 else
1490 return;
1491
1492 if ((no->is_variable()
1493 && !no->var_value()->is_global())
1494 || no->is_result_variable())
1495 {
1496 Node* n = Node::make_node(expr);
1497 if (gogo->debug_escape_level() != 0)
1498 go_inform(n->definition_location(),
1499 "moved to heap: %s",
1500 n->ast_format(gogo).c_str());
1501 if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
1502 go_error_at(expr->location(),
1503 "%s escapes to heap, not allowed in runtime",
1504 n->ast_format(gogo).c_str());
1505 }
1148 } 1506 }
1149 1507
1150 // Model expressions within a function as assignments and flows between nodes. 1508 // Model expressions within a function as assignments and flows between nodes.
1151 1509
1152 int 1510 int
1159 Node* n = Node::make_node(*pexpr); 1517 Node* n = Node::make_node(*pexpr);
1160 if ((n->encoding() & ESCAPE_MASK) != int(Node::ESCAPE_HEAP) 1518 if ((n->encoding() & ESCAPE_MASK) != int(Node::ESCAPE_HEAP)
1161 && n->is_big(this->context_)) 1519 && n->is_big(this->context_))
1162 { 1520 {
1163 if (debug_level > 1) 1521 if (debug_level > 1)
1164 go_inform((*pexpr)->location(), "too large for stack"); 1522 go_inform((*pexpr)->location(), "%s too large for stack",
1523 n->ast_format(gogo).c_str());
1524 move_to_heap(gogo, *pexpr);
1165 n->set_encoding(Node::ESCAPE_HEAP); 1525 n->set_encoding(Node::ESCAPE_HEAP);
1166 (*pexpr)->address_taken(true); 1526 (*pexpr)->address_taken(true);
1167 this->assign(this->context_->sink(), n); 1527 this->assign(this->context_->sink(), n);
1168 } 1528 }
1169 1529
1182 switch ((*pexpr)->classification()) 1542 switch ((*pexpr)->classification())
1183 { 1543 {
1184 case Expression::EXPRESSION_CALL: 1544 case Expression::EXPRESSION_CALL:
1185 { 1545 {
1186 Call_expression* call = (*pexpr)->call_expression(); 1546 Call_expression* call = (*pexpr)->call_expression();
1187 this->call(call); 1547 if (call->is_builtin())
1188 1548 {
1549 Builtin_call_expression* bce = call->builtin_call_expression();
1550 switch (bce->code())
1551 {
1552 case Builtin_call_expression::BUILTIN_PANIC:
1553 {
1554 // Argument could leak through recover.
1555 Node* panic_arg = Node::make_node(call->args()->front());
1556 this->assign(this->context_->sink(), panic_arg);
1557 }
1558 break;
1559
1560 case Builtin_call_expression::BUILTIN_APPEND:
1561 {
1562 // The contents being appended leak.
1563 if (call->is_varargs())
1564 {
1565 // append(slice1, slice2...) -- slice2 itself does not escape, but contents do
1566 Node* appended = Node::make_node(call->args()->back());
1567 this->assign_deref(this->context_->sink(), appended);
1568 if (debug_level > 2)
1569 go_inform((*pexpr)->location(),
1570 "special treatment of append(slice1, slice2...)");
1571 }
1572 else
1573 {
1574 for (Expression_list::const_iterator pa =
1575 call->args()->begin() + 1;
1576 pa != call->args()->end();
1577 ++pa)
1578 {
1579 Node* arg = Node::make_node(*pa);
1580 this->assign(this->context_->sink(), arg);
1581 }
1582 }
1583
1584 // The content of the original slice leaks as well.
1585 Node* appendee = Node::make_node(call->args()->front());
1586 this->assign_deref(this->context_->sink(), appendee);
1587 }
1588 break;
1589
1590 case Builtin_call_expression::BUILTIN_COPY:
1591 {
1592 // Lose track of the copied content.
1593 Node* copied = Node::make_node(call->args()->back());
1594 this->assign_deref(this->context_->sink(), copied);
1595 }
1596 break;
1597
1598 default:
1599 break;
1600 }
1601 break;
1602 }
1189 Func_expression* fe = call->fn()->func_expression(); 1603 Func_expression* fe = call->fn()->func_expression();
1190 if (fe != NULL && fe->is_runtime_function()) 1604 if (fe != NULL && fe->is_runtime_function())
1191 { 1605 {
1192 switch (fe->runtime_code()) 1606 switch (fe->runtime_code())
1193 { 1607 {
1194 case Runtime::GOPANIC:
1195 {
1196 // Argument could leak through recover.
1197 Node* panic_arg = Node::make_node(call->args()->front());
1198 this->assign(this->context_->sink(), panic_arg);
1199 }
1200 break;
1201
1202 case Runtime::GROWSLICE:
1203 {
1204 // The contents being appended leak.
1205 if (call->is_varargs())
1206 {
1207 Node* appended = Node::make_node(call->args()->back());
1208 this->assign_deref(this->context_->sink(), appended);
1209 }
1210 else
1211 {
1212 for (Expression_list::const_iterator pa =
1213 call->args()->begin();
1214 pa != call->args()->end();
1215 ++pa)
1216 {
1217 Node* arg = Node::make_node(*pa);
1218 this->assign(this->context_->sink(), arg);
1219 }
1220 }
1221
1222 if (debug_level > 2)
1223 go_error_at((*pexpr)->location(),
1224 "special treatment of append(slice1, slice2...)");
1225
1226 // The content of the original slice leaks as well.
1227 Node* appendee = Node::make_node(call->args()->front());
1228 this->assign_deref(this->context_->sink(), appendee);
1229 }
1230 break;
1231
1232 case Runtime::SLICECOPY:
1233 case Runtime::SLICESTRINGCOPY:
1234 case Runtime::TYPEDSLICECOPY:
1235 {
1236 // Lose track of the copied content.
1237 Node* copied = Node::make_node(call->args()->back());
1238 this->assign_deref(this->context_->sink(), copied);
1239 }
1240 break;
1241
1242 case Runtime::MAKECHAN: 1608 case Runtime::MAKECHAN:
1609 case Runtime::MAKECHAN64:
1243 case Runtime::MAKEMAP: 1610 case Runtime::MAKEMAP:
1244 case Runtime::MAKESLICE: 1611 case Runtime::MAKESLICE:
1245 case Runtime::MAKESLICE64: 1612 case Runtime::MAKESLICE64:
1246 case Runtime::SLICEBYTETOSTRING: 1613 this->context_->track(n);
1247 case Runtime::SLICERUNETOSTRING:
1248 case Runtime::STRINGTOSLICEBYTE:
1249 case Runtime::STRINGTOSLICERUNE:
1250 case Runtime::CONCATSTRINGS:
1251 case Runtime::CONCATSTRING2:
1252 case Runtime::CONCATSTRING3:
1253 case Runtime::CONCATSTRING4:
1254 case Runtime::CONCATSTRING5:
1255 case Runtime::CONSTRUCT_MAP:
1256 case Runtime::INTSTRING:
1257 {
1258 Node* runtime_node = Node::make_node(fe);
1259 this->context_->track(runtime_node);
1260 }
1261 break; 1614 break;
1615
1616 case Runtime::MAPASSIGN:
1617 {
1618 // Map key escapes. The last argument is the address
1619 // of the key.
1620 Node* key_node = Node::make_node(call->args()->back());
1621 this->assign_deref(this->context_->sink(), key_node);
1622 }
1623 break;
1624
1625 case Runtime::IFACEE2T2:
1626 case Runtime::IFACEI2T2:
1627 {
1628 // x, ok = v.(T), where T is non-pointer non-interface,
1629 // is lowered to
1630 // ok = IFACEI2T2(type, v, (void*)&tmp_x)
1631 // Here v flows to tmp_x.
1632 // Note: other IFACEX2Y2 returns the conversion result.
1633 // Those are handled in ::assign.
1634 Node* src_node = Node::make_node(call->args()->at(1));
1635 Node* dst_node;
1636 Expression* arg2 = call->args()->at(2);
1637 // Try to pull tmp_x out of the arg2 expression, and let v
1638 // flows into it, instead of simply dereference arg2,
1639 // which looks like dereference of an arbitrary pointer
1640 // and causes v immediately escape.
1641 // The expression form matches statement.cc,
1642 // Tuple_type_guard_assignment_statement::lower_to_object_type.
1643 Unary_expression* ue =
1644 (arg2->conversion_expression() != NULL
1645 ? arg2->conversion_expression()->expr()->unary_expression()
1646 : arg2->unary_expression());
1647 if (ue != NULL && ue->op() == OPERATOR_AND)
1648 {
1649 if (!ue->operand()->type()->has_pointer())
1650 // Don't bother flowing non-pointer.
1651 break;
1652 dst_node = Node::make_node(ue->operand());
1653 }
1654 else
1655 dst_node = this->context_->add_dereference(Node::make_node(arg2));
1656 this->assign(dst_node, src_node);
1657 }
1658 break;
1262 1659
1263 default: 1660 default:
1264 break; 1661 break;
1265 } 1662 }
1266 } 1663 }
1664 else
1665 this->call(call);
1267 } 1666 }
1268 break; 1667 break;
1269 1668
1270 case Expression::EXPRESSION_ALLOCATION: 1669 case Expression::EXPRESSION_ALLOCATION:
1271 { 1670 // This is Runtime::NEW.
1272 // Same as above; this is Runtime::NEW. 1671 this->context_->track(n);
1273 Node* alloc_node = Node::make_node(*pexpr); 1672 break;
1274 this->context_->track(alloc_node); 1673
1275 } 1674 case Expression::EXPRESSION_STRING_CONCAT:
1675 this->context_->track(n);
1276 break; 1676 break;
1277 1677
1278 case Expression::EXPRESSION_CONVERSION: 1678 case Expression::EXPRESSION_CONVERSION:
1279 { 1679 {
1280 Type_conversion_expression* tce = (*pexpr)->conversion_expression(); 1680 Type_conversion_expression* tce = (*pexpr)->conversion_expression();
1681 Type* ft = tce->expr()->type();
1682 Type* tt = tce->type();
1683 if ((ft->is_string_type() && tt->is_slice_type())
1684 || (ft->is_slice_type() && tt->is_string_type())
1685 || (ft->integer_type() != NULL && tt->is_string_type()))
1686 {
1687 // string([]byte), string([]rune), []byte(string), []rune(string), string(rune)
1688 this->context_->track(n);
1689 break;
1690 }
1281 Node* tce_node = Node::make_node(tce); 1691 Node* tce_node = Node::make_node(tce);
1282 Node* converted = Node::make_node(tce->expr()); 1692 Node* converted = Node::make_node(tce->expr());
1283 this->context_->track(tce_node); 1693 this->context_->track(tce_node);
1284 1694
1285 this->assign(tce_node, converted); 1695 this->assign(tce_node, converted);
1393 Expression_list::const_iterator p = sce->vals()->begin(); 1803 Expression_list::const_iterator p = sce->vals()->begin();
1394 ++p; 1804 ++p;
1395 for (; p != sce->vals()->end(); ++p) 1805 for (; p != sce->vals()->end(); ++p)
1396 { 1806 {
1397 Node* enclosed_node = Node::make_node(*p); 1807 Node* enclosed_node = Node::make_node(*p);
1398 Node::Escape_state* state = 1808 this->context_->track(enclosed_node);
1399 enclosed_node->state(this->context_, NULL);
1400 state->loop_depth = this->context_->loop_depth();
1401 this->assign(closure_node, enclosed_node); 1809 this->assign(closure_node, enclosed_node);
1402 } 1810 }
1403 } 1811 }
1404 } 1812 }
1405 break; 1813 break;
1406 1814
1407 case Expression::EXPRESSION_UNARY: 1815 case Expression::EXPRESSION_UNARY:
1408 { 1816 {
1409 if ((*pexpr)->unary_expression()->op() != OPERATOR_AND)
1410 break;
1411
1412 Node* addr_node = Node::make_node(*pexpr);
1413 this->context_->track(addr_node);
1414
1415 Expression* operand = (*pexpr)->unary_expression()->operand(); 1817 Expression* operand = (*pexpr)->unary_expression()->operand();
1416 Named_object* var = NULL; 1818
1417 if (operand->var_expression() != NULL) 1819 if ((*pexpr)->unary_expression()->op() == OPERATOR_AND)
1418 var = operand->var_expression()->named_object(); 1820 {
1419 else if (operand->enclosed_var_expression() != NULL) 1821 this->context_->track(n);
1420 var = operand->enclosed_var_expression()->variable(); 1822
1421 else if (operand->temporary_reference_expression() != NULL) 1823 Named_object* var = NULL;
1422 { 1824 if (operand->var_expression() != NULL)
1423 // Found in runtime/chanbarrier_test.go. The address of a struct 1825 var = operand->var_expression()->named_object();
1424 // reference is usually a heap expression, except when it is a part 1826 else if (operand->enclosed_var_expression() != NULL)
1425 // of a case statement. In that case, it is lowered into a 1827 var = operand->enclosed_var_expression()->variable();
1426 // temporary reference and never linked to the heap expression that 1828
1427 // initializes it. In general, when taking the address of some 1829 if (var != NULL
1428 // temporary, the analysis should really be looking at the initial 1830 && ((var->is_variable() && var->var_value()->is_parameter())
1429 // value of that temporary. 1831 || var->is_result_variable()))
1430 Temporary_reference_expression* tre = 1832 {
1431 operand->temporary_reference_expression(); 1833 Node::Escape_state* addr_state = n->state(this->context_, NULL);
1432 if (tre->statement() != NULL 1834 addr_state->loop_depth = 1;
1433 && tre->statement()->temporary_statement()->init() != NULL) 1835 break;
1434 { 1836 }
1435 Expression* init = 1837 }
1436 tre->statement()->temporary_statement()->init(); 1838
1437 Node* init_node = Node::make_node(init); 1839 if ((*pexpr)->unary_expression()->op() != OPERATOR_AND
1438 this->assign(addr_node, init_node); 1840 && (*pexpr)->unary_expression()->op() != OPERATOR_MULT)
1439 } 1841 break;
1440 } 1842
1441 1843 // For &x and *x, use the loop depth of x if known.
1442 if (var == NULL) 1844 Node::Escape_state* expr_state = n->state(this->context_, NULL);
1443 break; 1845 Node* operand_node = Node::make_node(operand);
1444 1846 Node::Escape_state* operand_state = operand_node->state(this->context_, NULL);
1445 if (var->is_variable() 1847 if (operand_state->loop_depth != 0)
1446 && !var->var_value()->is_parameter()) 1848 expr_state->loop_depth = operand_state->loop_depth;
1447 { 1849 }
1448 // For &x, use the loop depth of x if known. 1850 break;
1449 Node::Escape_state* addr_state = 1851
1450 addr_node->state(this->context_, NULL); 1852 case Expression::EXPRESSION_ARRAY_INDEX:
1451 Node* operand_node = Node::make_node(operand); 1853 {
1452 Node::Escape_state* operand_state = 1854 Array_index_expression* aie = (*pexpr)->array_index_expression();
1453 operand_node->state(this->context_, NULL); 1855
1454 if (operand_state->loop_depth != 0) 1856 // Propagate the loopdepth to element.
1455 addr_state->loop_depth = operand_state->loop_depth; 1857 Node* array_node = Node::make_node(aie->array());
1456 } 1858 Node::Escape_state* elem_state = n->state(this->context_, NULL);
1457 else if ((var->is_variable() 1859 Node::Escape_state* array_state = array_node->state(this->context_, NULL);
1458 && var->var_value()->is_parameter()) 1860 elem_state->loop_depth = array_state->loop_depth;
1459 || var->is_result_variable()) 1861
1460 { 1862 if (aie->end() != NULL && !aie->array()->type()->is_slice_type())
1461 Node::Escape_state* addr_state = 1863 {
1462 addr_node->state(this->context_, NULL); 1864 // Slicing an array. This effectively takes the address of the array.
1463 addr_state->loop_depth = 1; 1865 Expression* addr = Expression::make_unary(OPERATOR_AND, aie->array(),
1464 } 1866 aie->location());
1867 Node* addr_node = Node::make_node(addr);
1868 n->set_child(addr_node);
1869 this->context_->track(addr_node);
1870
1871 Node::Escape_state* addr_state = addr_node->state(this->context_, NULL);
1872 addr_state->loop_depth = array_state->loop_depth;
1873 }
1874 }
1875 break;
1876
1877 case Expression::EXPRESSION_FIELD_REFERENCE:
1878 {
1879 // Propagate the loopdepth to field.
1880 Node* struct_node =
1881 Node::make_node((*pexpr)->field_reference_expression()->expr());
1882 Node::Escape_state* field_state = n->state(this->context_, NULL);
1883 Node::Escape_state* struct_state = struct_node->state(this->context_, NULL);
1884 field_state->loop_depth = struct_state->loop_depth;
1465 } 1885 }
1466 break; 1886 break;
1467 1887
1468 default: 1888 default:
1469 break; 1889 break;
1525 (*p)->ast_format(gogo).c_str()); 1945 (*p)->ast_format(gogo).c_str());
1526 this->assign(this->context_->sink(), *p); 1946 this->assign(this->context_->sink(), *p);
1527 } 1947 }
1528 1948
1529 this->context_->init_retvals(call_node, fntype); 1949 this->context_->init_retvals(call_node, fntype);
1950
1951 // It could be a closure call that returns captured variable.
1952 // Model this by flowing the func expression to result.
1953 // See issue #14409.
1954 Node* fn_node = Node::make_node(call->fn());
1955 std::vector<Node*> retvals = call_node->state(this->context_, NULL)->retvals;
1956 for (std::vector<Node*>::const_iterator p = retvals.begin();
1957 p != retvals.end();
1958 ++p)
1959 this->assign_deref(*p, fn_node);
1960
1530 return; 1961 return;
1531 } 1962 }
1532 1963
1533 // If FN is an untagged function. 1964 // If FN is an untagged function.
1534 if (fn != NULL 1965 if (fn != NULL
1539 go_inform(call->location(), "esccall:: %s in recursive group", 1970 go_inform(call->location(), "esccall:: %s in recursive group",
1540 call_node->ast_format(gogo).c_str()); 1971 call_node->ast_format(gogo).c_str());
1541 1972
1542 Function* f = fn->named_object()->func_value(); 1973 Function* f = fn->named_object()->func_value();
1543 const Bindings* callee_bindings = f->block()->bindings(); 1974 const Bindings* callee_bindings = f->block()->bindings();
1544 1975 Function::Results* results = f->result_variables();
1545 const Typed_identifier_list* results = fntype->results();
1546 if (results != NULL) 1976 if (results != NULL)
1547 { 1977 {
1548 // Setup output list on this call node. 1978 // Setup output list on this call node.
1549 Node::Escape_state* state = call_node->state(this->context_, NULL); 1979 Node::Escape_state* state = call_node->state(this->context_, NULL);
1550 for (Typed_identifier_list::const_iterator p1 = results->begin(); 1980 for (Function::Results::const_iterator p1 = results->begin();
1551 p1 != results->end(); 1981 p1 != results->end();
1552 ++p1) 1982 ++p1)
1553 { 1983 {
1554 if (p1->name().empty() || Gogo::is_sink_name(p1->name())) 1984 Node* result_node = Node::make_node(*p1);
1555 continue;
1556
1557 Named_object* result_no =
1558 callee_bindings->lookup_local(p1->name());
1559 go_assert(result_no != NULL);
1560 Node* result_node = Node::make_node(result_no);
1561 state->retvals.push_back(result_node); 1985 state->retvals.push_back(result_node);
1562 } 1986 }
1563 } 1987 }
1564 1988
1565 std::vector<Node*>::iterator p = arg_nodes.begin(); 1989 std::vector<Node*>::iterator p = arg_nodes.begin();
1566 if (fntype->is_method() 1990 if (fntype->is_method())
1567 && fntype->receiver()->type()->has_pointer())
1568 { 1991 {
1569 std::string rcvr_name = fntype->receiver()->name(); 1992 std::string rcvr_name = fntype->receiver()->name();
1570 if (rcvr_name.empty() || Gogo::is_sink_name(rcvr_name)) 1993 if (rcvr_name.empty() || Gogo::is_sink_name(rcvr_name)
1994 || !fntype->receiver()->type()->has_pointer())
1571 ; 1995 ;
1572 else 1996 else
1573 { 1997 {
1574 Named_object* rcvr_no = 1998 Named_object* rcvr_no =
1575 callee_bindings->lookup_local(fntype->receiver()->name()); 1999 callee_bindings->lookup_local(fntype->receiver()->name());
1576 go_assert(rcvr_no != NULL); 2000 go_assert(rcvr_no != NULL);
1577 Node* rcvr_node = Node::make_node(rcvr_no); 2001 Node* rcvr_node = Node::make_node(rcvr_no);
1578 this->assign(rcvr_node, *p); 2002 if (fntype->receiver()->type()->points_to() == NULL
2003 && (*p)->expr()->type()->points_to() != NULL)
2004 // This is a call to a value method that has been lowered into a call
2005 // to a pointer method. Gccgo generates a pointer method for all
2006 // method calls and takes the address of the value passed as the
2007 // receiver then immediately dereferences it within the function.
2008 // In this case, the receiver address does not escape; its content
2009 // flows to the call.
2010 this->assign_deref(rcvr_node, *p);
2011 else
2012 this->assign(rcvr_node, *p);
1579 } 2013 }
1580 ++p; 2014 ++p;
1581 } 2015 }
1582 2016
1583 const Typed_identifier_list* til = fntype->parameters(); 2017 const Typed_identifier_list* til = fntype->parameters();
1626 this->context_->init_retvals(call_node, fntype); 2060 this->context_->init_retvals(call_node, fntype);
1627 2061
1628 // Receiver. 2062 // Receiver.
1629 std::vector<Node*>::iterator p = arg_nodes.begin(); 2063 std::vector<Node*>::iterator p = arg_nodes.begin();
1630 if (fntype->is_method() 2064 if (fntype->is_method()
1631 && fntype->receiver()->type()->has_pointer()
1632 && p != arg_nodes.end()) 2065 && p != arg_nodes.end())
1633 { 2066 {
1634 // First argument to call will be the receiver. 2067 // First argument to call will be the receiver.
1635 std::string* note = fntype->receiver()->note(); 2068 std::string* note = fntype->receiver()->note();
1636 if (fntype->receiver()->type()->points_to() == NULL 2069 if (fntype->receiver()->type()->points_to() == NULL
1637 && (*p)->expr()->unary_expression() != NULL 2070 && (*p)->expr()->type()->points_to() != NULL)
1638 && (*p)->expr()->unary_expression()->op() == OPERATOR_AND) 2071 // This is a call to a value method that has been lowered into a call
1639 { 2072 // to a pointer method. Gccgo generates a pointer method for all
1640 // This is a call to a value method that has been lowered into a call 2073 // method calls and takes the address of the value passed as the
1641 // to a pointer method. Gccgo generates a pointer method for all 2074 // receiver then immediately dereferences it within the function.
1642 // method calls and takes the address of the value passed as the 2075 // In this case, the receiver address does not escape; its content
1643 // receiver then immediately dereferences it within the function. 2076 // flows to the call.
1644 // In this case, the receiver does not escape. 2077 this->assign_from_note(note, call_state->retvals,
1645 } 2078 this->context_->add_dereference(*p));
1646 else 2079 else
1647 { 2080 {
1648 if (!Type::are_identical(fntype->receiver()->type(), 2081 if (!Type::are_identical(fntype->receiver()->type(),
1649 (*p)->expr()->type(), true, NULL)) 2082 (*p)->expr()->type(), Type::COMPARE_TAGS,
2083 NULL))
1650 { 2084 {
1651 // This will be converted later, preemptively track it instead 2085 // This will be converted later, preemptively track it instead
1652 // of its conversion expression which will show up in a later pass. 2086 // of its conversion expression which will show up in a later pass.
1653 this->context_->track(*p); 2087 this->context_->track(*p);
1654 } 2088 }
1663 for (Typed_identifier_list::const_iterator pn = til->begin(); 2097 for (Typed_identifier_list::const_iterator pn = til->begin();
1664 pn != til->end() && p != arg_nodes.end(); 2098 pn != til->end() && p != arg_nodes.end();
1665 ++pn, ++p) 2099 ++pn, ++p)
1666 { 2100 {
1667 if (!Type::are_identical(pn->type(), (*p)->expr()->type(), 2101 if (!Type::are_identical(pn->type(), (*p)->expr()->type(),
1668 true, NULL)) 2102 Type::COMPARE_TAGS, NULL))
1669 { 2103 {
1670 // This will be converted later, preemptively track it instead 2104 // This will be converted later, preemptively track it instead
1671 // of its conversion expression which will show up in a later pass. 2105 // of its conversion expression which will show up in a later pass.
1672 this->context_->track(*p); 2106 this->context_->track(*p);
1673 } 2107 }
1674 2108
1675 // TODO(cmang): Special care for varargs parameter?
1676 Type* t = pn->type(); 2109 Type* t = pn->type();
1677 if (t != NULL 2110 if (t != NULL
1678 && t->has_pointer()) 2111 && t->has_pointer())
1679 { 2112 {
1680 std::string* note = pn->note(); 2113 std::string* note = pn->note();
1681 int enc = this->assign_from_note(note, call_state->retvals, *p); 2114 int enc = this->assign_from_note(note, call_state->retvals, *p);
1682 if (enc == Node::ESCAPE_NONE 2115 if (enc == Node::ESCAPE_NONE
1683 && (call->is_deferred() 2116 && !call->is_deferred()
1684 || call->is_concurrent())) 2117 && !call->is_concurrent())
1685 { 2118 {
1686 // TODO(cmang): Mark the argument as strictly non-escaping. 2119 // TODO(cmang): Mark the argument as strictly non-escaping?
2120 // In the gc compiler this is for limiting the lifetime of
2121 // temporaries. We probably don't need this?
1687 } 2122 }
1688 } 2123 }
1689 } 2124 }
1690 2125
1691 for (; p != arg_nodes.end(); ++p) 2126 for (; p != arg_nodes.end(); ++p)
1716 dst->ast_format(gogo).c_str(), dst->details().c_str(), 2151 dst->ast_format(gogo).c_str(), dst->details().c_str(),
1717 dst->op_format().c_str(), 2152 dst->op_format().c_str(),
1718 src->ast_format(gogo).c_str(), src->details().c_str(), 2153 src->ast_format(gogo).c_str(), src->details().c_str(),
1719 src->op_format().c_str()); 2154 src->op_format().c_str());
1720 2155
1721 if (dst->expr() != NULL) 2156 if (dst->is_indirect())
2157 // Lose track of the dereference.
2158 dst = this->context_->sink();
2159 else if (dst->expr() != NULL)
1722 { 2160 {
1723 // Analyze the lhs of the assignment. 2161 // Analyze the lhs of the assignment.
1724 // Replace DST with this->context_->sink() if we can't track it. 2162 // Replace DST with this->context_->sink() if we can't track it.
1725 Expression* e = dst->expr(); 2163 Expression* e = dst->expr();
1726 switch (e->classification()) 2164 switch (e->classification())
1783 2221
1784 dst = this->context_->sink(); 2222 dst = this->context_->sink();
1785 } 2223 }
1786 break; 2224 break;
1787 2225
2226 case Expression::EXPRESSION_TEMPORARY_REFERENCE:
2227 {
2228 // Temporary is tracked through the underlying Temporary_statement.
2229 Temporary_statement* t =
2230 dst->expr()->temporary_reference_expression()->statement();
2231 if (t->value_escapes())
2232 dst = this->context_->sink();
2233 else
2234 dst = Node::make_node(t);
2235 }
2236 break;
2237
1788 default: 2238 default:
1789 // TODO(cmang): Add debugging info here: only a few expressions 2239 // TODO(cmang): Add debugging info here: only a few expressions
1790 // should leave DST unmodified. 2240 // should leave DST unmodified.
1791 break; 2241 break;
1792 } 2242 }
1793 } 2243 }
1794 2244
1795 if (src->expr() != NULL) 2245 if (src->object() != NULL)
2246 this->flows(dst, src);
2247 else if (src->is_indirect())
2248 this->flows(dst, src);
2249 else if (src->expr() != NULL)
1796 { 2250 {
1797 Expression* e = src->expr(); 2251 Expression* e = src->expr();
1798 switch (e->classification()) 2252 switch (e->classification())
1799 { 2253 {
1800 case Expression::EXPRESSION_VAR_REFERENCE: 2254 case Expression::EXPRESSION_VAR_REFERENCE:
2255 case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
1801 // DST = var 2256 // DST = var
1802 case Expression::EXPRESSION_HEAP: 2257 case Expression::EXPRESSION_HEAP:
1803 // DST = &T{...}. 2258 // DST = &T{...}.
1804 case Expression::EXPRESSION_FIXED_ARRAY_CONSTRUCTION: 2259 case Expression::EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
1805 case Expression::EXPRESSION_SLICE_CONSTRUCTION: 2260 case Expression::EXPRESSION_SLICE_CONSTRUCTION:
1810 // DST = T{...}. 2265 // DST = T{...}.
1811 case Expression::EXPRESSION_ALLOCATION: 2266 case Expression::EXPRESSION_ALLOCATION:
1812 // DST = new(T). 2267 // DST = new(T).
1813 case Expression::EXPRESSION_BOUND_METHOD: 2268 case Expression::EXPRESSION_BOUND_METHOD:
1814 // DST = x.M. 2269 // DST = x.M.
2270 case Expression::EXPRESSION_STRING_CONCAT:
2271 // DST = str1 + str2
1815 this->flows(dst, src); 2272 this->flows(dst, src);
1816 break; 2273 break;
1817 2274
1818 case Expression::EXPRESSION_UNSAFE_CONVERSION: 2275 case Expression::EXPRESSION_UNSAFE_CONVERSION:
1819 { 2276 {
1821 Node* underlying_node = Node::make_node(underlying); 2278 Node* underlying_node = Node::make_node(underlying);
1822 this->assign(dst, underlying_node); 2279 this->assign(dst, underlying_node);
1823 } 2280 }
1824 break; 2281 break;
1825 2282
1826 case Expression::EXPRESSION_ENCLOSED_VAR_REFERENCE:
1827 {
1828 Named_object* var = e->enclosed_var_expression()->variable();
1829 Node* var_node = Node::make_node(var);
1830 this->flows(dst, var_node);
1831 }
1832 break;
1833
1834 case Expression::EXPRESSION_CALL: 2283 case Expression::EXPRESSION_CALL:
1835 { 2284 {
1836 Call_expression* call = e->call_expression(); 2285 Call_expression* call = e->call_expression();
2286 if (call->is_builtin())
2287 {
2288 Builtin_call_expression* bce = call->builtin_call_expression();
2289 if (bce->code() == Builtin_call_expression::BUILTIN_APPEND)
2290 {
2291 // Append returns the first argument.
2292 // The subsequent arguments are already leaked because
2293 // they are operands to append.
2294 Node* appendee = Node::make_node(call->args()->front());
2295 this->assign(dst, appendee);
2296 }
2297 break;
2298 }
1837 Func_expression* fe = call->fn()->func_expression(); 2299 Func_expression* fe = call->fn()->func_expression();
1838 if (fe != NULL && fe->is_runtime_function()) 2300 if (fe != NULL && fe->is_runtime_function())
1839 { 2301 {
1840 switch (fe->runtime_code()) 2302 switch (fe->runtime_code())
1841 { 2303 {
1842 case Runtime::GROWSLICE:
1843 {
1844 // Append returns the first argument.
1845 // The subsequent arguments are already leaked because
1846 // they are operands to append.
1847 Node* appendee = Node::make_node(call->args()->front());
1848 this->assign(dst, appendee);
1849 break;
1850 }
1851
1852 case Runtime::MAKECHAN: 2304 case Runtime::MAKECHAN:
2305 case Runtime::MAKECHAN64:
1853 case Runtime::MAKEMAP: 2306 case Runtime::MAKEMAP:
1854 case Runtime::MAKESLICE: 2307 case Runtime::MAKESLICE:
1855 case Runtime::MAKESLICE64: 2308 case Runtime::MAKESLICE64:
1856 // DST = make(...). 2309 // DST = make(...).
1857 case Runtime::SLICEBYTETOSTRING: 2310 this->flows(dst, src);
1858 // DST = string([]byte{...}). 2311 break;
1859 case Runtime::SLICERUNETOSTRING:
1860 // DST = string([]int{...}).
1861 case Runtime::STRINGTOSLICEBYTE:
1862 // DST = []byte(str).
1863 case Runtime::STRINGTOSLICERUNE:
1864 // DST = []rune(str).
1865 case Runtime::CONCATSTRINGS:
1866 case Runtime::CONCATSTRING2:
1867 case Runtime::CONCATSTRING3:
1868 case Runtime::CONCATSTRING4:
1869 case Runtime::CONCATSTRING5:
1870 // DST = str1 + str2
1871 case Runtime::CONSTRUCT_MAP:
1872 // When building a map literal's backend representation.
1873 // Likely never seen here and covered in
1874 // Expression::EXPRESSION_MAP_CONSTRUCTION.
1875 case Runtime::INTSTRING:
1876 // DST = string(i).
1877 case Runtime::IFACEE2E2:
1878 case Runtime::IFACEI2E2:
1879 case Runtime::IFACEE2I2:
1880 case Runtime::IFACEI2I2:
1881 case Runtime::IFACEE2T2P:
1882 case Runtime::IFACEI2T2P:
1883 case Runtime::IFACEE2T2:
1884 case Runtime::IFACEI2T2:
1885 case Runtime::REQUIREITAB:
1886 // All versions of interface conversion that might result
1887 // from a type assertion. Some of these are the result of
1888 // a tuple type assertion statement and may not be covered
1889 // by the case in Expression::EXPRESSION_CONVERSION or
1890 // Expression::EXPRESSION_TYPE_GUARD.
1891 this->flows(dst, src);
1892 break;
1893 2312
1894 default: 2313 default:
1895 break; 2314 break;
1896 } 2315 }
1897 break; 2316 break;
1907 Node* rcvr_node = Node::make_node(call->args()->front()); 2326 Node* rcvr_node = Node::make_node(call->args()->front());
1908 this->assign(dst, rcvr_node); 2327 this->assign(dst, rcvr_node);
1909 break; 2328 break;
1910 } 2329 }
1911 2330
1912 // TODO(cmang): Handle case from issue 4529. 2331 // Result flows to dst.
1913 // Node* call_node = Node::make_node(e); 2332 Node* call_node = Node::make_node(e);
1914 // Node::Escape_state* call_state = call_node->state(this->context_, NULL); 2333 Node::Escape_state* call_state = call_node->state(this->context_, NULL);
1915 // std::vector<Node*> retvals = call_state->retvals; 2334 std::vector<Node*> retvals = call_state->retvals;
1916 // for (std::vector<Node*>::const_iterator p = retvals.begin(); 2335 for (std::vector<Node*>::const_iterator p = retvals.begin();
1917 // p != retvals.end(); 2336 p != retvals.end();
1918 // ++p) 2337 ++p)
1919 // this->flows(dst, *p); 2338 this->flows(dst, *p);
1920 } 2339 }
1921 break; 2340 break;
1922 2341
2342 case Expression::EXPRESSION_CALL_RESULT:
2343 {
2344 Call_result_expression* cre = e->call_result_expression();
2345 Call_expression* call = cre->call()->call_expression();
2346 if (call->is_builtin())
2347 break;
2348 if (call->fn()->func_expression() != NULL
2349 && call->fn()->func_expression()->is_runtime_function())
2350 {
2351 switch (call->fn()->func_expression()->runtime_code())
2352 {
2353 case Runtime::IFACEE2E2:
2354 case Runtime::IFACEI2E2:
2355 case Runtime::IFACEE2I2:
2356 case Runtime::IFACEI2I2:
2357 case Runtime::IFACEE2T2P:
2358 case Runtime::IFACEI2T2P:
2359 {
2360 // x, ok = v.(T), where T is a pointer or interface,
2361 // is lowered to
2362 // x, ok = IFACEI2E2(v), or
2363 // x, ok = IFACEI2I2(type, v)
2364 // The last arg flows to the first result.
2365 // Note: IFACEX2T2 has different signature, handled by
2366 // ::expression.
2367 if (cre->index() != 0)
2368 break;
2369 Node* arg_node = Node::make_node(call->args()->back());
2370 this->assign(dst, arg_node);
2371 }
2372 break;
2373
2374 default:
2375 break;
2376 }
2377 break;
2378 }
2379
2380 Node* call_node = Node::make_node(call);
2381 Node* ret_node = call_node->state(context_, NULL)->retvals[cre->index()];
2382 this->assign(dst, ret_node);
2383 }
2384 break;
2385
1923 case Expression::EXPRESSION_FUNC_REFERENCE: 2386 case Expression::EXPRESSION_FUNC_REFERENCE:
1924 if (e->func_expression()->closure() != NULL) 2387 if (e->func_expression()->closure() != NULL)
1925 { 2388 this->flows(dst, src);
1926 // If SRC is a reference to a function closure, DST flows into
1927 // the underyling closure variable.
1928 Expression* closure = e->func_expression()->closure();
1929 Node* closure_node = Node::make_node(closure);
1930 this->flows(dst, closure_node);
1931 }
1932 break; 2389 break;
2390
2391 case Expression::EXPRESSION_CONVERSION:
2392 {
2393 Type_conversion_expression* tce = e->conversion_expression();
2394 Type* ft = tce->expr()->type();
2395 Type* tt = tce->type();
2396 if ((ft->is_string_type() && tt->is_slice_type())
2397 || (ft->is_slice_type() && tt->is_string_type())
2398 || (ft->integer_type() != NULL && tt->is_string_type()))
2399 {
2400 // string([]byte), string([]rune), []byte(string), []rune(string), string(rune)
2401 this->flows(dst, src);
2402 break;
2403 }
2404 // Conversion preserves input value.
2405 Expression* underlying = tce->expr();
2406 this->assign(dst, Node::make_node(underlying));
2407 }
2408 break;
1933 2409
1934 case Expression::EXPRESSION_FIELD_REFERENCE: 2410 case Expression::EXPRESSION_FIELD_REFERENCE:
1935 { 2411 {
1936 // A non-pointer can't escape from a struct. 2412 // A non-pointer can't escape from a struct.
1937 if (!e->type()->has_pointer()) 2413 if (!e->type()->has_pointer())
1938 break; 2414 break;
1939 } 2415 }
1940 // Fall through. 2416 // Fall through.
1941 2417
1942 case Expression::EXPRESSION_CONVERSION:
1943 case Expression::EXPRESSION_TYPE_GUARD: 2418 case Expression::EXPRESSION_TYPE_GUARD:
1944 case Expression::EXPRESSION_ARRAY_INDEX: 2419 case Expression::EXPRESSION_ARRAY_INDEX:
1945 case Expression::EXPRESSION_STRING_INDEX: 2420 case Expression::EXPRESSION_STRING_INDEX:
1946 { 2421 {
1947 Expression* left = NULL; 2422 Expression* left = NULL;
1954 // DST = (*x).f 2429 // DST = (*x).f
1955 this->flows(dst, src); 2430 this->flows(dst, src);
1956 break; 2431 break;
1957 } 2432 }
1958 } 2433 }
1959 else if (e->conversion_expression() != NULL)
1960 left = e->conversion_expression()->expr();
1961 else if (e->type_guard_expression() != NULL) 2434 else if (e->type_guard_expression() != NULL)
1962 left = e->type_guard_expression()->expr(); 2435 left = e->type_guard_expression()->expr();
1963 else if (e->array_index_expression() != NULL) 2436 else if (e->array_index_expression() != NULL)
1964 { 2437 {
1965 Array_index_expression* aie = e->array_index_expression(); 2438 Array_index_expression* aie = e->array_index_expression();
1966 if (e->type()->is_slice_type()) 2439 if (aie->end() != NULL)
1967 left = aie->array(); 2440 // slicing
2441 if (aie->array()->type()->is_slice_type())
2442 left = aie->array();
2443 else
2444 {
2445 // slicing an array
2446 // The gc compiler has an implicit address operator.
2447 go_assert(src->child() != NULL);
2448 this->assign(dst, src->child());
2449 break;
2450 }
1968 else if (!aie->array()->type()->is_slice_type()) 2451 else if (!aie->array()->type()->is_slice_type())
1969 { 2452 {
1970 // Indexing an array preserves the input value. 2453 // Indexing an array preserves the input value.
1971 Node* array_node = Node::make_node(aie->array()); 2454 Node* array_node = Node::make_node(aie->array());
1972 this->assign(dst, array_node); 2455 this->assign(dst, array_node);
1979 } 2462 }
1980 } 2463 }
1981 else if (e->string_index_expression() != NULL) 2464 else if (e->string_index_expression() != NULL)
1982 { 2465 {
1983 String_index_expression* sie = e->string_index_expression(); 2466 String_index_expression* sie = e->string_index_expression();
1984 if (e->type()->is_slice_type()) 2467 if (e->type()->is_string_type())
2468 // slicing
1985 left = sie->string(); 2469 left = sie->string();
1986 else if (!sie->string()->type()->is_slice_type())
1987 {
1988 // Indexing a string preserves the input value.
1989 Node* string_node = Node::make_node(sie->string());
1990 this->assign(dst, string_node);
1991 break;
1992 }
1993 else 2470 else
1994 { 2471 {
1995 this->flows(dst, src); 2472 this->flows(dst, src);
1996 break; 2473 break;
1997 } 2474 }
2010 switch (e->binary_expression()->op()) 2487 switch (e->binary_expression()->op())
2011 { 2488 {
2012 case OPERATOR_PLUS: 2489 case OPERATOR_PLUS:
2013 case OPERATOR_MINUS: 2490 case OPERATOR_MINUS:
2014 case OPERATOR_XOR: 2491 case OPERATOR_XOR:
2492 case OPERATOR_OR:
2015 case OPERATOR_MULT: 2493 case OPERATOR_MULT:
2016 case OPERATOR_DIV: 2494 case OPERATOR_DIV:
2017 case OPERATOR_MOD: 2495 case OPERATOR_MOD:
2018 case OPERATOR_LSHIFT: 2496 case OPERATOR_LSHIFT:
2019 case OPERATOR_RSHIFT: 2497 case OPERATOR_RSHIFT:
2061 break; 2539 break;
2062 2540
2063 case Expression::EXPRESSION_TEMPORARY_REFERENCE: 2541 case Expression::EXPRESSION_TEMPORARY_REFERENCE:
2064 { 2542 {
2065 Statement* temp = e->temporary_reference_expression()->statement(); 2543 Statement* temp = e->temporary_reference_expression()->statement();
2066 if (temp != NULL 2544 this->assign(dst, Node::make_node(temp));
2067 && temp->temporary_statement()->init() != NULL)
2068 {
2069 Expression* init = temp->temporary_statement()->init();
2070 Node* init_node = Node::make_node(init);
2071 this->assign(dst, init_node);
2072 }
2073 } 2545 }
2074 break; 2546 break;
2075 2547
2076 default: 2548 default:
2077 // TODO(cmang): Add debug info here; this should not be reachable. 2549 // TODO(cmang): Add debug info here; this should not be reachable.
2078 // For now, just to be conservative, we'll just say dst flows to src. 2550 // For now, just to be conservative, we'll just say dst flows to src.
2079 break; 2551 break;
2080 } 2552 }
2081 } 2553 }
2554 else if (src->statement() != NULL && src->statement()->temporary_statement() != NULL)
2555 this->flows(dst, src);
2082 } 2556 }
2083 2557
2084 // Model the assignment of DST to an indirection of SRC. 2558 // Model the assignment of DST to an indirection of SRC.
2085 2559
2086 void 2560 void
2099 case Expression::EXPRESSION_IOTA: 2573 case Expression::EXPRESSION_IOTA:
2100 // No need to try indirections on literal values 2574 // No need to try indirections on literal values
2101 // or numeric constants. 2575 // or numeric constants.
2102 return; 2576 return;
2103 2577
2104 case Expression::EXPRESSION_FIXED_ARRAY_CONSTRUCTION:
2105 case Expression::EXPRESSION_SLICE_CONSTRUCTION:
2106 case Expression::EXPRESSION_STRUCT_CONSTRUCTION:
2107 {
2108 // Dereferencing an array, slice, or struct is like accessing each
2109 // of its values. In this situation, we model the flow from src to
2110 // dst where src is one of the above as a flow from each of src's
2111 // values to dst.
2112 Expression* e = src->expr();
2113 Expression_list* vals = NULL;
2114 if (e->slice_literal() != NULL)
2115 vals = e->slice_literal()->vals();
2116 else if (e->array_literal() != NULL)
2117 vals = e->array_literal()->vals();
2118 else
2119 vals = e->struct_literal()->vals();
2120
2121 if (vals != NULL)
2122 {
2123 for (Expression_list::const_iterator p = vals->begin();
2124 p != vals->end();
2125 ++p)
2126 {
2127 if ((*p) != NULL)
2128 this->assign(dst, Node::make_node(*p));
2129 }
2130 }
2131 }
2132 return;
2133
2134 default: 2578 default:
2135 break; 2579 break;
2136 } 2580 }
2137 } 2581 }
2138 2582
2167 break; 2611 break;
2168 } 2612 }
2169 } 2613 }
2170 2614
2171 if (this->context_->gogo()->debug_escape_level() > 2) 2615 if (this->context_->gogo()->debug_escape_level() > 2)
2172 go_inform(src->location(), "assignfromtag:: src= em=%s", 2616 go_inform(src->location(), "assignfromtag:: src=%s em=%s",
2617 src->ast_format(context_->gogo()).c_str(),
2173 Escape_note::make_tag(enc).c_str()); 2618 Escape_note::make_tag(enc).c_str());
2174 2619
2175 if (enc == Node::ESCAPE_UNKNOWN) 2620 if (enc == Node::ESCAPE_UNKNOWN)
2176 { 2621 {
2177 // Lost track of the value. 2622 // Lost track of the value.
2220 2665
2221 void 2666 void
2222 Escape_analysis_assign::flows(Node* dst, Node* src) 2667 Escape_analysis_assign::flows(Node* dst, Node* src)
2223 { 2668 {
2224 // Don't bother capturing the flow from scalars. 2669 // Don't bother capturing the flow from scalars.
2225 if (src->expr() != NULL 2670 if (src->type() != NULL && !src->type()->has_pointer())
2226 && !src->expr()->type()->has_pointer())
2227 return; 2671 return;
2228 2672
2229 // Don't confuse a blank identifier with the sink. 2673 // Don't confuse a blank identifier with the sink.
2230 if (dst->is_sink() && dst != this->context_->sink()) 2674 if (dst->is_sink() && dst != this->context_->sink())
2231 return; 2675 return;
2232 2676
2233 Node::Escape_state* dst_state = dst->state(this->context_, NULL); 2677 Node::Escape_state* dst_state = dst->state(this->context_, NULL);
2234 Node::Escape_state* src_state = src->state(this->context_, NULL); 2678 Node::Escape_state* src_state = src->state(this->context_, NULL);
2235 if (dst == src 2679 if (dst == src
2236 || dst_state == src_state 2680 || dst_state == src_state
2237 || dst_state->flows.find(src) != dst_state->flows.end() 2681 || dst_state->flows.find(src) != dst_state->flows.end())
2238 || src_state->flows.find(dst) != src_state->flows.end())
2239 return; 2682 return;
2240 2683
2241 Gogo* gogo = this->context_->gogo(); 2684 Gogo* gogo = this->context_->gogo();
2242 if (gogo->debug_escape_level() > 2) 2685 if (gogo->debug_escape_level() > 2)
2243 go_inform(Linemap::unknown_location(), "flows:: %s <- %s", 2686 go_inform(Linemap::unknown_location(), "flows:: %s <- %s",
2269 p != res->end(); 2712 p != res->end();
2270 ++p) 2713 ++p)
2271 { 2714 {
2272 Node* res_node = Node::make_node(*p); 2715 Node* res_node = Node::make_node(*p);
2273 Node::Escape_state* res_state = res_node->state(context, fn); 2716 Node::Escape_state* res_state = res_node->state(context, fn);
2717 res_state->fn = fn;
2274 res_state->loop_depth = 0; 2718 res_state->loop_depth = 0;
2275 2719
2276 // If this set of functions is recursive, we lose track of the return values. 2720 // If this set of functions is recursive, we lose track of the return values.
2277 // Just say that the result flows to the sink. 2721 // Just say that the result flows to the sink.
2278 if (context->recursive()) 2722 if (context->recursive())
2297 2741
2298 Named_object* param_no = callee_bindings->lookup_local(p->name()); 2742 Named_object* param_no = callee_bindings->lookup_local(p->name());
2299 go_assert(param_no != NULL); 2743 go_assert(param_no != NULL);
2300 Node* param_node = Node::make_node(param_no); 2744 Node* param_node = Node::make_node(param_no);
2301 Node::Escape_state* param_state = param_node->state(context, fn); 2745 Node::Escape_state* param_state = param_node->state(context, fn);
2746 param_state->fn = fn;
2302 param_state->loop_depth = 1; 2747 param_state->loop_depth = 1;
2303 2748
2304 if (!p->type()->has_pointer()) 2749 if (!p->type()->has_pointer())
2305 continue; 2750 continue;
2306 2751
2307 // External function? Parameters must escape unless //go:noescape is set. 2752 // External function? Parameters must escape unless //go:noescape is set.
2308 // TODO(cmang): Implement //go:noescape directive. 2753 // TODO(cmang): Implement //go:noescape directive.
2309 if (fn->package() != NULL) 2754 if (fn->package() != NULL)
2310 param_node->set_encoding(Node::ESCAPE_HEAP); 2755 param_node->set_encoding(Node::ESCAPE_HEAP);
2311 else 2756 else
2312 param_node->set_encoding(Node::ESCAPE_NONE); 2757 {
2313 2758 param_node->set_encoding(Node::ESCAPE_NONE);
2314 // TODO(cmang): Track this node in no_escape list. 2759 context->track(param_node);
2760 }
2315 } 2761 }
2316 2762
2317 Escape_analysis_loop el; 2763 Escape_analysis_loop el;
2318 fn->func_value()->traverse(&el); 2764 fn->func_value()->traverse(&el);
2319 2765
2430 if (dst->expr() != NULL && dst->expr()->var_expression() != NULL) 2876 if (dst->expr() != NULL && dst->expr()->var_expression() != NULL)
2431 dst_no = dst->expr()->var_expression()->named_object(); 2877 dst_no = dst->expr()->var_expression()->named_object();
2432 else 2878 else
2433 dst_no = dst->object(); 2879 dst_no = dst->object();
2434 bool dst_is_result = dst_no != NULL && dst_no->is_result_variable(); 2880 bool dst_is_result = dst_no != NULL && dst_no->is_result_variable();
2881 Node::Escape_state* dst_state = dst->state(this->context_, NULL);
2435 2882
2436 if (src_is_param 2883 if (src_is_param
2437 && dst_is_result 2884 && dst_is_result
2438 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_SCOPE) 2885 && src_state->fn == dst_state->fn
2886 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_HEAP)
2439 && dst->encoding() != Node::ESCAPE_HEAP) 2887 && dst->encoding() != Node::ESCAPE_HEAP)
2440 { 2888 {
2441 // This case handles: 2889 // This case handles:
2442 // 1. return in 2890 // 1. return in
2443 // 2. return &in 2891 // 2. return &in
2444 // 3. tmp := in; return &tmp 2892 // 3. tmp := in; return &tmp
2445 // 4. return *in 2893 // 4. return *in
2446 if (debug_level != 0) 2894 if (debug_level != 0)
2447 { 2895 {
2448 if (debug_level == 1) 2896 if (debug_level == 1)
2449 go_inform(src->location(), 2897 go_inform(src->definition_location(),
2450 "leaking param: %s to result %s level=%d", 2898 "leaking param: %s to result %s level=%d",
2451 src->ast_format(gogo).c_str(), 2899 src->ast_format(gogo).c_str(),
2452 dst->ast_format(gogo).c_str(), 2900 dst->ast_format(gogo).c_str(),
2453 level.value()); 2901 level.value());
2454 else 2902 else
2455 go_inform(src->location(), 2903 go_inform(src->definition_location(),
2456 "leaking param: %s to result %s level={%d %d}", 2904 "leaking param: %s to result %s level={%d %d}",
2457 src->ast_format(gogo).c_str(), 2905 src->ast_format(gogo).c_str(),
2458 dst->ast_format(gogo).c_str(), 2906 dst->ast_format(gogo).c_str(),
2459 level.value(), level.suffix_value()); 2907 level.value(), level.suffix_value());
2460 } 2908 }
2484 // If parameter content escape to heap, set ESCAPE_CONTENT_ESCAPES. 2932 // If parameter content escape to heap, set ESCAPE_CONTENT_ESCAPES.
2485 // Note minor confusion around escape from pointer-to-struct vs 2933 // Note minor confusion around escape from pointer-to-struct vs
2486 // escape from struct. 2934 // escape from struct.
2487 if (src_is_param 2935 if (src_is_param
2488 && dst->encoding() == Node::ESCAPE_HEAP 2936 && dst->encoding() == Node::ESCAPE_HEAP
2489 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_SCOPE) 2937 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_HEAP)
2490 && level.value() > 0) 2938 && level.value() > 0)
2491 { 2939 {
2492 int enc = 2940 int enc =
2493 Node::max_encoding((src->encoding() | ESCAPE_CONTENT_ESCAPES), 2941 Node::max_encoding((src->encoding() | ESCAPE_CONTENT_ESCAPES),
2494 Node::ESCAPE_NONE); 2942 Node::ESCAPE_NONE);
2495 src->set_encoding(enc); 2943 src->set_encoding(enc);
2496 if (debug_level != 0) 2944 if (debug_level != 0)
2497 go_inform(src->location(), "mark escaped content: %s", 2945 go_inform(src->definition_location(), "mark escaped content: %s",
2498 src->ast_format(gogo).c_str()); 2946 src->ast_format(gogo).c_str());
2499 } 2947 }
2500 2948
2501 // A src object leaks if its value or address is assigned to a dst object 2949 // A src object leaks if its value or address is assigned to a dst object
2502 // in a different scope (at a different loop depth). 2950 // in a different scope (at a different loop depth).
2503 Node::Escape_state* dst_state = dst->state(this->context_, NULL);
2504 bool src_leaks = (level.value() <= 0 2951 bool src_leaks = (level.value() <= 0
2505 && level.suffix_value() <= 0 2952 && level.suffix_value() <= 0
2506 && dst_state->loop_depth < mod_loop_depth); 2953 && dst_state->loop_depth < mod_loop_depth);
2954 src_leaks = src_leaks || (level.value() <= 0
2955 && (dst->encoding() & ESCAPE_MASK) == Node::ESCAPE_HEAP);
2956 // old src encoding, used to prevent duplicate error messages
2957 int osrcesc = src->encoding();
2507 2958
2508 if (src_is_param 2959 if (src_is_param
2509 && (src_leaks || dst_state->loop_depth < 0) 2960 && (src_leaks || dst_state->loop_depth < 0)
2510 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_SCOPE)) 2961 && (src->encoding() & ESCAPE_MASK) < int(Node::ESCAPE_HEAP))
2511 { 2962 {
2512 if (level.suffix_value() > 0) 2963 if (level.suffix_value() > 0)
2513 { 2964 {
2514 int enc = 2965 int enc =
2515 Node::max_encoding((src->encoding() | ESCAPE_CONTENT_ESCAPES), 2966 Node::max_encoding((src->encoding() | ESCAPE_CONTENT_ESCAPES),
2516 Node::ESCAPE_NONE); 2967 Node::ESCAPE_NONE);
2517 src->set_encoding(enc); 2968 src->set_encoding(enc);
2969 if (debug_level != 0 && osrcesc != src->encoding())
2970 go_inform(src->definition_location(), "leaking param content: %s",
2971 src->ast_format(gogo).c_str());
2972 }
2973 else
2974 {
2518 if (debug_level != 0) 2975 if (debug_level != 0)
2519 go_inform(src->location(), "leaking param content: %s", 2976 go_inform(src->definition_location(), "leaking param: %s",
2520 src->ast_format(gogo).c_str()); 2977 src->ast_format(gogo).c_str());
2521 } 2978 src->set_encoding(Node::ESCAPE_HEAP);
2522 else
2523 {
2524 if (debug_level != 0)
2525 go_inform(src->location(), "leaking param");
2526 src->set_encoding(Node::ESCAPE_SCOPE);
2527 } 2979 }
2528 } 2980 }
2529 else if (src->expr() != NULL) 2981 else if (src->expr() != NULL)
2530 { 2982 {
2531 Expression* e = src->expr(); 2983 Expression* e = src->expr();
2555 // to the heap. 3007 // to the heap.
2556 underlying->address_taken(src_leaks); 3008 underlying->address_taken(src_leaks);
2557 if (src_leaks) 3009 if (src_leaks)
2558 { 3010 {
2559 src->set_encoding(Node::ESCAPE_HEAP); 3011 src->set_encoding(Node::ESCAPE_HEAP);
2560 if (debug_level != 0) 3012 if (osrcesc != src->encoding())
2561 { 3013 {
2562 go_inform(underlying->location(), "moved to heap: %s", 3014 move_to_heap(gogo, underlying);
2563 underlying_node->ast_format(gogo).c_str()); 3015 if (debug_level > 1)
2564 3016 go_inform(src->location(),
2565 if (debug_level > 1) 3017 "%s escapes to heap, level={%d %d}, "
2566 go_inform(src->location(), 3018 "dst.eld=%d, src.eld=%d",
2567 "%s escapes to heap, level={%d %d}, " 3019 src->ast_format(gogo).c_str(), level.value(),
2568 "dst.eld=%d, src.eld=%d", 3020 level.suffix_value(), dst_state->loop_depth,
2569 src->ast_format(gogo).c_str(), level.value(), 3021 mod_loop_depth);
2570 level.suffix_value(), dst_state->loop_depth, 3022 else if (debug_level > 0)
2571 mod_loop_depth); 3023 go_inform(src->location(), "%s escapes to heap",
2572 else 3024 src->ast_format(gogo).c_str());
2573 go_inform(src->location(), "%s escapes to heap", 3025 }
2574 src->ast_format(gogo).c_str());
2575 }
2576 3026
2577 this->flood(level.decrease(), dst, 3027 this->flood(level.decrease(), dst,
2578 underlying_node, mod_loop_depth); 3028 underlying_node, mod_loop_depth);
2579 extra_loop_depth = mod_loop_depth; 3029 extra_loop_depth = mod_loop_depth;
2580 } 3030 }
2598 } 3048 }
2599 } 3049 }
2600 if (src_leaks) 3050 if (src_leaks)
2601 { 3051 {
2602 src->set_encoding(Node::ESCAPE_HEAP); 3052 src->set_encoding(Node::ESCAPE_HEAP);
2603 if (debug_level != 0) 3053 if (debug_level != 0 && osrcesc != src->encoding())
2604 go_inform(src->location(), "%s escapes to heap", 3054 go_inform(src->location(), "%s escapes to heap",
2605 src->ast_format(gogo).c_str()); 3055 src->ast_format(gogo).c_str());
2606 extra_loop_depth = mod_loop_depth; 3056 extra_loop_depth = mod_loop_depth;
2607 } 3057 }
2608 } 3058 }
2609 else if (e->call_expression() != NULL) 3059 else if (e->call_expression() != NULL)
2610 { 3060 {
2611 Call_expression* call = e->call_expression(); 3061 Call_expression* call = e->call_expression();
2612 if (call->fn()->func_expression() != NULL) 3062 if (call->is_builtin())
2613 { 3063 {
2614 Func_expression* func = call->fn()->func_expression(); 3064 Builtin_call_expression* bce = call->builtin_call_expression();
2615 if (func->is_runtime_function()) 3065 if (bce->code() == Builtin_call_expression::BUILTIN_APPEND)
2616 { 3066 {
2617 switch (func->runtime_code()) 3067 // Propagate escape information to appendee.
2618 { 3068 Expression* appendee = call->args()->front();
2619 case Runtime::GROWSLICE: 3069 this->flood(level, dst, Node::make_node(appendee), -1);
2620 { 3070 }
2621 // Propagate escape information to appendee. 3071 }
2622 Expression* appendee = call->args()->front(); 3072 else if (call->fn()->func_expression() != NULL
2623 this->flood(level, dst, Node::make_node(appendee), -1); 3073 && call->fn()->func_expression()->is_runtime_function())
2624 } 3074 {
2625 break; 3075 switch (call->fn()->func_expression()->runtime_code())
2626 3076 {
2627 case Runtime::MAKECHAN: 3077 case Runtime::MAKECHAN:
2628 case Runtime::MAKEMAP: 3078 case Runtime::MAKECHAN64:
2629 case Runtime::MAKESLICE: 3079 case Runtime::MAKEMAP:
2630 case Runtime::MAKESLICE64: 3080 case Runtime::MAKESLICE:
2631 case Runtime::SLICEBYTETOSTRING: 3081 case Runtime::MAKESLICE64:
2632 case Runtime::SLICERUNETOSTRING: 3082 if (src_leaks)
2633 case Runtime::STRINGTOSLICEBYTE: 3083 {
2634 case Runtime::STRINGTOSLICERUNE: 3084 src->set_encoding(Node::ESCAPE_HEAP);
2635 case Runtime::CONCATSTRINGS: 3085 if (debug_level != 0 && osrcesc != src->encoding())
2636 case Runtime::CONCATSTRING2: 3086 go_inform(src->location(), "%s escapes to heap",
2637 case Runtime::CONCATSTRING3: 3087 src->ast_format(gogo).c_str());
2638 case Runtime::CONCATSTRING4: 3088 extra_loop_depth = mod_loop_depth;
2639 case Runtime::CONCATSTRING5: 3089 }
2640 case Runtime::CONSTRUCT_MAP: 3090 break;
2641 case Runtime::INTSTRING: 3091
2642 case Runtime::REQUIREITAB: 3092 default:
2643 // All runtime calls that involve allocation of memory 3093 break;
2644 // except new. Runtime::NEW gets lowered into an 3094 }
2645 // allocation expression. 3095 }
2646 if (src_leaks) 3096 else if (src_state->retvals.size() > 0)
2647 { 3097 {
2648 src->set_encoding(Node::ESCAPE_HEAP); 3098 // In this case a link went directly to a call, but should really go
2649 if (debug_level != 0) 3099 // to the dummy .outN outputs that were created for the call that
2650 go_inform(src->location(), "%s escapes to heap", 3100 // themselves link to the inputs with levels adjusted.
2651 src->ast_format(gogo).c_str()); 3101 // See e.g. #10466.
2652 extra_loop_depth = mod_loop_depth; 3102 // This can only happen with functions returning a single result.
2653 } 3103 go_assert(src_state->retvals.size() == 1);
2654 break; 3104 if (debug_level > 2)
2655 3105 go_inform(src->location(), "[%d] dst %s escwalk replace src: %s with %s",
2656 default: 3106 this->context_->loop_depth(),
2657 break; 3107 dst->ast_format(gogo).c_str(),
2658 } 3108 src->ast_format(gogo).c_str(),
2659 } 3109 src_state->retvals[0]->ast_format(gogo).c_str());
2660 else if (src_leaks 3110 src = src_state->retvals[0];
2661 && (func->closure() != NULL 3111 src_state = src->state(this->context_, NULL);
2662 || func->bound_method_expression() != NULL)) 3112 }
2663 {
2664 // A closure or bound method; we lost track of actual function
2665 // so if this leaks, this call must be done on the heap.
2666 src->set_encoding(Node::ESCAPE_HEAP);
2667 if (debug_level != 0)
2668 go_inform(src->location(), "%s escapes to heap",
2669 src->ast_format(gogo).c_str());
2670 }
2671 }
2672 } 3113 }
2673 else if (e->allocation_expression() != NULL && src_leaks) 3114 else if (e->allocation_expression() != NULL && src_leaks)
2674 { 3115 {
2675 // Calls to Runtime::NEW get lowered into an allocation expression. 3116 // Calls to Runtime::NEW get lowered into an allocation expression.
2676 src->set_encoding(Node::ESCAPE_HEAP); 3117 src->set_encoding(Node::ESCAPE_HEAP);
2677 if (debug_level != 0) 3118 if (debug_level != 0 && osrcesc != src->encoding())
2678 go_inform(src->location(), "%s escapes to heap", 3119 go_inform(src->location(), "%s escapes to heap",
2679 src->ast_format(gogo).c_str()); 3120 src->ast_format(gogo).c_str());
2680 } 3121 extra_loop_depth = mod_loop_depth;
3122 }
3123 else if ((e->map_literal() != NULL
3124 || e->string_concat_expression() != NULL
3125 || (e->func_expression() != NULL && e->func_expression()->closure() != NULL)
3126 || e->bound_method_expression() != NULL)
3127 && src_leaks)
3128 {
3129 src->set_encoding(Node::ESCAPE_HEAP);
3130 if (debug_level != 0 && osrcesc != src->encoding())
3131 go_inform(src->location(), "%s escapes to heap",
3132 src->ast_format(gogo).c_str());
3133 extra_loop_depth = mod_loop_depth;
3134 }
3135 else if (e->conversion_expression() != NULL && src_leaks)
3136 {
3137 Type_conversion_expression* tce = e->conversion_expression();
3138 Type* ft = tce->expr()->type();
3139 Type* tt = tce->type();
3140 if ((ft->is_string_type() && tt->is_slice_type())
3141 || (ft->is_slice_type() && tt->is_string_type())
3142 || (ft->integer_type() != NULL && tt->is_string_type()))
3143 {
3144 // string([]byte), string([]rune), []byte(string), []rune(string), string(rune)
3145 src->set_encoding(Node::ESCAPE_HEAP);
3146 if (debug_level != 0 && osrcesc != src->encoding())
3147 go_inform(src->location(), "%s escapes to heap",
3148 src->ast_format(gogo).c_str());
3149 extra_loop_depth = mod_loop_depth;
3150 }
3151 }
3152 else if (e->array_index_expression() != NULL
3153 && !e->array_index_expression()->array()->type()->is_slice_type())
3154 {
3155 Array_index_expression* aie = e->array_index_expression();
3156 if (aie->end() != NULL)
3157 {
3158 // Slicing an array.
3159 // Flow its implicit address-of node to DST.
3160 this->flood(level, dst, src->child(), -1);
3161 }
3162 else
3163 {
3164 // Indexing an array.
3165 // An array element flowing to DST behaves like the array
3166 // flowing to DST.
3167 Expression* underlying = e->array_index_expression()->array();
3168 Node* underlying_node = Node::make_node(underlying);
3169 this->flood(level, dst, underlying_node, -1);
3170 }
3171 }
2681 else if ((e->field_reference_expression() != NULL 3172 else if ((e->field_reference_expression() != NULL
2682 && e->field_reference_expression()->expr()->unary_expression() == NULL) 3173 && e->field_reference_expression()->expr()->unary_expression() == NULL)
2683 || e->type_guard_expression() != NULL 3174 || e->type_guard_expression() != NULL
2684 || (e->array_index_expression() != NULL 3175 || (e->array_index_expression() != NULL
2685 && e->type()->is_slice_type()) 3176 && e->array_index_expression()->end() != NULL)
2686 || (e->string_index_expression() != NULL 3177 || (e->string_index_expression() != NULL
2687 && e->type()->is_slice_type())) 3178 && e->type()->is_string_type()))
2688 { 3179 {
2689 Expression* underlying; 3180 Expression* underlying;
2690 if (e->field_reference_expression() != NULL) 3181 if (e->field_reference_expression() != NULL)
2691 underlying = e->field_reference_expression()->expr(); 3182 underlying = e->field_reference_expression()->expr();
2692 else if (e->type_guard_expression() != NULL) 3183 else if (e->type_guard_expression() != NULL)
2711 { 3202 {
2712 underlying = e->field_reference_expression()->expr(); 3203 underlying = e->field_reference_expression()->expr();
2713 underlying = underlying->unary_expression()->operand(); 3204 underlying = underlying->unary_expression()->operand();
2714 } 3205 }
2715 else if (e->array_index_expression() != NULL) 3206 else if (e->array_index_expression() != NULL)
2716 { 3207 underlying = e->array_index_expression()->array();
2717 underlying = e->array_index_expression()->array();
2718 if (!underlying->type()->is_slice_type())
2719 {
2720 Node* underlying_node = Node::make_node(underlying);
2721 this->flood(level, dst, underlying_node, 1);
2722 }
2723 }
2724 else if (e->map_index_expression() != NULL) 3208 else if (e->map_index_expression() != NULL)
2725 underlying = e->map_index_expression()->map(); 3209 underlying = e->map_index_expression()->map();
2726 else 3210 else
2727 underlying = e->unary_expression()->operand(); 3211 underlying = e->unary_expression()->operand();
2728 3212
2729 // Increase the level for a dereference. 3213 // Increase the level for a dereference.
2730 Node* underlying_node = Node::make_node(underlying); 3214 Node* underlying_node = Node::make_node(underlying);
2731 this->flood(level.increase(), dst, underlying_node, -1); 3215 this->flood(level.increase(), dst, underlying_node, -1);
2732 } 3216 }
2733 3217 else if (e->temporary_reference_expression() != NULL)
2734 // TODO(cmang): Add case for Issue #10466. 3218 {
2735 } 3219 Statement* t = e->temporary_reference_expression()->statement();
3220 this->flood(level, dst, Node::make_node(t), -1);
3221 }
3222 }
3223 else if (src->is_indirect())
3224 // Increase the level for a dereference.
3225 this->flood(level.increase(), dst, src->child(), -1);
2736 3226
2737 level = level.copy(); 3227 level = level.copy();
2738 for (std::set<Node*>::const_iterator p = src_state->flows.begin(); 3228 for (std::set<Node*>::const_iterator p = src_state->flows.begin();
2739 p != src_state->flows.end(); 3229 p != src_state->flows.end();
2740 ++p) 3230 ++p)
2747 // This is an implementation of gc/esc.go:escflood. 3237 // This is an implementation of gc/esc.go:escflood.
2748 3238
2749 void 3239 void
2750 Gogo::propagate_escape(Escape_context* context, Node* dst) 3240 Gogo::propagate_escape(Escape_context* context, Node* dst)
2751 { 3241 {
3242 if (dst->object() == NULL
3243 && (dst->expr() == NULL
3244 || (dst->expr()->var_expression() == NULL
3245 && dst->expr()->enclosed_var_expression() == NULL
3246 && dst->expr()->func_expression() == NULL)))
3247 return;
3248
2752 Node::Escape_state* state = dst->state(context, NULL); 3249 Node::Escape_state* state = dst->state(context, NULL);
2753 Gogo* gogo = context->gogo(); 3250 Gogo* gogo = context->gogo();
2754 if (gogo->debug_escape_level() > 1) 3251 if (gogo->debug_escape_level() > 1)
2755 go_inform(Linemap::unknown_location(), "escflood:%d: dst %s scope:%s[%d]", 3252 go_inform(Linemap::unknown_location(), "escflood:%d: dst %s scope:%s[%d]",
2756 context->flood_id(), dst->ast_format(gogo).c_str(), 3253 context->flood_id(), dst->ast_format(gogo).c_str(),
2786 void 3283 void
2787 Escape_analysis_tag::tag(Named_object* fn) 3284 Escape_analysis_tag::tag(Named_object* fn)
2788 { 3285 {
2789 // External functions are assumed unsafe 3286 // External functions are assumed unsafe
2790 // unless //go:noescape is given before the declaration. 3287 // unless //go:noescape is given before the declaration.
2791 if (fn->package() != NULL || !fn->is_function()) 3288 if (fn->package() != NULL)
2792 { 3289 return;
2793 // TODO(cmang): Implement //go:noescape directive for external functions; 3290
2794 // mark input parameters as not escaping. 3291 if (fn->is_function_declaration())
2795 return; 3292 {
2796 } 3293 Function_declaration* fdcl = fn->func_declaration_value();
3294 if ((fdcl->pragmas() & GOPRAGMA_NOESCAPE) != 0)
3295 {
3296 Function_type* fntype = fdcl->type();
3297 if (fntype->parameters() != NULL)
3298 {
3299 const Typed_identifier_list* til = fntype->parameters();
3300 int i = 0;
3301 for (Typed_identifier_list::const_iterator p = til->begin();
3302 p != til->end();
3303 ++p, ++i)
3304 if (p->type()->has_pointer())
3305 fntype->add_parameter_note(i, Node::ESCAPE_NONE);
3306 }
3307 }
3308 }
3309
3310 if (!fn->is_function())
3311 return;
2797 3312
2798 Function_type* fntype = fn->func_value()->type(); 3313 Function_type* fntype = fn->func_value()->type();
2799 Bindings* bindings = fn->func_value()->block()->bindings(); 3314 Bindings* bindings = fn->func_value()->block()->bindings();
2800 3315
2801 if (fntype->is_method() 3316 if (fntype->is_method())
2802 && !fntype->receiver()->name().empty() 3317 {
2803 && !Gogo::is_sink_name(fntype->receiver()->name())) 3318 if (fntype->receiver()->name().empty()
2804 { 3319 || Gogo::is_sink_name(fntype->receiver()->name()))
2805 Named_object* rcvr_no = bindings->lookup(fntype->receiver()->name()); 3320 // Unnamed receiver is not used in the function body, does not escape.
2806 go_assert(rcvr_no != NULL); 3321 fntype->add_receiver_note(Node::ESCAPE_NONE);
2807 Node* rcvr_node = Node::make_node(rcvr_no); 3322 else
2808 switch ((rcvr_node->encoding() & ESCAPE_MASK)) 3323 {
2809 { 3324 Named_object* rcvr_no = bindings->lookup(fntype->receiver()->name());
2810 case Node::ESCAPE_NONE: // not touched by flood 3325 go_assert(rcvr_no != NULL);
2811 case Node::ESCAPE_RETURN: 3326 Node* rcvr_node = Node::make_node(rcvr_no);
2812 if (fntype->receiver()->type()->has_pointer()) 3327 switch ((rcvr_node->encoding() & ESCAPE_MASK))
2813 // Don't bother tagging for scalars. 3328 {
2814 fntype->add_receiver_note(rcvr_node->encoding()); 3329 case Node::ESCAPE_NONE: // not touched by flood
2815 break; 3330 case Node::ESCAPE_RETURN:
2816 3331 if (fntype->receiver()->type()->has_pointer())
2817 case Node::ESCAPE_HEAP: // flooded, moved to heap. 3332 // Don't bother tagging for scalars.
2818 case Node::ESCAPE_SCOPE: // flooded, value leaves scope. 3333 fntype->add_receiver_note(rcvr_node->encoding());
2819 break; 3334 break;
2820 3335
2821 default: 3336 case Node::ESCAPE_HEAP: // flooded, moved to heap.
2822 break; 3337 break;
2823 } 3338
3339 default:
3340 break;
3341 }
3342 }
2824 } 3343 }
2825 3344
2826 int i = 0; 3345 int i = 0;
2827 if (fntype->parameters() != NULL) 3346 if (fntype->parameters() != NULL)
2828 { 3347 {
2830 for (Typed_identifier_list::const_iterator p = til->begin(); 3349 for (Typed_identifier_list::const_iterator p = til->begin();
2831 p != til->end(); 3350 p != til->end();
2832 ++p, ++i) 3351 ++p, ++i)
2833 { 3352 {
2834 if (p->name().empty() || Gogo::is_sink_name(p->name())) 3353 if (p->name().empty() || Gogo::is_sink_name(p->name()))
2835 continue; 3354 {
3355 // Parameter not used in the function body, does not escape.
3356 if (p->type()->has_pointer())
3357 fntype->add_parameter_note(i, Node::ESCAPE_NONE);
3358 continue;
3359 }
2836 3360
2837 Named_object* param_no = bindings->lookup(p->name()); 3361 Named_object* param_no = bindings->lookup(p->name());
2838 go_assert(param_no != NULL); 3362 go_assert(param_no != NULL);
2839 Node* param_node = Node::make_node(param_no); 3363 Node* param_node = Node::make_node(param_no);
2840 switch ((param_node->encoding() & ESCAPE_MASK)) 3364 switch ((param_node->encoding() & ESCAPE_MASK))
2845 // Don't bother tagging for scalars. 3369 // Don't bother tagging for scalars.
2846 fntype->add_parameter_note(i, param_node->encoding()); 3370 fntype->add_parameter_note(i, param_node->encoding());
2847 break; 3371 break;
2848 3372
2849 case Node::ESCAPE_HEAP: // flooded, moved to heap. 3373 case Node::ESCAPE_HEAP: // flooded, moved to heap.
2850 case Node::ESCAPE_SCOPE: // flooded, value leaves scope.
2851 break; 3374 break;
2852 3375
2853 default: 3376 default:
2854 break; 3377 break;
2855 } 3378 }
2865 Gogo::tag_function(Escape_context* context, Named_object* fn) 3388 Gogo::tag_function(Escape_context* context, Named_object* fn)
2866 { 3389 {
2867 Escape_analysis_tag eat(context); 3390 Escape_analysis_tag eat(context);
2868 eat.tag(fn); 3391 eat.tag(fn);
2869 } 3392 }
3393
3394 // Reclaim memory of escape analysis Nodes.
3395
3396 void
3397 Gogo::reclaim_escape_nodes()
3398 {
3399 Node::reclaim_nodes();
3400 }
3401
3402 void
3403 Node::reclaim_nodes()
3404 {
3405 for (std::map<Named_object*, Node*>::iterator p = Node::objects.begin();
3406 p != Node::objects.end();
3407 ++p)
3408 delete p->second;
3409 Node::objects.clear();
3410
3411 for (std::map<Expression*, Node*>::iterator p = Node::expressions.begin();
3412 p != Node::expressions.end();
3413 ++p)
3414 delete p->second;
3415 Node::expressions.clear();
3416
3417 for (std::map<Statement*, Node*>::iterator p = Node::statements.begin();
3418 p != Node::statements.end();
3419 ++p)
3420 delete p->second;
3421 Node::statements.clear();
3422
3423 for (std::vector<Node*>::iterator p = Node::indirects.begin();
3424 p != Node::indirects.end();
3425 ++p)
3426 delete *p;
3427 Node::indirects.clear();
3428 }