Mercurial > projects > ldc
comparison dmd2/cast.c @ 1526:54b3c1394d62
Merged dmdfe 2.031.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 07 Jul 2009 02:26:11 +0100 |
parents | 638d16625da2 |
children | e4f7b5d9c68a |
comparison
equal
deleted
inserted
replaced
1525:d28cd7c45267 | 1526:54b3c1394d62 |
---|---|
31 | 31 |
32 MATCH match = implicitConvTo(t); | 32 MATCH match = implicitConvTo(t); |
33 if (match) | 33 if (match) |
34 { TY tyfrom = type->toBasetype()->ty; | 34 { TY tyfrom = type->toBasetype()->ty; |
35 TY tyto = t->toBasetype()->ty; | 35 TY tyto = t->toBasetype()->ty; |
36 #if DMDV1 | |
36 if (global.params.warnings && | 37 if (global.params.warnings && |
37 Type::impcnvWarn[tyfrom][tyto] && | 38 Type::impcnvWarn[tyfrom][tyto] && |
38 op != TOKint64) | 39 op != TOKint64) |
39 { | 40 { |
40 Expression *e = optimize(WANTflags | WANTvalue); | 41 Expression *e = optimize(WANTflags | WANTvalue); |
41 | 42 |
42 if (e->op == TOKint64) | 43 if (e->op == TOKint64) |
43 return e->implicitCastTo(sc, t); | 44 return e->implicitCastTo(sc, t); |
44 | |
45 if (tyfrom == Tint32 && | 45 if (tyfrom == Tint32 && |
46 (op == TOKadd || op == TOKmin || | 46 (op == TOKadd || op == TOKmin || |
47 op == TOKand || op == TOKor || op == TOKxor) | 47 op == TOKand || op == TOKor || op == TOKxor) |
48 ) | 48 ) |
49 { | 49 { |
59 { | 59 { |
60 warning("implicit conversion of expression (%s) of type %s to %s can cause loss of data", | 60 warning("implicit conversion of expression (%s) of type %s to %s can cause loss of data", |
61 toChars(), type->toChars(), t->toChars()); | 61 toChars(), type->toChars(), t->toChars()); |
62 } | 62 } |
63 } | 63 } |
64 #endif | |
64 #if DMDV2 | 65 #if DMDV2 |
65 if (match == MATCHconst && t == type->constOf()) | 66 if (match == MATCHconst && t == type->constOf()) |
66 { | 67 { |
67 Expression *e = copy(); | 68 Expression *e = copy(); |
68 e->type = t; | 69 e->type = t; |
142 return e->implicitConvTo(t); | 143 return e->implicitConvTo(t); |
143 } | 144 } |
144 MATCH match = type->implicitConvTo(t); | 145 MATCH match = type->implicitConvTo(t); |
145 if (match != MATCHnomatch) | 146 if (match != MATCHnomatch) |
146 return match; | 147 return match; |
148 | |
149 /* See if we can do integral narrowing conversions | |
150 */ | |
151 if (type->isintegral() && t->isintegral() && | |
152 type->isTypeBasic() && t->isTypeBasic()) | |
153 { IntRange ir = getIntRange(); | |
154 if (ir.imax <= t->sizemask()) | |
155 return MATCHconvert; | |
156 } | |
157 | |
147 #if 0 | 158 #if 0 |
148 Type *tb = t->toBasetype(); | 159 Type *tb = t->toBasetype(); |
149 if (tb->ty == Tdelegate) | 160 if (tb->ty == Tdelegate) |
150 { TypeDelegate *td = (TypeDelegate *)tb; | 161 { TypeDelegate *td = (TypeDelegate *)tb; |
151 TypeFunction *tf = (TypeFunction *)td->nextOf(); | 162 TypeFunction *tf = (TypeFunction *)td->nextOf(); |
674 } | 685 } |
675 } | 686 } |
676 return result; | 687 return result; |
677 } | 688 } |
678 | 689 |
690 MATCH OrExp::implicitConvTo(Type *t) | |
691 { | |
692 MATCH result = Expression::implicitConvTo(t); | |
693 | |
694 if (result == MATCHnomatch) | |
695 { | |
696 MATCH m1 = e1->implicitConvTo(t); | |
697 MATCH m2 = e2->implicitConvTo(t); | |
698 | |
699 // Pick the worst match | |
700 result = (m1 < m2) ? m1 : m2; | |
701 } | |
702 return result; | |
703 } | |
704 | |
705 MATCH XorExp::implicitConvTo(Type *t) | |
706 { | |
707 MATCH result = Expression::implicitConvTo(t); | |
708 | |
709 if (result == MATCHnomatch) | |
710 { | |
711 MATCH m1 = e1->implicitConvTo(t); | |
712 MATCH m2 = e2->implicitConvTo(t); | |
713 | |
714 // Pick the worst match | |
715 result = (m1 < m2) ? m1 : m2; | |
716 } | |
717 return result; | |
718 } | |
719 | |
679 MATCH CondExp::implicitConvTo(Type *t) | 720 MATCH CondExp::implicitConvTo(Type *t) |
680 { | 721 { |
681 MATCH m1; | 722 MATCH m1 = e1->implicitConvTo(t); |
682 MATCH m2; | 723 MATCH m2 = e2->implicitConvTo(t); |
683 | 724 //printf("CondExp: m1 %d m2 %d\n", m1, m2); |
684 m1 = e1->implicitConvTo(t); | |
685 m2 = e2->implicitConvTo(t); | |
686 | 725 |
687 // Pick the worst match | 726 // Pick the worst match |
688 return (m1 < m2) ? m1 : m2; | 727 return (m1 < m2) ? m1 : m2; |
689 } | 728 } |
690 | 729 |
730 MATCH CommaExp::implicitConvTo(Type *t) | |
731 { | |
732 return e2->implicitConvTo(t); | |
733 } | |
734 | |
735 MATCH CastExp::implicitConvTo(Type *t) | |
736 { | |
737 #if 0 | |
738 printf("CastExp::implicitConvTo(this=%s, type=%s, t=%s)\n", | |
739 toChars(), type->toChars(), t->toChars()); | |
740 #endif | |
741 MATCH result; | |
742 | |
743 result = type->implicitConvTo(t); | |
744 | |
745 if (result == MATCHnomatch) | |
746 { | |
747 if (t->isintegral() && | |
748 e1->type->isintegral() && | |
749 e1->implicitConvTo(t) != MATCHnomatch) | |
750 result = MATCHconvert; | |
751 else | |
752 result = Expression::implicitConvTo(t); | |
753 } | |
754 return result; | |
755 } | |
691 | 756 |
692 /* ==================== castTo ====================== */ | 757 /* ==================== castTo ====================== */ |
693 | 758 |
694 /************************************** | 759 /************************************** |
695 * Do an explicit cast. | 760 * Do an explicit cast. |
1256 if (f) | 1321 if (f) |
1257 { | 1322 { |
1258 f = f->overloadExactMatch(tb->nextOf(), m); | 1323 f = f->overloadExactMatch(tb->nextOf(), m); |
1259 if (f) | 1324 if (f) |
1260 { | 1325 { |
1261 if (tb->ty == Tdelegate && f->needThis() && hasThis(sc)) | 1326 if (tb->ty == Tdelegate) |
1262 { | 1327 { |
1263 e = new DelegateExp(loc, new ThisExp(loc), f); | 1328 if (f->needThis() && hasThis(sc)) |
1264 e = e->semantic(sc); | 1329 { |
1265 } | 1330 e = new DelegateExp(loc, new ThisExp(loc), f); |
1266 else if (tb->ty == Tdelegate && f->isNested()) | 1331 e = e->semantic(sc); |
1267 { | 1332 } |
1268 e = new DelegateExp(loc, new IntegerExp(0), f); | 1333 else if (f->isNested()) |
1269 e = e->semantic(sc); | 1334 { |
1335 e = new DelegateExp(loc, new IntegerExp(0), f); | |
1336 e = e->semantic(sc); | |
1337 } | |
1338 else if (f->needThis()) | |
1339 { error("no 'this' to create delegate for %s", f->toChars()); | |
1340 e = new ErrorExp(); | |
1341 } | |
1342 else | |
1343 { error("cannot cast from function pointer to delegate"); | |
1344 e = new ErrorExp(); | |
1345 } | |
1270 } | 1346 } |
1271 else | 1347 else |
1272 { | 1348 { |
1273 e = new SymOffExp(loc, f, 0); | 1349 e = new SymOffExp(loc, f, 0); |
1274 e->type = t; | 1350 e->type = t; |
1275 } | 1351 } |
1352 #if DMDV2 | |
1276 f->tookAddressOf++; | 1353 f->tookAddressOf++; |
1354 #endif | |
1277 return e; | 1355 return e; |
1278 } | 1356 } |
1279 } | 1357 } |
1280 } | 1358 } |
1281 e = Expression::castTo(sc, t); | 1359 e = Expression::castTo(sc, t); |
1351 e = Expression::castTo(sc, t); | 1429 e = Expression::castTo(sc, t); |
1352 } | 1430 } |
1353 return e; | 1431 return e; |
1354 } | 1432 } |
1355 | 1433 |
1434 Expression *CommaExp::castTo(Scope *sc, Type *t) | |
1435 { | |
1436 Expression *e2c = e2->castTo(sc, t); | |
1437 Expression *e; | |
1438 | |
1439 if (e2c != e2) | |
1440 { | |
1441 e = new CommaExp(loc, e1, e2c); | |
1442 e->type = e2c->type; | |
1443 } | |
1444 else | |
1445 { e = this; | |
1446 e->type = e2->type; | |
1447 } | |
1448 return e; | |
1449 } | |
1450 | |
1356 /* ==================== ====================== */ | 1451 /* ==================== ====================== */ |
1357 | 1452 |
1358 /**************************************** | 1453 /**************************************** |
1359 * Scale addition/subtraction to/from pointer. | 1454 * Scale addition/subtraction to/from pointer. |
1360 */ | 1455 */ |
1775 } | 1870 } |
1776 return 1; | 1871 return 1; |
1777 } | 1872 } |
1778 return 0; | 1873 return 0; |
1779 } | 1874 } |
1875 | |
1876 /******************************************************************/ | |
1877 | |
1878 /* Determine the integral ranges of an expression. | |
1879 * This is used to determine if implicit narrowing conversions will | |
1880 * be allowed. | |
1881 */ | |
1882 | |
1883 uinteger_t getMask(uinteger_t v) | |
1884 { | |
1885 uinteger_t u = 0; | |
1886 if (v >= 0x80) | |
1887 u = 0xFF; | |
1888 while (u < v) | |
1889 u = (u << 1) | 1; | |
1890 return u; | |
1891 } | |
1892 | |
1893 IntRange Expression::getIntRange() | |
1894 { | |
1895 IntRange ir; | |
1896 ir.imin = 0; | |
1897 ir.imax = type->sizemask(); | |
1898 return ir; | |
1899 } | |
1900 | |
1901 IntRange IntegerExp::getIntRange() | |
1902 { | |
1903 IntRange ir; | |
1904 ir.imin = value & type->sizemask(); | |
1905 ir.imax = ir.imin; | |
1906 return ir; | |
1907 } | |
1908 | |
1909 IntRange CastExp::getIntRange() | |
1910 { | |
1911 IntRange ir; | |
1912 ir = e1->getIntRange(); | |
1913 // Do sign extension | |
1914 switch (e1->type->toBasetype()->ty) | |
1915 { | |
1916 case Tint8: | |
1917 if (ir.imax & 0x80) | |
1918 ir.imax |= 0xFFFFFFFFFFFFFF00ULL; | |
1919 break; | |
1920 case Tint16: | |
1921 if (ir.imax & 0x8000) | |
1922 ir.imax |= 0xFFFFFFFFFFFF0000ULL; | |
1923 break; | |
1924 case Tint32: | |
1925 if (ir.imax & 0x80000000) | |
1926 ir.imax |= 0xFFFFFFFF00000000ULL; | |
1927 break; | |
1928 } | |
1929 ir.imin &= type->sizemask(); | |
1930 ir.imax &= type->sizemask(); | |
1931 //printf("CastExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
1932 return ir; | |
1933 } | |
1934 | |
1935 IntRange DivExp::getIntRange() | |
1936 { | |
1937 if (!e1->type->isunsigned() && !e2->type->isunsigned()) | |
1938 return Expression::getIntRange(); | |
1939 | |
1940 IntRange ir; | |
1941 IntRange ir1 = e1->getIntRange(); | |
1942 IntRange ir2 = e2->getIntRange(); | |
1943 | |
1944 ir.imin = ir1.imin / ir2.imax; | |
1945 ir.imax = ir1.imax / ir2.imin; | |
1946 | |
1947 ir.imin &= type->sizemask(); | |
1948 ir.imax &= type->sizemask(); | |
1949 | |
1950 //printf("DivExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
1951 //e1->dump(0); | |
1952 | |
1953 return ir; | |
1954 } | |
1955 | |
1956 IntRange AndExp::getIntRange() | |
1957 { | |
1958 IntRange ir; | |
1959 IntRange ir1 = e1->getIntRange(); | |
1960 IntRange ir2 = e2->getIntRange(); | |
1961 | |
1962 ir.imin = ir1.imin; | |
1963 if (ir2.imin < ir.imin) | |
1964 ir.imin = ir2.imin; | |
1965 | |
1966 ir.imax = ir1.imax; | |
1967 if (ir2.imax > ir.imax) | |
1968 ir.imax = ir2.imax; | |
1969 | |
1970 uinteger_t u; | |
1971 | |
1972 u = getMask(ir1.imax); | |
1973 ir.imin &= u; | |
1974 ir.imax &= u; | |
1975 | |
1976 u = getMask(ir2.imax); | |
1977 ir.imin &= u; | |
1978 ir.imax &= u; | |
1979 | |
1980 ir.imin &= type->sizemask(); | |
1981 ir.imax &= type->sizemask(); | |
1982 | |
1983 //printf("AndExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
1984 //e1->dump(0); | |
1985 | |
1986 return ir; | |
1987 } | |
1988 | |
1989 IntRange OrExp::getIntRange() | |
1990 { | |
1991 IntRange ir; | |
1992 IntRange ir1 = e1->getIntRange(); | |
1993 IntRange ir2 = e2->getIntRange(); | |
1994 | |
1995 ir.imin = ir1.imin; | |
1996 if (ir2.imin < ir.imin) | |
1997 ir.imin = ir2.imin; | |
1998 | |
1999 ir.imax = ir1.imax; | |
2000 if (ir2.imax > ir.imax) | |
2001 ir.imax = ir2.imax; | |
2002 | |
2003 ir.imin &= type->sizemask(); | |
2004 ir.imax &= type->sizemask(); | |
2005 | |
2006 //printf("OrExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
2007 //e1->dump(0); | |
2008 | |
2009 return ir; | |
2010 } | |
2011 | |
2012 IntRange XorExp::getIntRange() | |
2013 { | |
2014 IntRange ir; | |
2015 IntRange ir1 = e1->getIntRange(); | |
2016 IntRange ir2 = e2->getIntRange(); | |
2017 | |
2018 ir.imin = ir1.imin; | |
2019 if (ir2.imin < ir.imin) | |
2020 ir.imin = ir2.imin; | |
2021 | |
2022 ir.imax = ir1.imax; | |
2023 if (ir2.imax > ir.imax) | |
2024 ir.imax = ir2.imax; | |
2025 | |
2026 ir.imin &= type->sizemask(); | |
2027 ir.imax &= type->sizemask(); | |
2028 | |
2029 //printf("XorExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
2030 //e1->dump(0); | |
2031 | |
2032 return ir; | |
2033 } | |
2034 | |
2035 IntRange ShlExp::getIntRange() | |
2036 { | |
2037 IntRange ir; | |
2038 IntRange ir1 = e1->getIntRange(); | |
2039 IntRange ir2 = e2->getIntRange(); | |
2040 | |
2041 ir.imin = getMask(ir1.imin) << ir2.imin; | |
2042 ir.imax = getMask(ir1.imax) << ir2.imax; | |
2043 | |
2044 ir.imin &= type->sizemask(); | |
2045 ir.imax &= type->sizemask(); | |
2046 | |
2047 //printf("ShlExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
2048 //e1->dump(0); | |
2049 | |
2050 return ir; | |
2051 } | |
2052 | |
2053 IntRange ShrExp::getIntRange() | |
2054 { | |
2055 if (!e1->type->isunsigned()) | |
2056 return Expression::getIntRange(); | |
2057 | |
2058 IntRange ir; | |
2059 IntRange ir1 = e1->getIntRange(); | |
2060 IntRange ir2 = e2->getIntRange(); | |
2061 | |
2062 ir.imin = ir1.imin >> ir2.imax; | |
2063 ir.imax = ir1.imax >> ir2.imin; | |
2064 | |
2065 ir.imin &= type->sizemask(); | |
2066 ir.imax &= type->sizemask(); | |
2067 | |
2068 //printf("ShrExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
2069 //e1->dump(0); | |
2070 | |
2071 return ir; | |
2072 } | |
2073 | |
2074 IntRange UshrExp::getIntRange() | |
2075 { | |
2076 IntRange ir; | |
2077 IntRange ir1 = e1->getIntRange(); | |
2078 IntRange ir2 = e2->getIntRange(); | |
2079 | |
2080 ir.imin = ir1.imin >> ir2.imax; | |
2081 ir.imax = ir1.imax >> ir2.imin; | |
2082 | |
2083 ir.imin &= type->sizemask(); | |
2084 ir.imax &= type->sizemask(); | |
2085 | |
2086 //printf("UshrExp: imin = x%llx, imax = x%llx\n", ir.imin, ir.imax); | |
2087 //e1->dump(0); | |
2088 | |
2089 return ir; | |
2090 } | |
2091 | |
2092 IntRange CommaExp::getIntRange() | |
2093 { | |
2094 return e2->getIntRange(); | |
2095 } | |
2096 | |
2097 |