comparison dmd/expression.c @ 1618:a87f1d6ff48e

Merge DMD r303: harmonize --- dmd/expression.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++----- dmd/expression.h | 8 +++++ dmd/template.c | 27 ++++++++++++------- 3 files changed, 95 insertions(+), 18 deletions(-)
author Leandro Lucarella <llucax@gmail.com>
date Wed, 06 Jan 2010 15:18:21 -0300
parents c94049033c20
children c61782a76dff
comparison
equal deleted inserted replaced
1617:6820110de311 1618:a87f1d6ff48e
1185 1185
1186 void Expression::checkEscape() 1186 void Expression::checkEscape()
1187 { 1187 {
1188 } 1188 }
1189 1189
1190 void Expression::checkEscapeRef()
1191 {
1192 }
1193
1190 void Expression::checkScalar() 1194 void Expression::checkScalar()
1191 { 1195 {
1192 if (!type->isscalar()) 1196 if (!type->isscalar())
1193 error("'%s' is not a scalar, it is a %s", toChars(), type->toChars()); 1197 error("'%s' is not a scalar, it is a %s", toChars(), type->toChars());
1194 } 1198 }
1201 1205
1202 Expression *Expression::checkIntegral() 1206 Expression *Expression::checkIntegral()
1203 { 1207 {
1204 if (!type->isintegral()) 1208 if (!type->isintegral())
1205 { error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); 1209 { error("'%s' is not of integral type, it is a %s", toChars(), type->toChars());
1206 return new IntegerExp(0); 1210 return new ErrorExp();
1207 } 1211 }
1208 return this; 1212 return this;
1209 } 1213 }
1210 1214
1211 Expression *Expression::checkArithmetic() 1215 Expression *Expression::checkArithmetic()
1212 { 1216 {
1213 if (!type->isintegral() && !type->isfloating()) 1217 if (!type->isintegral() && !type->isfloating())
1214 { error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars()); 1218 { error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars());
1215 return new IntegerExp(0); 1219 return new ErrorExp();
1216 } 1220 }
1217 return this; 1221 return this;
1218 } 1222 }
1219 1223
1220 void Expression::checkDeprecated(Scope *sc, Dsymbol *s) 1224 void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
3996 void SymOffExp::checkEscape() 4000 void SymOffExp::checkEscape()
3997 { 4001 {
3998 VarDeclaration *v = var->isVarDeclaration(); 4002 VarDeclaration *v = var->isVarDeclaration();
3999 if (v) 4003 if (v)
4000 { 4004 {
4001 if (!v->isDataseg()) 4005 if (!v->isDataseg() && !(v->storage_class & (STCref | STCout)))
4002 error("escaping reference to local variable %s", v->toChars()); 4006 { /* BUG: This should be allowed:
4007 * void foo()
4008 * { int a;
4009 * int* bar() { return &a; }
4010 * }
4011 */
4012 error("escaping reference to local %s", v->toChars());
4013 }
4003 } 4014 }
4004 } 4015 }
4005 4016
4006 void SymOffExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4017 void SymOffExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4007 { 4018 {
4047 type = new TypeDelegate(tf); 4058 type = new TypeDelegate(tf);
4048 type = type->semantic(loc, sc); 4059 type = type->semantic(loc, sc);
4049 } 4060 }
4050 #endif 4061 #endif
4051 } 4062 }
4063
4052 /* Fix for 1161 doesn't work because it causes protection 4064 /* Fix for 1161 doesn't work because it causes protection
4053 * problems when instantiating imported templates passing private 4065 * problems when instantiating imported templates passing private
4054 * variables as alias template parameters. 4066 * variables as alias template parameters.
4055 */ 4067 */
4056 //accessCheck(loc, sc, NULL, var); 4068 //accessCheck(loc, sc, NULL, var);
4082 e = new FuncExp(loc, fd); 4094 e = new FuncExp(loc, fd);
4083 e->type = type; 4095 e->type = type;
4084 return e; 4096 return e;
4085 } 4097 }
4086 #endif 4098 #endif
4099
4087 return this; 4100 return this;
4088 } 4101 }
4089 4102
4090 char *VarExp::toChars() 4103 char *VarExp::toChars()
4091 { 4104 {
4108 if (v->isScope() && !v->noscope) 4121 if (v->isScope() && !v->noscope)
4109 error("escaping reference to scope local %s", v->toChars()); 4122 error("escaping reference to scope local %s", v->toChars());
4110 else if (v->storage_class & STCvariadic) 4123 else if (v->storage_class & STCvariadic)
4111 error("escaping reference to variadic parameter %s", v->toChars()); 4124 error("escaping reference to variadic parameter %s", v->toChars());
4112 } 4125 }
4126 }
4127 }
4128
4129 void VarExp::checkEscapeRef()
4130 {
4131 VarDeclaration *v = var->isVarDeclaration();
4132 if (v)
4133 {
4134 if (!v->isDataseg() && !(v->storage_class & (STCref | STCout)))
4135 error("escaping reference to local variable %s", v->toChars());
4113 } 4136 }
4114 } 4137 }
4115 4138
4116 #if DMDV2 4139 #if DMDV2
4117 int VarExp::isLvalue() 4140 int VarExp::isLvalue()
4739 break; 4762 break;
4740 4763
4741 case TOKinvariant: 4764 case TOKinvariant:
4742 case TOKimmutable: 4765 case TOKimmutable:
4743 if (!targ->isInvariant()) 4766 if (!targ->isInvariant())
4767 goto Lno;
4768 tded = targ;
4769 break;
4770
4771 case TOKshared:
4772 if (!targ->isShared())
4744 goto Lno; 4773 goto Lno;
4745 tded = targ; 4774 tded = targ;
4746 break; 4775 break;
4747 #endif 4776 #endif
4748 4777
4832 dedtypes.data[0] = NULL; 4861 dedtypes.data[0] = NULL;
4833 4862
4834 m = targ->deduceType(NULL, tspec, &parameters, &dedtypes); 4863 m = targ->deduceType(NULL, tspec, &parameters, &dedtypes);
4835 if (m == MATCHnomatch || 4864 if (m == MATCHnomatch ||
4836 (m != MATCHexact && tok == TOKequal)) 4865 (m != MATCHexact && tok == TOKequal))
4866 {
4837 goto Lno; 4867 goto Lno;
4868 }
4838 else 4869 else
4839 { 4870 {
4840 assert(dedtypes.dim == 1); 4871 assert(dedtypes.dim == 1);
4841 tded = (Type *)dedtypes.data[0]; 4872 tded = (Type *)dedtypes.data[0];
4842 if (!tded) 4873 if (!tded)
4852 goto Lyes; 4883 goto Lyes;
4853 } 4884 }
4854 else if (tspec) 4885 else if (tspec)
4855 { 4886 {
4856 /* Evaluate to TRUE if targ matches tspec 4887 /* Evaluate to TRUE if targ matches tspec
4888 * is(targ == tspec)
4889 * is(targ : tspec)
4857 */ 4890 */
4858 tspec = tspec->semantic(loc, sc); 4891 tspec = tspec->semantic(loc, sc);
4859 //printf("targ = %s\n", targ->toChars()); 4892 //printf("targ = %s\n", targ->toChars());
4860 //printf("tspec = %s\n", tspec->toChars()); 4893 //printf("tspec = %s\n", tspec->toChars());
4861 if (tok == TOKcolon) 4894 if (tok == TOKcolon)
5663 * as: 5696 * as:
5664 * .ident(e1) 5697 * .ident(e1)
5665 */ 5698 */
5666 unsigned errors = global.errors; 5699 unsigned errors = global.errors;
5667 global.gag++; 5700 global.gag++;
5701 Type *t1 = e1->type;
5668 e = e1->type->dotExp(sc, e1, ident); 5702 e = e1->type->dotExp(sc, e1, ident);
5669 global.gag--; 5703 global.gag--;
5670 if (errors != global.errors) // if failed to find the property 5704 if (errors != global.errors) // if failed to find the property
5671 { 5705 {
5672 global.errors = errors; 5706 global.errors = errors;
5707 e1->type = t1; // kludge to restore type
5673 e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident); 5708 e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident);
5674 e = new CallExp(loc, e, e1); 5709 e = new CallExp(loc, e, e1);
5675 } 5710 }
5676 e = e->semantic(sc); 5711 e = e->semantic(sc);
5677 return e; 5712 return e;
5861 (t1->ty == Tpointer && !t1->nextOf()->isMutable()) || 5896 (t1->ty == Tpointer && !t1->nextOf()->isMutable()) ||
5862 !var->type->isMutable() || 5897 !var->type->isMutable() ||
5863 !var->type->isAssignable() || 5898 !var->type->isAssignable() ||
5864 var->storage_class & STCmanifest 5899 var->storage_class & STCmanifest
5865 ) 5900 )
5866 error("cannot modify const/invariant %s", toChars()); 5901 error("cannot modify const/immutable expression %s", toChars());
5867 } 5902 }
5868 #endif 5903 #endif
5869 return this; 5904 return this;
5870 } 5905 }
5871 5906
6938 return optimize(WANTvalue); 6973 return optimize(WANTvalue);
6939 } 6974 }
6940 return this; 6975 return this;
6941 } 6976 }
6942 6977
6978 void AddrExp::checkEscape()
6979 {
6980 e1->checkEscapeRef();
6981 }
6982
6943 /************************************************************/ 6983 /************************************************************/
6944 6984
6945 PtrExp::PtrExp(Loc loc, Expression *e) 6985 PtrExp::PtrExp(Loc loc, Expression *e)
6946 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) 6986 : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
6947 { 6987 {
6992 int PtrExp::isLvalue() 7032 int PtrExp::isLvalue()
6993 { 7033 {
6994 return 1; 7034 return 1;
6995 } 7035 }
6996 #endif 7036 #endif
7037
7038 void PtrExp::checkEscapeRef()
7039 {
7040 e1->checkEscape();
7041 }
6997 7042
6998 Expression *PtrExp::toLvalue(Scope *sc, Expression *e) 7043 Expression *PtrExp::toLvalue(Scope *sc, Expression *e)
6999 { 7044 {
7000 #if 0 7045 #if 0
7001 tym = tybasic(e1->ET->Tty); 7046 tym = tybasic(e1->ET->Tty);
7570 } 7615 }
7571 return e; 7616 return e;
7572 } 7617 }
7573 7618
7574 if (t->ty == Tarray) 7619 if (t->ty == Tarray)
7620 {
7575 type = e1->type; 7621 type = e1->type;
7622 }
7576 else 7623 else
7577 type = t->nextOf()->arrayOf(); 7624 type = t->nextOf()->arrayOf();
7578 return e; 7625 return e;
7579 7626
7580 Lerror: 7627 Lerror:
7582 if (t->ty == Tvoid) 7629 if (t->ty == Tvoid)
7583 s = e1->toChars(); 7630 s = e1->toChars();
7584 else 7631 else
7585 s = t->toChars(); 7632 s = t->toChars();
7586 error("%s cannot be sliced with []", s); 7633 error("%s cannot be sliced with []", s);
7587 e = new IntegerExp(0); 7634 e = new ErrorExp();
7588 return e; 7635 return e;
7589 } 7636 }
7590 7637
7591 void SliceExp::checkEscape() 7638 void SliceExp::checkEscape()
7592 { 7639 {
7593 e1->checkEscape(); 7640 e1->checkEscape();
7641 }
7642
7643 void SliceExp::checkEscapeRef()
7644 {
7645 e1->checkEscapeRef();
7594 } 7646 }
7595 7647
7596 #if DMDV2 7648 #if DMDV2
7597 int SliceExp::isLvalue() 7649 int SliceExp::isLvalue()
7598 { 7650 {
7636 : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1) 7688 : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1)
7637 { 7689 {
7638 } 7690 }
7639 7691
7640 Expression *ArrayLengthExp::semantic(Scope *sc) 7692 Expression *ArrayLengthExp::semantic(Scope *sc)
7641 { Expression *e; 7693 {
7642
7643 #if LOGSEMANTIC 7694 #if LOGSEMANTIC
7644 printf("ArrayLengthExp::semantic('%s')\n", toChars()); 7695 printf("ArrayLengthExp::semantic('%s')\n", toChars());
7645 #endif 7696 #endif
7646 if (!type) 7697 if (!type)
7647 { 7698 {
7788 } 7839 }
7789 7840
7790 void CommaExp::checkEscape() 7841 void CommaExp::checkEscape()
7791 { 7842 {
7792 e2->checkEscape(); 7843 e2->checkEscape();
7844 }
7845
7846 void CommaExp::checkEscapeRef()
7847 {
7848 e2->checkEscapeRef();
7793 } 7849 }
7794 7850
7795 #if DMDV2 7851 #if DMDV2
7796 int CommaExp::isLvalue() 7852 int CommaExp::isLvalue()
7797 { 7853 {
9969 { 10025 {
9970 e1->checkEscape(); 10026 e1->checkEscape();
9971 e2->checkEscape(); 10027 e2->checkEscape();
9972 } 10028 }
9973 10029
10030 void CondExp::checkEscapeRef()
10031 {
10032 e1->checkEscapeRef();
10033 e2->checkEscapeRef();
10034 }
10035
9974 10036
9975 Expression *CondExp::checkToBoolean() 10037 Expression *CondExp::checkToBoolean()
9976 { 10038 {
9977 e1 = e1->checkToBoolean(); 10039 e1 = e1->checkToBoolean();
9978 e2 = e2->checkToBoolean(); 10040 e2 = e2->checkToBoolean();