Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #1008 from 9rnsr/fix6652_1

fix Issue 6652 - 1. Warn modifying non ref variable if -w is specified.
  • Loading branch information...
commit 38a0a5141a3455395e8b9571a57bf85ed698c6b3 2 parents 0b1ffa8 + 4c1f71e
@WalterBright WalterBright authored
View
4 src/declaration.h
@@ -87,6 +87,10 @@ enum PURE;
#define STCtemp 0x10000000000LL // temporary variable introduced by inlining
// and used only in backend process, so it's rvalue
+#ifdef BUG6652
+#define STCbug6652 0x800000000000LL //
+#endif
+
struct Match
{
int count; // number of matches found
View
10 src/expression.c
@@ -5031,6 +5031,16 @@ Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
//if (type && type->toBasetype()->ty == Tsarray)
//error("cannot change reference to static array '%s'", var->toChars());
+#if (BUG6652 == 1)
+ VarDeclaration *v = var->isVarDeclaration();
+ if (v && (v->storage_class & STCbug6652) && global.params.warnings)
+ warning("Variable modified in foreach body requires ref storage class");
+#elif (BUG6652 == 2)
+ VarDeclaration *v = var->isVarDeclaration();
+ if (v && (v->storage_class & STCbug6652) && !global.params.useDeprecated)
+ error("Variable modified in foreach body requires ref storage class");
+#endif
+
var->checkModify(loc, sc, type);
// See if this expression is a modifiable lvalue (i.e. not const)
View
3  src/mars.h
@@ -91,6 +91,9 @@ void unittests();
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
#define SARRAYVALUE DMDV2 // static arrays are value types
#define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class
+#define BUG6652 1 // Making foreach range statement parameter non-ref in default
+ // 1: Modifying iteratee in body is warned with -w switch
+ // 2: Modifying iteratee in body is error without -d switch
// Set if C++ mangling is done by the front end
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS))
View
84 src/statement.c
@@ -1743,17 +1743,32 @@ Statement *ForeachStatement::semantic(Scope *sc)
Type *argtype = arg->type->semantic(loc, sc);
VarDeclaration *var;
- var = new VarDeclaration(loc, argtype, arg->ident, NULL);
- var->storage_class |= STCforeach;
- var->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR);
- if (var->storage_class & (STCref | STCout))
- var->storage_class |= STCnodtor;
if (dim == 2 && i == 0)
- { key = var;
- //var->storage_class |= STCfinal;
+ {
+#if (BUG6652 == 1 || BUG6652 == 2)
+ var = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), NULL);
+ var->storage_class |= arg->storageClass & (STCin | STCout | STC_TYPECTOR);
+#else
+ if (arg->storageClass & STCref)
+ var = new VarDeclaration(loc, argtype, arg->ident, NULL);
+ else
+ var = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), NULL);
+ var->storage_class |= arg->storageClass & (STCin | STCout | STC_TYPECTOR);
+#endif
+ var->storage_class |= STCforeach;
+ if (var->storage_class & (STCref | STCout))
+ var->storage_class |= STCnodtor;
+
+ key = var;
}
else
{
+ var = new VarDeclaration(loc, argtype, arg->ident, NULL);
+ var->storage_class |= STCforeach;
+ var->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR);
+ if (var->storage_class & (STCref | STCout))
+ var->storage_class |= STCnodtor;
+
value = var;
if (var->storage_class & STCref)
{
@@ -1826,6 +1841,30 @@ Statement *ForeachStatement::semantic(Scope *sc)
value->init = new ExpInitializer(loc, new IndexExp(loc, new VarExp(loc, tmp), new VarExp(loc, key)));
Statement *ds = new ExpStatement(loc, value);
+ if (dim == 2)
+ { Parameter *arg = (*arguments)[0];
+#if (BUG6652 == 1 || BUG6652 == 2)
+ if ((*arguments)[0]->storageClass & STCref)
+ {
+ AliasDeclaration *v = new AliasDeclaration(loc, arg->ident, key);
+ body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
+ }
+ else
+ {
+ ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
+ VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
+ v->storage_class |= STCforeach | STCref | STCbug6652;
+ body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
+ }
+#else
+ if (!(arg->storageClass & STCref))
+ {
+ ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
+ VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
+ body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
+ }
+#endif
+ }
body = new CompoundStatement(loc, ds, body);
s = new ForStatement(loc, forinit, cond, increment, body);
@@ -2452,7 +2491,14 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
*/
ExpInitializer *ie = new ExpInitializer(loc, (op == TOKforeach) ? lwr : upr);
- key = new VarDeclaration(loc, arg->type, arg->ident, ie);
+#if (BUG6652 == 1 || BUG6652 == 2)
+ key = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), ie);
+#else
+ if (arg->storageClass & STCref)
+ key = new VarDeclaration(loc, arg->type, arg->ident, ie);
+ else
+ key = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), ie);
+#endif
Identifier *id = Lexer::uniqueId("__limit");
ie = new ExpInitializer(loc, (op == TOKforeach) ? upr : lwr);
@@ -2499,6 +2545,28 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
//increment = new AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(1));
increment = new PreExp(TOKpreplusplus, loc, new VarExp(loc, key));
+#if (BUG6652 == 1 || BUG6652 == 2)
+ if (arg->storageClass & STCref)
+ {
+ AliasDeclaration *v = new AliasDeclaration(loc, arg->ident, key);
+ body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
+ }
+ else
+ {
+ ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
+ VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
+ v->storage_class |= STCforeach | STCref | STCbug6652;
+ body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
+ }
+#else
+ if (!(arg->storageClass & STCref))
+ {
+ ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
+ VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
+ body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
+ }
+#endif
+
ForStatement *fs = new ForStatement(loc, forinit, cond, increment, body);
s = fs->semantic(sc);
return s;
View
13 test/fail_compilation/fail6652a.d
@@ -0,0 +1,13 @@
+// REQUIRED_ARGS: -w
+
+/******************************************/
+// 6652
+
+void main()
+{
+ size_t[] res;
+ foreach (i; 0..2)
+ {
+ res ~= ++i;
+ }
+}
View
13 test/fail_compilation/fail6652b.d
@@ -0,0 +1,13 @@
+// REQUIRED_ARGS: -w
+
+/******************************************/
+// 6652
+
+void main()
+{
+ size_t[] res;
+ foreach (i, e; [1,2,3,4,5])
+ {
+ res ~= ++i;
+ }
+}
View
8 test/runnable/iasm.d
@@ -3882,7 +3882,7 @@ L1: pop EAX ;
mov p[EBP],EAX ;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4267,7 +4267,7 @@ L1: pop EAX;
mov p[EBP],EAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4561,7 +4561,7 @@ L1: pop EAX;
mov p[EBP],EAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4639,7 +4639,7 @@ L1: pop EAX;
mov p[EBP],EAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
View
20 test/runnable/iasm64.d
@@ -3881,7 +3881,7 @@ L1: pop RAX ;
mov p[RBP],RAX ;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4010,7 +4010,7 @@ L1: pop RAX ;
mov p[RBP],RAX ;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4089,7 +4089,7 @@ L1: pop RAX;
mov p[RBP],RAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4139,7 +4139,7 @@ L1: pop RAX;
mov p[RBP],RAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4339,7 +4339,7 @@ L1: pop RAX;
mov p[RBP],RAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4671,7 +4671,7 @@ L1: pop RAX;
mov p[RBP],RAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4761,7 +4761,7 @@ L1: pop RAX;
mov p[RBP],RAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -4797,7 +4797,7 @@ L1:
mov p[RBP], RAX;
}
- foreach (i, b; data)
+ foreach (ref i, b; data)
{
assert(p[i] == b);
}
@@ -6383,7 +6383,7 @@ L1: pop RAX;
mov p[RBP],RAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
// printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
@@ -6443,7 +6443,7 @@ L1: pop RAX;
mov p[RBP],RAX;
}
- foreach (i,b; data)
+ foreach (ref i, b; data)
{
//printf("data[%d] = 0x%02x, should be 0x%02x\n", i, p[i], b);
assert(p[i] == b);
Please sign in to comment.
Something went wrong with that request. Please try again.