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();