@@ -1221,6 +1221,11 @@ void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
1221
1221
}
1222
1222
1223
1223
#if DMDV2
1224
+ /*********************************************
1225
+ * Calling function f.
1226
+ * Check the purity, i.e. if we're in a pure function
1227
+ * we can only call other pure functions.
1228
+ */
1224
1229
void Expression ::checkPurity (Scope * sc , FuncDeclaration * f )
1225
1230
{
1226
1231
#if 1
@@ -1256,12 +1261,14 @@ void Expression::checkPurity(Scope *sc, FuncDeclaration *f)
1256
1261
}
1257
1262
// If the caller has a pure parent, then either the called func must be pure,
1258
1263
// OR, they must have the same pure parent.
1259
- if (outerfunc -> isPure () && !sc -> intypeof &&
1264
+ if (/*outerfunc->isPure() &&*/ // comment out because we deduce purity now
1265
+ !sc -> intypeof &&
1260
1266
!(sc -> flags & SCOPEdebug ) &&
1261
1267
!(f -> isPure () || (calledparent == outerfunc )))
1262
1268
{
1263
- error ("pure function '%s' cannot call impure function '%s'" ,
1264
- outerfunc -> toChars (), f -> toChars ());
1269
+ if (outerfunc -> setImpure ())
1270
+ error ("pure function '%s' cannot call impure function '%s'" ,
1271
+ outerfunc -> toChars (), f -> toChars ());
1265
1272
}
1266
1273
}
1267
1274
#else
@@ -4405,21 +4412,83 @@ Expression *VarExp::semantic(Scope *sc)
4405
4412
VarDeclaration * v = var -> isVarDeclaration ();
4406
4413
if (v )
4407
4414
{
4408
- #if 0
4409
- if ((v -> isConst () || v -> isImmutable ()) &&
4410
- type -> toBasetype ()-> ty != Tsarray && v -> init )
4415
+ v -> checkNestedReference (sc , loc );
4416
+ #if DMDV2
4417
+ #if 1
4418
+ /* Look for purity and safety violations when accessing variable v
4419
+ * from current function.
4420
+ */
4421
+ if (sc -> func &&
4422
+ !sc -> intypeof && // allow violations inside typeof(expression)
4423
+ !(sc -> flags & SCOPEdebug ) && // allow violations inside debug conditionals
4424
+ v -> ident != Id ::ctfe && // magic variable never violates pure and safe
4425
+ !v -> isImmutable () && // always safe and pure to access immutables...
4426
+ !(v -> storage_class & STCmanifest ) // ...or manifest constants
4427
+ )
4411
4428
{
4412
- ExpInitializer * ei = v -> init -> isExpInitializer ();
4413
- if (ei )
4429
+ if (v -> isDataseg ())
4430
+ {
4431
+ /* Accessing global mutable state.
4432
+ * Therefore, this function and all its immediately enclosing
4433
+ * functions must be pure.
4434
+ */
4435
+ bool msg = FALSE;
4436
+ for (Dsymbol * s = sc -> func ; s ; s = s -> toParent2 ())
4437
+ {
4438
+ FuncDeclaration * ff = s -> isFuncDeclaration ();
4439
+ if (!ff )
4440
+ break ;
4441
+ if (ff -> setImpure () && !msg )
4442
+ { error ("pure function '%s' cannot access mutable static data '%s'" ,
4443
+ sc -> func -> toChars (), v -> toChars ());
4444
+ printf ("test1\n" );
4445
+ msg = TRUE; // only need the innermost message
4446
+ }
4447
+ }
4448
+ }
4449
+ else
4414
4450
{
4415
- //ei->exp->implicitCastTo(sc, type)->print();
4416
- return ei -> exp -> implicitCastTo (sc , type );
4451
+ /* Given:
4452
+ * void f()
4453
+ * { int fx;
4454
+ * pure void g()
4455
+ * { int gx;
4456
+ * void h()
4457
+ * { int hx;
4458
+ * void i() { }
4459
+ * }
4460
+ * }
4461
+ * }
4462
+ * i() can modify hx and gx but not fx
4463
+ */
4464
+
4465
+ /* Back up until we find the parent function of v,
4466
+ * requiring each function in between to be impure.
4467
+ */
4468
+ Dsymbol * vparent = v -> toParent2 ();
4469
+ for (Dsymbol * s = sc -> func ; s ; s = s -> toParent2 ())
4470
+ {
4471
+ if (s == vparent )
4472
+ break ;
4473
+ FuncDeclaration * ff = s -> isFuncDeclaration ();
4474
+ if (!ff )
4475
+ break ;
4476
+ if (ff -> setImpure ())
4477
+ { error ("pure nested function '%s' cannot access mutable data '%s'" ,
4478
+ ff -> toChars (), v -> toChars ());
4479
+ printf ("test2\n" );
4480
+ break ;
4481
+ }
4482
+ }
4417
4483
}
4484
+
4485
+ /* Do not allow safe functions to access __gshared data
4486
+ */
4487
+ if (sc -> func -> isSafe () && v -> storage_class & STCgshared )
4488
+ error ("safe function '%s' cannot access __gshared data '%s'" ,
4489
+ sc -> func -> toChars (), v -> toChars ());
4418
4490
}
4419
- #endif
4420
- v -> checkNestedReference (sc , loc );
4421
- #if DMDV2
4422
- #if 1
4491
+ #else
4423
4492
if (sc -> func && !sc -> intypeof && !(sc -> flags & SCOPEdebug ))
4424
4493
{
4425
4494
/* Given:
@@ -4486,12 +4555,6 @@ Expression *VarExp::semantic(Scope *sc)
4486
4555
error ("safe function '%s' cannot access __gshared data '%s'" ,
4487
4556
sc -> func -> toChars (), v -> toChars ());
4488
4557
}
4489
- #else
4490
- if (sc -> func && sc -> func -> isPure () && !sc -> intypeof )
4491
- {
4492
- if (v -> isDataseg () && !v -> isImmutable ())
4493
- error ("pure function '%s' cannot access mutable static data '%s'" , sc -> func -> toChars (), v -> toChars ());
4494
- }
4495
4558
#endif
4496
4559
#endif
4497
4560
}
@@ -7365,9 +7428,10 @@ Expression *CallExp::semantic(Scope *sc)
7365
7428
{ TypeDelegate * td = (TypeDelegate * )t1 ;
7366
7429
assert (td -> next -> ty == Tfunction );
7367
7430
tf = (TypeFunction * )(td -> next );
7368
- if (sc -> func && sc -> func -> isPure () && !tf -> purity && !(sc -> flags & SCOPEdebug ))
7431
+ if (sc -> func && !tf -> purity && !(sc -> flags & SCOPEdebug ))
7369
7432
{
7370
- error ("pure function '%s' cannot call impure delegate '%s'" , sc -> func -> toChars (), e1 -> toChars ());
7433
+ if (sc -> func -> setImpure ())
7434
+ error ("pure function '%s' cannot call impure delegate '%s'" , sc -> func -> toChars (), e1 -> toChars ());
7371
7435
}
7372
7436
if (sc -> func && sc -> func -> isSafe () && tf -> trust <= TRUSTsystem )
7373
7437
{
@@ -7379,9 +7443,10 @@ Expression *CallExp::semantic(Scope *sc)
7379
7443
{
7380
7444
Expression * e = new PtrExp (loc , e1 );
7381
7445
t1 = ((TypePointer * )t1 )-> next ;
7382
- if (sc -> func && sc -> func -> isPure () && !((TypeFunction * )t1 )-> purity && !(sc -> flags & SCOPEdebug ))
7446
+ if (sc -> func && !((TypeFunction * )t1 )-> purity && !(sc -> flags & SCOPEdebug ))
7383
7447
{
7384
- error ("pure function '%s' cannot call impure function pointer '%s'" , sc -> func -> toChars (), e1 -> toChars ());
7448
+ if (sc -> func -> setImpure ())
7449
+ error ("pure function '%s' cannot call impure function pointer '%s'" , sc -> func -> toChars (), e1 -> toChars ());
7385
7450
}
7386
7451
if (sc -> func && sc -> func -> isSafe () && !((TypeFunction * )t1 )-> trust <= TRUSTsystem )
7387
7452
{
@@ -9332,6 +9397,8 @@ Expression *AssignExp::semantic(Scope *sc)
9332
9397
VarDeclaration * v = new VarDeclaration (loc , aaValueType ,
9333
9398
id , new VoidInitializer (NULL ));
9334
9399
v -> storage_class |= STCctfe ;
9400
+ v -> semantic (sc );
9401
+ v -> parent = sc -> parent ;
9335
9402
9336
9403
Expression * de = new DeclarationExp (loc , v );
9337
9404
VarExp * ve = new VarExp (loc , v );
0 commit comments