Beispiel #1
0
void Z3AssumptionSolverImpl::postCheck(const Query&) {
    errs() << "==> Number of assumptions: " << guards_.size() << '\n';
    if (guards_.size() > AssumptionResetThreshold) {
        reset();
        guards_.clear();
    }
}
Beispiel #2
0
void CAtom::remove_guard( CAtom** ptr )
{
    if( !*ptr )
        return;
    GuardMap* map = guard_map();
    if( !map || map->empty() )
        return;
    bool more = false;  // if the CAtom has more pointers attached to it.
    GuardMap::iterator it = map->find( *ptr );
    const GuardMap::iterator end = map->end();
    for( ; it != end && it->first == *ptr; ++it )
    {
        if( it->second == ptr )
        {
            if( !more )
            {
                ++it;
                more = ( it != end ) && ( it->first == *ptr );
                --it;
            }
            map->erase( it );
            break;
        }
        more = true;
    }
    if( !more )
        ( *ptr )->set_has_guards( false );
}
Beispiel #3
0
void CAtom::add_guard( CAtom** ptr )
{
    if( !*ptr )
        return;
    GuardMap* map = guard_map();
    if( !map )
    {
        *ptr = 0;
        return;
    }
    map->insert( GuardMap::value_type( *ptr, ptr ) );
    ( *ptr )->set_has_guards( true );
}
Beispiel #4
0
z3::expr Z3AssumptionSolverImpl::getAssumption(ref<Expr> assertion) {
    GuardMap::iterator it = guards_.find(assertion);
    if (it != guards_.end()) {
        return it->second;
    }

    char name[16];
    snprintf(name, 16, "g%lu", guard_counter_++);
    z3::expr result = context_.bool_const(name);
    guards_.insert(std::make_pair(assertion, result));

    solver_.add(z3::to_expr(context_,
            Z3_mk_implies(context_, result, builder_->construct(assertion))));

    return result;
}
Beispiel #5
0
void CAtom::change_guard( CAtom** ptr, CAtom* o )
{
    GuardMap* map = guard_map();
    if( !map )
    {
        *ptr = 0;
        return;
    }
    if( o )
    {
        map->insert( GuardMap::value_type( o, ptr ) );
        o->set_has_guards( true );
    }
    CAtom::remove_guard( ptr );
    *ptr = o;
}
Beispiel #6
0
static void rewriteFile(const std::string& output_path, std::deque<std::string>& file_lines,
                        const GuardMap& guard_map) {
  for (auto it = guard_map.rbegin(); it != guard_map.rend(); ++it) {
    const Location& loc = it->first;
    const DeclarationAvailability& avail = it->second;

    std::string condition = generateGuardCondition(avail);
    if (condition.empty()) {
      continue;
    }

    std::string prologue = "\n#if "s + condition + "\n";
    std::string epilogue = "\n#endif /* " + condition + " */\n";

    file_lines[loc.end.line - 1].insert(loc.end.column, epilogue);
    file_lines[loc.start.line - 1].insert(loc.start.column - 1, prologue);
  }

  printf("Preprocessing %s...\n", output_path.c_str());
  writeFileLines(output_path, file_lines);
}
Beispiel #7
0
void CAtom::clear_guards( CAtom* o )
{
    GuardMap* map = 0;
    try
    {
        map = guard_map();
    }
    catch( std::bad_alloc& )
    {
        // do nothing in case of OOM - code below is safe
    }
    if( !map || map->empty() )
        return;
    GuardMap::iterator it = map->find( o );
    GuardMap::iterator first = it;
    const GuardMap::iterator end = map->end();
    for( ; it != end && it->first == o; ++it )
        *it->second = 0;
    map->erase( first, it );
    o->set_has_guards( false );
}
Beispiel #8
0
// Merge adjacent blocks with identical guards.
static void mergeGuards(std::deque<std::string>& file_lines, GuardMap& guard_map) {
  if (guard_map.size() < 2) {
    return;
  }

  auto current = guard_map.begin();
  auto next = current;
  ++next;

  while (next != guard_map.end()) {
    if (current->second != next->second) {
      ++current;
      ++next;
      continue;
    }

    // Scan from the end of current to the beginning of next.
    bool in_block_comment = false;
    bool valid = true;

    FileLocation current_location = current->first.end;
    FileLocation end_location = next->first.start;

    auto nextLine = [&current_location]() {
      ++current_location.line;
      current_location.column = 1;
    };

    auto nextCol = [&file_lines, &current_location, &nextLine]() {
      if (current_location.column == file_lines[current_location.column - 1].length()) {
        nextLine();
      } else {
        ++current_location.column;
      }
    };

    // The end location will point to the semicolon, which we don't want to read, so skip it.
    nextCol();

    while (current_location < end_location) {
      const std::string& line = file_lines[current_location.line - 1];
      size_t line_index = current_location.column - 1;

      if (in_block_comment) {
        size_t pos = line.find("*/", line_index);
        if (pos == std::string::npos) {
          D("Didn't find block comment terminator, skipping line\n");
          nextLine();
          continue;
        } else {
          D("Found block comment terminator\n");
          in_block_comment = false;
          current_location.column = pos + 2;
          nextCol();
          continue;
        }
      } else {
        size_t pos = line.find_first_not_of(" \t", line_index);
        if (pos == std::string::npos) {
          nextLine();
          continue;
        }

        current_location.column = pos + 1;
        if (line[pos] != '/') {
          D("Trailing character '%c' is not a slash: %s\n", line[pos], line.substr(pos).c_str());
          valid = false;
          break;
        }

        nextCol();
        if (line.length() <= pos + 1) {
          // Trailing slash at the end of a line?
          D("Trailing slash at end of line\n");
          valid = false;
          break;
        }

        if (line[pos + 1] == '/') {
          // C++ style comment
          nextLine();
        } else if (line[pos + 1] == '*') {
          // Block comment
          nextCol();
          in_block_comment = true;
          D("In a block comment\n");
        } else {
          // Garbage?
          D("Unexpected output after /: %s\n", line.substr(pos).c_str());
          valid = false;
          break;
        }
      }
    }

    if (!valid) {
      D("Not merging blocks %s and %s\n", to_string(current->first).c_str(),
        to_string(next->first).c_str());
      ++current;
      ++next;
      continue;
    }

    D("Merging blocks %s and %s\n", to_string(current->first).c_str(),
      to_string(next->first).c_str());

    Location merged = current->first;
    merged.end = next->first.end;

    DeclarationAvailability avail = current->second;

    guard_map.erase(current);
    guard_map.erase(next);
    bool dummy;
    std::tie(current, dummy) = guard_map.insert(std::make_pair(merged, avail));
    next = current;
    ++next;
  }
}