Mercurial > projects > ldc
comparison gen/llvmhelpers.cpp @ 399:0e6b4d65d3f8
Give error messages for invalid casts.
This required passing Loc information to certain functions.
Fixes nocompile/b/bug_cgcs_354_A/B.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 26 Jul 2008 17:19:16 +0200 |
parents | d1574e142e93 |
children | 023fa78c1203 |
comparison
equal
deleted
inserted
replaced
398:811f82dfddbd | 399:0e6b4d65d3f8 |
---|---|
510 /****************************************************************************************/ | 510 /****************************************************************************************/ |
511 /*//////////////////////////////////////////////////////////////////////////////////////// | 511 /*//////////////////////////////////////////////////////////////////////////////////////// |
512 // ASSIGNMENT HELPER (store this in that) | 512 // ASSIGNMENT HELPER (store this in that) |
513 ////////////////////////////////////////////////////////////////////////////////////////*/ | 513 ////////////////////////////////////////////////////////////////////////////////////////*/ |
514 | 514 |
515 void DtoAssign(DValue* lhs, DValue* rhs) | 515 void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) |
516 { | 516 { |
517 Logger::cout() << "DtoAssign(...);\n"; | 517 Logger::cout() << "DtoAssign(...);\n"; |
518 LOG_SCOPE; | 518 LOG_SCOPE; |
519 | 519 |
520 Type* t = DtoDType(lhs->getType()); | 520 Type* t = DtoDType(lhs->getType()); |
534 if (DSliceValue* s = lhs->isSlice()) { | 534 if (DSliceValue* s = lhs->isSlice()) { |
535 if (DSliceValue* s2 = rhs->isSlice()) { | 535 if (DSliceValue* s2 = rhs->isSlice()) { |
536 DtoArrayCopySlices(s, s2); | 536 DtoArrayCopySlices(s, s2); |
537 } | 537 } |
538 else if (t->next->toBasetype()->equals(t2)) { | 538 else if (t->next->toBasetype()->equals(t2)) { |
539 DtoArrayInit(s, rhs); | 539 DtoArrayInit(loc, s, rhs); |
540 } | 540 } |
541 else { | 541 else { |
542 DtoArrayCopyToSlice(s, rhs); | 542 DtoArrayCopyToSlice(s, rhs); |
543 } | 543 } |
544 } | 544 } |
559 else if (t->ty == Tsarray) { | 559 else if (t->ty == Tsarray) { |
560 if (DtoType(lhs->getType()) == DtoType(rhs->getType())) { | 560 if (DtoType(lhs->getType()) == DtoType(rhs->getType())) { |
561 DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); | 561 DtoStaticArrayCopy(lhs->getLVal(), rhs->getRVal()); |
562 } | 562 } |
563 else { | 563 else { |
564 DtoArrayInit(lhs, rhs); | 564 DtoArrayInit(loc, lhs, rhs); |
565 } | 565 } |
566 } | 566 } |
567 else if (t->ty == Tdelegate) { | 567 else if (t->ty == Tdelegate) { |
568 if (rhs->isNull()) | 568 if (rhs->isNull()) |
569 DtoAggrZeroInit(lhs->getLVal()); | 569 DtoAggrZeroInit(lhs->getLVal()); |
594 assert(!lhs->isComplex()); | 594 assert(!lhs->isComplex()); |
595 | 595 |
596 LLValue* dst; | 596 LLValue* dst; |
597 if (DLRValue* lr = lhs->isLRValue()) { | 597 if (DLRValue* lr = lhs->isLRValue()) { |
598 dst = lr->getLVal(); | 598 dst = lr->getLVal(); |
599 rhs = DtoCastComplex(rhs, lr->getLType()); | 599 rhs = DtoCastComplex(loc, rhs, lr->getLType()); |
600 } | 600 } |
601 else { | 601 else { |
602 dst = lhs->getRVal(); | 602 dst = lhs->getRVal(); |
603 } | 603 } |
604 | 604 |
614 const LLType* lit = l->getType()->getContainedType(0); | 614 const LLType* lit = l->getType()->getContainedType(0); |
615 if (r->getType() != lit) { | 615 if (r->getType() != lit) { |
616 // handle lvalue cast assignments | 616 // handle lvalue cast assignments |
617 if (DLRValue* lr = lhs->isLRValue()) { | 617 if (DLRValue* lr = lhs->isLRValue()) { |
618 Logger::println("lvalue cast!"); | 618 Logger::println("lvalue cast!"); |
619 r = DtoCast(rhs, lr->getLType())->getRVal(); | 619 r = DtoCast(loc, rhs, lr->getLType())->getRVal(); |
620 } | 620 } |
621 else { | 621 else { |
622 r = DtoCast(rhs, lhs->getType())->getRVal(); | 622 r = DtoCast(loc, rhs, lhs->getType())->getRVal(); |
623 } | 623 } |
624 Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; | 624 Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; |
625 assert(r->getType() == l->getType()->getContainedType(0)); | 625 assert(r->getType() == l->getType()->getContainedType(0)); |
626 } | 626 } |
627 gIR->ir->CreateStore(r, l); | 627 gIR->ir->CreateStore(r, l); |
674 /****************************************************************************************/ | 674 /****************************************************************************************/ |
675 /*//////////////////////////////////////////////////////////////////////////////////////// | 675 /*//////////////////////////////////////////////////////////////////////////////////////// |
676 // CASTING HELPERS | 676 // CASTING HELPERS |
677 ////////////////////////////////////////////////////////////////////////////////////////*/ | 677 ////////////////////////////////////////////////////////////////////////////////////////*/ |
678 | 678 |
679 DValue* DtoCastInt(DValue* val, Type* _to) | 679 DValue* DtoCastInt(Loc& loc, DValue* val, Type* _to) |
680 { | 680 { |
681 const LLType* tolltype = DtoType(_to); | 681 const LLType* tolltype = DtoType(_to); |
682 | 682 |
683 Type* to = DtoDType(_to); | 683 Type* to = DtoDType(_to); |
684 Type* from = DtoDType(val->getType()); | 684 Type* from = DtoDType(val->getType()); |
707 else { | 707 else { |
708 rval = DtoBitCast(rval, tolltype); | 708 rval = DtoBitCast(rval, tolltype); |
709 } | 709 } |
710 } | 710 } |
711 else if (to->iscomplex()) { | 711 else if (to->iscomplex()) { |
712 return DtoComplex(to, val); | 712 return DtoComplex(loc, to, val); |
713 } | 713 } |
714 else if (to->isfloating()) { | 714 else if (to->isfloating()) { |
715 if (from->isunsigned()) { | 715 if (from->isunsigned()) { |
716 rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); | 716 rval = new llvm::UIToFPInst(rval, tolltype, "tmp", gIR->scopebb()); |
717 } | 717 } |
722 else if (to->ty == Tpointer) { | 722 else if (to->ty == Tpointer) { |
723 Logger::cout() << "cast pointer: " << *tolltype << '\n'; | 723 Logger::cout() << "cast pointer: " << *tolltype << '\n'; |
724 rval = gIR->ir->CreateIntToPtr(rval, tolltype, "tmp"); | 724 rval = gIR->ir->CreateIntToPtr(rval, tolltype, "tmp"); |
725 } | 725 } |
726 else { | 726 else { |
727 assert(0 && "bad int cast"); | 727 error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), _to->toChars()); |
728 fatal(); | |
728 } | 729 } |
729 | 730 |
730 return new DImValue(_to, rval); | 731 return new DImValue(_to, rval); |
731 } | 732 } |
732 | 733 |
733 DValue* DtoCastPtr(DValue* val, Type* to) | 734 DValue* DtoCastPtr(Loc& loc, DValue* val, Type* to) |
734 { | 735 { |
735 const LLType* tolltype = DtoType(to); | 736 const LLType* tolltype = DtoType(to); |
736 | 737 |
737 Type* totype = DtoDType(to); | 738 Type* totype = DtoDType(to); |
738 Type* fromtype = DtoDType(val->getType()); | 739 Type* fromtype = DtoDType(val->getType()); |
747 } | 748 } |
748 else if (totype->isintegral()) { | 749 else if (totype->isintegral()) { |
749 rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); | 750 rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); |
750 } | 751 } |
751 else { | 752 else { |
752 Logger::println("invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); | 753 error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); |
753 assert(0); | 754 fatal(); |
754 } | 755 } |
755 | 756 |
756 return new DImValue(to, rval); | 757 return new DImValue(to, rval); |
757 } | 758 } |
758 | 759 |
759 DValue* DtoCastFloat(DValue* val, Type* to) | 760 DValue* DtoCastFloat(Loc& loc, DValue* val, Type* to) |
760 { | 761 { |
761 if (val->getType() == to) | 762 if (val->getType() == to) |
762 return val; | 763 return val; |
763 | 764 |
764 const LLType* tolltype = DtoType(to); | 765 const LLType* tolltype = DtoType(to); |
771 size_t tosz = totype->size(); | 772 size_t tosz = totype->size(); |
772 | 773 |
773 LLValue* rval; | 774 LLValue* rval; |
774 | 775 |
775 if (totype->iscomplex()) { | 776 if (totype->iscomplex()) { |
776 return DtoComplex(to, val); | 777 return DtoComplex(loc, to, val); |
777 } | 778 } |
778 else if (totype->isfloating()) { | 779 else if (totype->isfloating()) { |
779 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { | 780 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { |
780 rval = val->getRVal(); | 781 rval = val->getRVal(); |
781 } | 782 } |
787 } | 788 } |
788 else if (fromsz > tosz) { | 789 else if (fromsz > tosz) { |
789 rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); | 790 rval = new llvm::FPTruncInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); |
790 } | 791 } |
791 else { | 792 else { |
792 assert(0 && "bad float cast"); | 793 error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); |
794 fatal(); | |
793 } | 795 } |
794 } | 796 } |
795 else if (totype->isintegral()) { | 797 else if (totype->isintegral()) { |
796 if (totype->isunsigned()) { | 798 if (totype->isunsigned()) { |
797 rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); | 799 rval = new llvm::FPToUIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); |
799 else { | 801 else { |
800 rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); | 802 rval = new llvm::FPToSIInst(val->getRVal(), tolltype, "tmp", gIR->scopebb()); |
801 } | 803 } |
802 } | 804 } |
803 else { | 805 else { |
804 assert(0 && "bad float cast"); | 806 error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); |
807 fatal(); | |
805 } | 808 } |
806 | 809 |
807 return new DImValue(to, rval); | 810 return new DImValue(to, rval); |
808 } | 811 } |
809 | 812 |
810 DValue* DtoCast(DValue* val, Type* to) | 813 DValue* DtoCast(Loc& loc, DValue* val, Type* to) |
811 { | 814 { |
812 Type* fromtype = DtoDType(val->getType()); | 815 Type* fromtype = DtoDType(val->getType()); |
813 Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); | 816 Logger::println("Casting from '%s' to '%s'", fromtype->toChars(), to->toChars()); |
814 if (fromtype->isintegral()) { | 817 if (fromtype->isintegral()) { |
815 return DtoCastInt(val, to); | 818 return DtoCastInt(loc, val, to); |
816 } | 819 } |
817 else if (fromtype->iscomplex()) { | 820 else if (fromtype->iscomplex()) { |
818 return DtoCastComplex(val, to); | 821 return DtoCastComplex(loc, val, to); |
819 } | 822 } |
820 else if (fromtype->isfloating()) { | 823 else if (fromtype->isfloating()) { |
821 return DtoCastFloat(val, to); | 824 return DtoCastFloat(loc, val, to); |
822 } | 825 } |
823 else if (fromtype->ty == Tclass) { | 826 else if (fromtype->ty == Tclass) { |
824 return DtoCastClass(val, to); | 827 return DtoCastClass(val, to); |
825 } | 828 } |
826 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { | 829 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { |
827 return DtoCastArray(val, to); | 830 return DtoCastArray(val, to); |
828 } | 831 } |
829 else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) { | 832 else if (fromtype->ty == Tpointer || fromtype->ty == Tfunction) { |
830 return DtoCastPtr(val, to); | 833 return DtoCastPtr(loc, val, to); |
831 } | 834 } |
832 else { | 835 else { |
833 assert(0); | 836 error(loc, "invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars()); |
837 fatal(); | |
834 } | 838 } |
835 } | 839 } |
836 | 840 |
837 /****************************************************************************************/ | 841 /****************************************************************************************/ |
838 /*//////////////////////////////////////////////////////////////////////////////////////// | 842 /*//////////////////////////////////////////////////////////////////////////////////////// |
870 gIR->ir->CreateCondBr(cond, initbb, endinitbb); | 874 gIR->ir->CreateCondBr(cond, initbb, endinitbb); |
871 gIR->scope() = IRScope(initbb,endinitbb); | 875 gIR->scope() = IRScope(initbb,endinitbb); |
872 DValue* ie = DtoInitializer(init); | 876 DValue* ie = DtoInitializer(init); |
873 if (!ie->inPlace()) { | 877 if (!ie->inPlace()) { |
874 DValue* dst = new DVarValue(t, gvar, true); | 878 DValue* dst = new DVarValue(t, gvar, true); |
875 DtoAssign(dst, ie); | 879 DtoAssign(init->loc, dst, ie); |
876 } | 880 } |
877 gIR->ir->CreateStore(DtoConstBool(true), gflag); | 881 gIR->ir->CreateStore(DtoConstBool(true), gflag); |
878 gIR->ir->CreateBr(endinitbb); | 882 gIR->ir->CreateBr(endinitbb); |
879 gIR->scope() = IRScope(endinitbb,oldend); | 883 gIR->scope() = IRScope(endinitbb,oldend); |
880 } | 884 } |
1357 } | 1361 } |
1358 } | 1362 } |
1359 | 1363 |
1360 ////////////////////////////////////////////////////////////////////////////////////////// | 1364 ////////////////////////////////////////////////////////////////////////////////////////// |
1361 | 1365 |
1362 LLValue* DtoBoolean(DValue* dval) | 1366 LLValue* DtoBoolean(Loc& loc, DValue* dval) |
1363 { | 1367 { |
1364 Type* dtype = dval->getType()->toBasetype(); | 1368 Type* dtype = dval->getType()->toBasetype(); |
1365 TY ty = dtype->ty; | 1369 TY ty = dtype->ty; |
1366 | 1370 |
1367 // integer | 1371 // integer |
1376 } | 1380 } |
1377 } | 1381 } |
1378 // complex | 1382 // complex |
1379 else if (dtype->iscomplex()) | 1383 else if (dtype->iscomplex()) |
1380 { | 1384 { |
1381 return DtoComplexEquals(TOKnotequal, dval, DtoNullValue(dtype)); | 1385 return DtoComplexEquals(loc, TOKnotequal, dval, DtoNullValue(dtype)); |
1382 } | 1386 } |
1383 // floating point | 1387 // floating point |
1384 else if (dtype->isfloating()) | 1388 else if (dtype->isfloating()) |
1385 { | 1389 { |
1386 LLValue* val = dval->getRVal(); | 1390 LLValue* val = dval->getRVal(); |