~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
142
142
                if(debug['x'])  
143
143
                        print("yyerror: yystate=%d yychar=%d\n", yystate, yychar);
144
144
 
 
145
                // An unexpected EOF caused a syntax error. Use the previous
 
146
                // line number since getc generated a fake newline character.
 
147
                if(curio.eofnl)
 
148
                        lexlineno = prevlineno;
 
149
 
145
150
                // only one syntax error per line
146
151
                if(lastsyntax == lexlineno)
147
152
                        return;
148
153
                lastsyntax = lexlineno;
149
 
                
150
 
                if(strstr(fmt, "{ or {")) {
 
154
                        
 
155
                if(strstr(fmt, "{ or {") || strstr(fmt, " or ?") || strstr(fmt, " or @")) {
151
156
                        // The grammar has { and LBRACE but both show up as {.
152
157
                        // Rewrite syntax error referring to "{ or {" to say just "{".
153
158
                        strecpy(buf, buf+sizeof buf, fmt);
154
159
                        p = strstr(buf, "{ or {");
155
160
                        if(p)
156
161
                                memmove(p+1, p+6, strlen(p+6)+1);
 
162
                        
 
163
                        // The grammar has ? and @ but only for reading imports.
 
164
                        // Silence them in ordinary errors.
 
165
                        p = strstr(buf, " or ?");
 
166
                        if(p)
 
167
                                memmove(p, p+5, strlen(p+5)+1);
 
168
                        p = strstr(buf, " or @");
 
169
                        if(p)
 
170
                                memmove(p, p+5, strlen(p+5)+1);
157
171
                        fmt = buf;
158
172
                }
159
173
                
214
228
        va_start(arg, fmt);
215
229
        adderr(line, fmt, arg);
216
230
        va_end(arg);
 
231
        if(debug['m'])
 
232
                flusherrors();
217
233
}
218
234
 
219
235
void
377
393
        Sym *s, *s1;
378
394
        uint32 h;
379
395
        int n;
 
396
        char *pkgerror;
380
397
 
381
398
        n = 0;
382
399
        for(h=0; h<NHASH; h++) {
389
406
                                continue;
390
407
                        s1 = lookup(s->name);
391
408
                        if(s1->def != N) {
392
 
                                redeclare(s1, "during import");
 
409
                                pkgerror = smprint("during import \"%Z\"", opkg->path);
 
410
                                redeclare(s1, pkgerror);
393
411
                                continue;
394
412
                        }
395
413
                        s1->def = s->def;
396
414
                        s1->block = s->block;
397
415
                        s1->def->pack = pack;
 
416
                        s1->origpkg = opkg;
398
417
                        n++;
399
418
                }
400
419
        }
494
513
        return n;
495
514
}
496
515
 
 
516
void
 
517
saveorignode(Node *n)
 
518
{
 
519
        Node *norig;
 
520
 
 
521
        if(n->orig != N)
 
522
                return;
 
523
        norig = nod(n->op, N, N);
 
524
        *norig = *n;
 
525
        n->orig = norig;
 
526
}
 
527
 
 
528
// ispaddedfield returns whether the given field
 
529
// is followed by padding. For the case where t is
 
530
// the last field, total gives the size of the enclosing struct.
 
531
static int
 
532
ispaddedfield(Type *t, vlong total)
 
533
{
 
534
        if(t->etype != TFIELD)
 
535
                fatal("ispaddedfield called non-field %T", t);
 
536
        if(t->down == T)
 
537
                return t->width + t->type->width != total;
 
538
        return t->width + t->type->width != t->down->width;
 
539
}
 
540
 
