~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to src/cmd/gc/esc.c

  • Committer: Package Import Robot
  • Author(s): Ondřej Surý
  • Date: 2012-05-02 15:44:59 UTC
  • mfrom: (14.1.12 sid)
  • Revision ID: package-import@ubuntu.com-20120502154459-wcmy8ao1325ml619
Tags: 2:1.0.1-1
* Imported Upstream version 1.0.1
* Apply godoc patch to display package list correctly (Closes: #669354)

Show diffs side-by-side

added added

removed removed

Lines of Context:
131
131
        }
132
132
 
133
133
        // walk will take the address of cvar->closure later and assign it to cvar.
134
 
        // handle that here by linking a fake oaddr node directly to the closure.
 
134
        // linking a fake oaddr node directly to the closure handles the case
 
135
        // of the closure itself leaking.  Following the flow of the value to th
 
136
        // paramref is done in escflow, because if we did that here, it would look
 
137
        // like the original is assigned out of its loop depth, whereas it's just
 
138
        // assigned to something in an inner function.  A paramref itself is never
 
139
        // moved to the heap, only its original.
135
140
        for(ll=curfn->cvars; ll; ll=ll->next) {
136
141
                if(ll->n->op == OXXX)  // see dcl.c:398
137
142
                        continue;
221
226
        if(n->op == OFOR || n->op == ORANGE)
222
227
                loopdepth++;
223
228
 
224
 
        esc(n->left);
225
 
        esc(n->right);
226
 
        esc(n->ntest);
227
 
        esc(n->nincr);
228
 
        esclist(n->ninit);
229
 
        esclist(n->nbody);
230
 
        esclist(n->nelse);
231
 
        esclist(n->list);
232
 
        esclist(n->rlist);
233
 
 
 
229
        if(n->op == OCLOSURE) {
 
230
                escfunc(n);
 
231
        } else {
 
232
                esc(n->left);
 
233
                esc(n->right);
 
234
                esc(n->ntest);
 
235
                esc(n->nincr);
 
236
                esclist(n->ninit);
 
237
                esclist(n->nbody);
 
238
                esclist(n->nelse);
 
239
                esclist(n->list);
 
240
                esclist(n->rlist);
 
241
        }
234
242
        if(n->op == OFOR || n->op == ORANGE)
235
243
                loopdepth--;
236
244
 
379
387
                }
380
388
                break;
381
389
        
 
390
        case OCLOSURE:
382
391
        case OADDR:
383
 
        case OCLOSURE:
384
392
        case OMAKECHAN:
385
393
        case OMAKEMAP:
386
394
        case OMAKESLICE:
407
415
                return;
408
416
 
409
417
        if(debug['m'] > 1)
410
 
                print("%L:[%d] %S escassign: %hN = %hN\n", lineno, loopdepth,
411
 
                      (curfn && curfn->nname) ? curfn->nname->sym : S, dst, src);
 
418
                print("%L:[%d] %S escassign: %hN(%hJ) = %hN(%hJ)\n", lineno, loopdepth,
 
419
                      (curfn && curfn->nname) ? curfn->nname->sym : S, dst, dst, src, src);
412
420
 
413
421
        setlineno(dst);
414
422
        
467
475
        case OARRAYLIT:
468
476
        case OMAPLIT:
469
477
        case OSTRUCTLIT:
470
 
                // loopdepth was set in the defining statement or function header
 
478
        case OMAKECHAN:
 
479
        case OMAKEMAP:
 
480
        case OMAKESLICE:
 
481
        case ONEW:
 
482
        case OCLOSURE:
471
483
                escflows(dst, src);
472
484
                break;
473
485
 
500
512
                        escassign(dst, src->left);
501
513
                break;
502
514
 
503
 
        case OMAKECHAN:
504
 
        case OMAKEMAP:
505
 
        case OMAKESLICE:
506
 
        case ONEW:
507
 
                escflows(dst, src);
508
 
                break;
509
 
 
510
 
        case OCLOSURE:
511
 
                escflows(dst, src);
512
 
                escfunc(src);
513
 
                break;
514
 
 
515
515
        case OADD:
516
516
        case OSUB:
517
517
        case OOR:
543
543
// This is a bit messier than fortunate, pulled out of escassign's big
544
544
// switch for clarity.  We either have the paramnodes, which may be
545
545
// connected to other things throug flows or we have the parameter type
546
 
// nodes, which may be marked 'n(ofloworescape)'. Navigating the ast is slightly
 
546
// nodes, which may be marked "noescape". Navigating the ast is slightly
547
547
// different for methods vs plain functions and for imported vs
548
548
// this-package
549
549
static void
711
711
        src->walkgen = walkgen;
712
712
 
713
713
        if(debug['m']>1)
714
 
                print("escwalk: level:%d depth:%d %.*s %hN scope:%S[%d]\n",
715
 
                      level, pdepth, pdepth, "\t\t\t\t\t\t\t\t\t\t", src,
 
714
                print("escwalk: level:%d depth:%d %.*s %hN(%hJ) scope:%S[%d]\n",
 
715
                      level, pdepth, pdepth, "\t\t\t\t\t\t\t\t\t\t", src, src,
716
716
                      (src->curfn && src->curfn->nname) ? src->curfn->nname->sym : S, src->escloopdepth);
717
717
 
718
718
        pdepth++;
726
726
                        if(debug['m'])
727
727
                                warnl(src->lineno, "leaking param: %hN", src);
728
728
                }
 
729
                // handle the missing flow ref <- orig
 
730
                // a paramref is automagically dereferenced, and taking its
 
731
                // address produces the address of the original, so all we have to do here
 
732
                // is keep track of the value flow, so level is unchanged.
 
733
                // alternatively, we could have substituted PPARAMREFs with their ->closure in esc/escassign/flow,
 
734
                if(src->class == PPARAMREF) {
 
735
                        if(leaks && debug['m'])
 
736
                                warnl(src->lineno, "leaking closure reference %hN", src);
 
737
                        escwalk(level, dst, src->closure);
 
738
                }
729
739
                break;
730
740
 
731
741
        case OPTRLIT: