void Visit(Exp *lval) { // match any access which uses a GC thing type as an rvalue, // including those where the thing is not actually dereferenced. // we are watching not just for direct accesses to the thing, // but to places where it is copied to arguments, a return value, // a variable or heap location. any use of an GC thing pointer // not protected against GC is considered to be an error, and adding // these asserts aggressively lets us discharge reports easier and // generate reports close to the site of the actual problem. if (!lval->IsDrf()) return; ExpDrf *nlval = lval->AsDrf(); Type *type = nlval->GetType(); if (type && type->IsCSU() && TypeIsGCThing(type->AsCSU())) { AssertInfo info; info.kind = ASK_GCSafe; info.cls = ASC_Check; info.point = point; Exp *target = nlval->GetTarget(); if (target->IsFld() && BlockSummary::FieldIsGCSafe(target->AsFld()->GetField())) { info.bit = Bit::MakeConstant(true); } else { Exp *gcsafe = Exp::MakeGCSafe(nlval->GetTarget(), false); info.bit = Bit::MakeVar(gcsafe); } asserts.PushBack(info); } }