497
541
int
498
542
algtype1(Type *t, Type **bad)
499
543
{
504
548
                *bad = T;
505
549
 
506
550
        switch(t->etype) {
 
551
        case TANY:
 
552
        case TFORW:
 
553
                // will be defined later.
 
554
                *bad = t;
 
555
                return -1;
 
556
 
507
557
        case TINT8:
508
558
        case TUINT8:
509
559
        case TINT16:
571
621
                }
572
622
                ret = AMEM;
573
623
                for(t1=t->type; t1!=T; t1=t1->down) {
574
 
                        if(isblanksym(t1->sym))
 
624
                        // Blank fields and padding must be ignored,
 
625
                        // so need special compare.
 
626
                        if(isblanksym(t1->sym) || ispaddedfield(t1, t->width)) {
 
627
                                ret = -1;
575
628
                                continue;
 
629
                        }
576
630
                        a = algtype1(t1->type, bad);
577
631
                        if(a == ANOEQ)
578
632
                                return ANOEQ;  // not comparable
617
671
maptype(Type *key, Type *val)
618
672
{
619
673
        Type *t;
 
674
        Type *bad;
 
675
        int atype;
620
676
 
621
677
        if(key != nil) {
622
 
                switch(key->etype) {
 
678
                atype = algtype1(key, &bad);
 
679
                switch(bad == T ? key->etype : bad->etype) {
623
680
                default:
624
 
                        if(algtype1(key, nil) == ANOEQ)
 
681
                        if(atype == ANOEQ)
625
682
                                yyerror("invalid map key type %T", key);
626
683
                        break;
627
684
                case TANY:
666
723
        
667
724
        a = *(Type**)va;
668
725
        b = *(Type**)vb;
 
726
        if(a->sym == S && b->sym == S)
 
727
                return 0;
 
728
        if(a->sym == S)
 
729
                return -1;
 
730
        if(b->sym == S)
 
731
                return 1;
669
732
        i = strcmp(a->sym->name, b->sym->name);
670
733
        if(i != 0)
671
734
                return i;
776
839
aindex(Node *b, Type *t)
777
840
{
778
841
        Type *r;
779
 
        int bound;
 
842
        int64 bound;
780
843
 
781
844
        bound = -1;     // open bound
782
845
        typecheck(&b, Erv);
813
876
        default:
814
877
                m = nod(OXXX, N, N);
815
878
                *m = *n;
 
879
                m->orig = m;
816
880
                m->left = treecopy(n->left);
817
881
                m->right = treecopy(n->right);
818
882
                m->list = listtreecopy(n->list);
1214
1278
                return 0;
1215
1279
        }
1216
1280
        if(src->etype == TINTER && dst->etype != TBLANK) {
1217
 
                if(why != nil)
 
1281
                if(why != nil && implements(dst, src, &missing, &have, &ptr))
1218
1282
                        *why = ": need type assertion";
1219
1283
                return 0;
1220
1284
        }
1344
1408
        Node *r, *old;
1345
1409
        char *why;
1346
1410
        
1347
 
        if(n == N || n->type == T)
 
1411
        if(n == N || n->type == T || n->type->broke)
1348
1412
                return n;
1349
1413
 
1350
1414
        old = n;
1379
1443
        r->type = t;
1380
1444
        r->typecheck = 1;
1381
1445
        r->implicit = 1;
 
1446
        r->orig = n->orig;
1382
1447
        return r;
1383
1448
}
1384
1449
 
1709
1774
        case OCALLINTER:
1710
1775
                ul = UINF;
1711
1776
                goto out;
 
1777
        case OANDAND:
 
1778
        case OOROR:
 
1779
                // hard with race detector
 
1780
                if(flag_race) {
 
1781
                        ul = UINF;
 
1782
                        goto out;
 
1783
                }
1712
1784
        }
1713
1785
        ul = 1;
1714
1786
        if(n->left != N)
1722
1794
                ul = ur;
1723
1795
 
1724
1796
out:
 
1797
        if(ul > 200)
 
1798
                ul = 200; // clamp to uchar with room to grow
1725
1799
        n->ullman = ul;
1726
1800
}
1727
1801
 
2029
2103
 
2030
2104
/*
2031
2105
 * return n in a local variable of type t if it is not already.
 
2106
 * the value is guaranteed not to change except by direct
 
2107
 * assignment to it.
2032
2108
 */
2033
2109
Node*
2034
2110
localexpr(Node *n, Type *t, NodeList **init)
2035
2111
{
2036
 
        if(n->op == ONAME &&
 
2112
        if(n->op == ONAME && !n->addrtaken &&
2037
2113
                (n->class == PAUTO || n->class == PPARAM || n->class == PPARAMOUT) &&
2038
2114
                convertop(n->type, t, nil) == OCONVNOP)
2039
2115
                return n;
2044
2120
void
2045
2121
setmaxarg(Type *t)
2046
2122
{
2047
 
        int32 w;
 
2123
        int64 w;
2048
2124
 
2049
2125
        dowidth(t);
2050
2126
        w = t->argwid;
2508
2584
 
2509
2585
        funcbody(fn);
2510
2586
        curfn = fn;
 
2587
        // wrappers where T is anonymous (struct{ NamedType }) can be duplicated.
 
2588
        if(rcvr->etype == TSTRUCT || isptr[rcvr->etype] && rcvr->type->etype == TSTRUCT)
 
2589
                fn->dupok = 1;
2511
2590
        typecheck(&fn, Etop);
2512
2591
        typechecklist(fn->nbody, Etop);
 
2592
        inlcalls(fn);
2513
2593
        curfn = nil;
2514
2594
        funccompile(fn, 0);
2515
2595
}
2591
2671
        Node *hashel;
2592
2672
        Type *first, *t1;
2593
2673
        int old_safemode;
2594
 
        int64 size, mul;
 
2674
        int64 size, mul, offend;
2595
2675
 
2596
2676
        if(debug['r'])
2597
2677
                print("genhash %S %T\n", sym, t);
2664
2744
                call->list = list(call->list, nh);
2665
2745
                call->list = list(call->list, nodintconst(t->type->width));
2666
2746
                nx = nod(OINDEX, np, ni);
2667
 
                nx->etype = 1;  // no bounds check
 
2747
                nx->bounded = 1;
2668
2748
                na = nod(OADDR, nx, N);
2669
2749
                na->etype = 1;  // no escape to heap
2670
2750
                call->list = list(call->list, na);
2677
2757
                // Walk the struct using memhash for runs of AMEM
2678
2758
                // and calling specific hash functions for the others.
2679
2759
                first = T;
 
2760
                offend = 0;
2680
2761
                for(t1=t->type;; t1=t1->down) {
2681
 
                        if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) {
2682
 
                                if(first == T && !isblanksym(t1->sym))
 
2762
                        if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) {
 
2763
                                offend = t1->width + t1->type->width;
 
2764
                                if(first == T)
2683
2765
                                        first = t1;
2684
 
                                continue;
 
2766
                                // If it's a memory field but it's padded, stop here.
 
2767
                                if(ispaddedfield(t1, t->width))
 
2768
                                        t1 = t1->down;
 
2769
                                else
 
2770
                                        continue;
2685
2771
                        }
2686
2772
                        // Run memhash for fields up to this one.
2687
 
                        while(first != T && isblanksym(first->sym))
2688
 
                                first = first->down;
2689
2773
                        if(first != T) {
2690
 
                                if(first->down == t1)
2691
 
                                        size = first->type->width;
2692
 
                                else if(t1 == T)
2693
 
                                        size = t->width - first->width;  // first->width is offset
2694
 
                                else
2695
 
                                        size = t1->width - first->width;  // both are offsets
 
2774
                                size = offend - first->width; // first->width is offset
2696
2775
                                hashel = hashmem(first->type);
2697
2776
                                // hashel(h, size, &p.first)
2698
2777
                                call = nod(OCALL, hashel, N);
2708
2787
                        }
2709
2788
                        if(t1 == T)
2710
2789
                                break;
 
2790
                        if(isblanksym(t1->sym))
 
2791
                                continue;
2711
2792
 
2712
2793
                        // Run hash for this field.
2713
2794
                        hashel = hashfor(t1->type);
2721
2802
                        call->list = list(call->list, na);
2722
2803
                        fn->nbody = list(fn->nbody, call);
2723
2804
                }
 
2805
                // make sure body is not empty.
 
2806
                fn->nbody = list(fn->nbody, nod(ORETURN, N, N));
2724
2807
                break;
2725
2808
        }
2726
2809
 
2822
2905
        Type *t1, *first;
2823
2906
        int old_safemode;
2824
2907
        int64 size;
 
2908
        int64 offend;
2825
2909
 
2826
2910
        if(debug['r'])
2827
2911
                print("geneq %S %T\n", sym, t);
2875
2959
                
2876
2960
                // if p[i] != q[i] { *eq = false; return }
2877
2961
                nx = nod(OINDEX, np, ni);
2878
 
                nx->etype = 1;  // no bounds check
 
2962
                nx->bounded = 1;
2879
2963
                ny = nod(OINDEX, nq, ni);
2880
 
                ny->etype = 1;  // no bounds check
 
2964
                ny->bounded = 1;
2881
2965
 
2882
2966
                nif = nod(OIF, N, N);
2883
2967
                nif->ntest = nod(ONE, nx, ny);
2893
2977
        case TSTRUCT:
2894
2978
                // Walk the struct using memequal for runs of AMEM
2895
2979
                // and calling specific equality tests for the others.
 
2980
                // Skip blank-named fields.
2896
2981
                first = T;
 
2982
                offend = 0;
2897
2983
                for(t1=t->type;; t1=t1->down) {
2898
 
                        if(t1 != T && (isblanksym(t1->sym) || algtype1(t1->type, nil) == AMEM)) {
2899
 
                                if(first == T && !isblanksym(t1->sym))
 
2984
                        if(t1 != T && algtype1(t1->type, nil) == AMEM && !isblanksym(t1->sym)) {
 
2985
                                offend = t1->width + t1->type->width;
 
2986
                                if(first == T)
2900
2987
                                        first = t1;
2901
 
                                continue;
 
2988
                                // If it's a memory field but it's padded, stop here.
 
2989
                                if(ispaddedfield(t1, t->width))
 
2990
                                        t1 = t1->down;
 
2991
                                else
 
2992
                                        continue;
2902
2993
                        }
2903
2994
                        // Run memequal for fields up to this one.
2904
2995
                        // TODO(rsc): All the calls to newname are wrong for
2905
2996
                        // cross-package unexported fields.
2906
 
                        while(first != T && isblanksym(first->sym))
2907
 
                                first = first->down;
2908
2997
                        if(first != T) {
2909
2998
                                if(first->down == t1) {
2910
2999
                                        fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
2915
3004
                                                fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
2916
3005
                                } else {
2917
3006
                                        // More than two fields: use memequal.
2918
 
                                        if(t1 == T)
2919
 
                                                size = t->width - first->width;  // first->width is offset
2920
 
                                        else
2921
 
                                                size = t1->width - first->width;  // both are offsets
 
3007
                                        size = offend - first->width; // first->width is offset
2922
3008
                                        fn->nbody = list(fn->nbody, eqmem(np, nq, newname(first->sym), size, neq));
2923
3009
                                }
2924
3010
                                first = T;
2925
3011
                        }
2926
3012
                        if(t1 == T)
2927
3013
                                break;
 
3014
                        if(isblanksym(t1->sym))
 
3015
                                continue;
2928
3016
 
2929
3017
                        // Check this field, which is not just memory.
2930
3018
                        fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->sym), neq));
3031
3119
        for(im=iface->type; im; im=im->down) {
3032
3120
                imtype = methodfunc(im->type, 0);
3033
3121
                tm = ifacelookdot(im->sym, t, &followptr, 0);
3034
 
                if(tm == T || !eqtype(methodfunc(tm->type, 0), imtype)) {
 
3122
                if(tm == T || tm->nointerface || !eqtype(methodfunc(tm->type, 0), imtype)) {
3035
3123
                        if(tm == T)
3036
3124
                                tm = ifacelookdot(im->sym, t, &followptr, 1);
3037
3125
                        *m = im;
3210
3298
int
3211
3299
count(NodeList *l)
3212
3300
{
3213
 
        int n;
 
3301
        vlong n;
3214
3302
 
3215
3303
        n = 0;
3216
3304
        for(; l; l=l->next)
3217
3305
                n++;
 
3306
        if((int)n != n) { // Overflow.
 
3307
                yyerror("too many elements in list");
 
3308
        }
3218
3309
        return n;
3219
3310
}
3220
3311
 
3504
3595
Sym*
3505
3596
ngotype(Node *n)
3506
3597
{
3507
 
        if(n->sym != S && n->realtype != T)
3508
 
        if(strncmp(n->sym->name, "autotmp_", 8) != 0)
3509
 
        if(strncmp(n->sym->name, "statictmp_", 8) != 0)
3510
 
                return typename(n->realtype)->left->sym;
3511
 
 
 
3598
        if(n->type != T)
 
3599
                return typenamesym(n->type);
3512
3600
        return S;
3513
3601
}
3514
3602
 
3564
3652
        Pkg *p;
3565
3653
        int h;
3566
3654
 
3567
 
        if(isbadimport(path))
3568
 
                errorexit();
3569
 
        
3570
3655
        h = stringhash(path->s) & (nelem(phash)-1);
3571
3656
        for(p=phash[h]; p; p=p->link)
3572
3657
                if(p->path->len == path->len && memcmp(path->s, p->path->s, path->len) == 0)
3615
3700
        n->ullman = UINF;
3616
3701
}
3617
3702
 
 
3703
static char* reservedimports[] = {
 
3704
        "go",
 
3705
        "type",
 
3706
};
 
3707
 
3618
3708
int
3619
3709
isbadimport(Strlit *path)
3620
3710
{
 
3711
        int i;
3621
3712
        char *s;
3622
3713
        Rune r;
3623
3714
 
3625
3716
                yyerror("import path contains NUL");
3626
3717
                return 1;
3627
3718
        }
 
3719
        
 
3720
        for(i=0; i<nelem(reservedimports); i++) {
 
3721
                if(strcmp(path->s, reservedimports[i]) == 0) {
 
3722
                        yyerror("import path \"%s\" is reserved and cannot be used", path->s);
 
3723
                        return 1;
 
3724
                }
 
3725
        }
3628
3726
 
3629
3727
        s = path->s;
3630
3728
        while(*s) {
3652
3750
        }
3653
3751
        return 0;
3654
3752
}
 
3753
 
 
3754
void
 
3755
checknotnil(Node *x, NodeList **init)
 
3756
{
 
3757
        Node *n;
 
3758
        
 
3759
        if(isinter(x->type)) {
 
3760
                x = nod(OITAB, x, N);
 
3761
                typecheck(&x, Erv);
 
3762
        }
 
3763
        n = nod(OCHECKNOTNIL, x, N);
 
3764
        n->typecheck = 1;
 
3765
        *init = list(*init, n);
 
3766
}