Example #1
0
  void LookupInsert(Cache_BlockCFG *cache, BlockId *id)
  {
    Assert(id->Kind() == B_Function || id->Kind() == B_Loop);
    String *function = id->Function();
    const char *function_name = function->Value();

    if (!DoLookupTransaction(BODY_DATABASE, function_name, &scratch_buf)) {
      id->IncRef(cache);
      cache->Insert(id, NULL);
      return;
    }

    Buffer read_buf(scratch_buf.base, scratch_buf.pos - scratch_buf.base);
    Vector<BlockCFG*> cfg_list;
    BlockCFG::ReadList(&read_buf, &cfg_list);

    scratch_buf.Reset();

    for (size_t ind = 0; ind < cfg_list.Size(); ind++) {
      BlockCFG *cfg = cfg_list[ind];
      BlockId *id = cfg->GetId();

      id->IncRef(cache);
      cfg->MoveRef(NULL, cache);
      cache->Insert(id, cfg);
    }
  }
Example #2
0
void BlockCFGCacheAddListWithRefs(const Vector<BlockCFG*> &cfgs)
{
  for (size_t ind = 0; ind < cfgs.Size(); ind++) {
    BlockCFG *cfg = cfgs[ind];
    BlockId *id = cfg->GetId();

    id->IncRef(&BlockCFGCache);
    cfg->IncRef(&BlockCFGCache);
    BlockCFGCache.Insert(id, cfg);
  }
}
Example #3
0
  void Visit(Exp *exp)
  {
    if (ExpFld *nexp = exp->IfFld()) {
      // pick up any type invariants from the host type.
      String *csu_name = nexp->GetField()->GetCSUType()->GetCSUName();
      Vector<BlockCFG*> *annot_list = CompAnnotCache.Lookup(csu_name);

      for (size_t ind = 0; annot_list && ind < annot_list->Size(); ind++) {
        BlockCFG *annot_cfg = annot_list->At(ind);
        Assert(annot_cfg->GetAnnotationKind() == AK_Invariant ||
               annot_cfg->GetAnnotationKind() == AK_InvariantAssume);
        BlockId *id = annot_cfg->GetId();

        Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg);
        if (!bit) continue;

        // get the *this expression. we'll replace this with the actual CSU
        // lvalue to get the assumed bit.
        id->IncRef();
        Variable *this_var = Variable::Make(id, VK_This, NULL, 0, NULL);
        Exp *this_exp = Exp::MakeVar(this_var);
        Exp *this_drf = Exp::MakeDrf(this_exp);
        Exp *target = nexp->GetTarget();

        GuardExpVector lval_res;
        if (mcfg) {
          mcfg->TranslateExp(TRK_Point, point, target, &lval_res);
        }
        else {
          target->IncRef();
          lval_res.PushBack(GuardExp(target, Bit::MakeConstant(true)));
        }

        for (size_t lind = 0; lind < lval_res.Size(); lind++) {
          // ignore the guard component of the result here. this means that
          // accessing a field of a value means related invariants hold for
          // the value along all paths. which is normally right, except when
          // the value is the result of a cast, and could have a different type
          // along other paths. TODO: sort this out.
          const GuardExp &gs = lval_res[lind];
          Bit *new_bit = BitReplaceExp(bit, this_drf, gs.exp);

          new_bit->MoveRef(NULL, assume_list);
          annot_cfg->IncRef(assume_list);

          AssumeInfo info;
          info.annot = annot_cfg;
          info.point = 0;
          info.bit = new_bit;
          assume_list->PushBack(info);
        }

        this_drf->DecRef();
      }

      CompAnnotCache.Release(csu_name);
    }

    if (ExpVar *nexp = exp->IfVar()) {
      if (nexp->GetVariable()->Kind() == VK_Glob) {
        String *var_name = nexp->GetVariable()->GetName();
        Vector<BlockCFG*> *annot_list = InitAnnotCache.Lookup(var_name);

        for (size_t ind = 0; annot_list && ind < annot_list->Size(); ind++) {
          BlockCFG *annot_cfg = annot_list->At(ind);
          Assert(annot_cfg->GetAnnotationKind() == AK_Invariant ||
                 annot_cfg->GetAnnotationKind() == AK_InvariantAssume);

          Bit *bit = BlockMemory::GetAnnotationBit(annot_cfg);
          if (!bit) continue;

          bit->IncRef(assume_list);
          annot_cfg->IncRef(assume_list);

          AssumeInfo info;
          info.annot = annot_cfg;
          info.point = 0;
          info.bit = bit;
          assume_list->PushBack(info);
        }

        InitAnnotCache.Release(var_name);
      }
    }
  }