Permalink
Browse files

fix Issue 6652 - 1. Warn modifying non ref variable if -w is specified.

  • Loading branch information...
9rnsr committed Jun 12, 2012
1 parent eb41499 commit 8ea1a0ef35b9cef3047699396487f4d2fe149a39
Showing with 119 additions and 8 deletions.
  1. +4 −0 src/declaration.h
  2. +10 −0 src/expression.c
  3. +3 −0 src/mars.h
  4. +76 −8 src/statement.c
  5. +13 −0 test/fail_compilation/fail6652a.d
  6. +13 −0 test/fail_compilation/fail6652b.d
View
@@ -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
@@ -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
@@ -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
@@ -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;
@@ -0,0 +1,13 @@
+// REQUIRED_ARGS: -w
+
+/******************************************/
+// 6652
+
+void main()
+{
+ size_t[] res;
+ foreach (i; 0..2)
+ {
+ res ~= ++i;
+ }
+}
@@ -0,0 +1,13 @@
+// REQUIRED_ARGS: -w
+
+/******************************************/
+// 6652
+
+void main()
+{
+ size_t[] res;
+ foreach (i, e; [1,2,3,4,5])
+ {
+ res ~= ++i;
+ }
+}

0 comments on commit 8ea1a0e

Please sign in to comment.