//===- FaultInjector.cpp - Insert faults into programs -----------------------//
// 
//                          The SAFECode Compiler 
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file implements a pass that transforms the program to add the following
// kind of faults:
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "FaultInjector"

#include "dsa/DSGraph.h"

#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/ADT/VectorExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"

#include "safecode/FaultInjector.h"
#include "SCUtils.h"

#include <cstdlib>
#include <limits.h>
#include <iostream>
#include <vector>

using namespace llvm;

char llvm::FaultInjector::ID = 0;

// Register the pass and tell a bad joke all at the same time.
// I know, I know; it's my own darn fault...
RegisterPass<FaultInjector> MyFault ("faultinjector", "Insert Faults");

///////////////////////////////////////////////////////////////////////////
// Command line options
///////////////////////////////////////////////////////////////////////////
cl::opt<bool>
InjectEasyDPFaults ("inject-easydp",
                    cl::init(false),
                    cl::desc("Inject Trivial Dangling Pointer Dereferences"));

cl::opt<bool>
InjectHardDPFaults ("inject-harddp",
                    cl::init(false),
                    cl::desc("Inject Non-Trivial Dangling Pointer Dereferences"));

cl::opt<bool>
InjectRealDPFaults ("inject-realdp",
                    cl::init(false),
                    cl::desc("Inject Only Dangling Pointer Dereferences"));

cl::opt<bool>
InjectBadSizes ("inject-badsize",
                cl::init(false),
                cl::desc("Inject Array Allocations of the Wrong Size"));

cl::opt<bool>
InjectBadIndices ("inject-badindices",
                  cl::init(false),
                  cl::desc("Inject Bad Indices in GEPs"));

cl::opt<bool>
InjectUninitUses ("inject-uninituses",
                  cl::init(false),
                  cl::desc("Inject Uses of Uninitialized Pointers"));

cl::opt<int>
Seed ("seed", cl::init(1),
      cl::desc("Seed Value for Random Number Generator"));

cl::opt<int>
Frequency ("freq", cl::init(100),
           cl::desc("Probability of Inserting a Fault"));

cl::list<std::string>
Funcs ("funcs",
       cl::value_desc("list"),
       cl::CommaSeparated,
       cl::desc ("List of functions to process"));

//
// Basic LLVM Types
//
static const Type * Int32Type = 0;

namespace {
  ///////////////////////////////////////////////////////////////////////////
  // Pass Statistics
  ///////////////////////////////////////////////////////////////////////////
  STATISTIC (DPFaults,       "Number of Dangling Pointer Faults Injected");
  STATISTIC (BadSizes,       "Number of Bad Allocation Size Faults Injected");
  STATISTIC (BadIndices,     "Number of Bad Indexing Faults Injected");
  STATISTIC (UsesBeforeInit, "Number of Injected Uses Before Initialization");
  STATISTIC (NumFuncs,       "Number of Functions Examined");

  // Threshold for determining whether a fault will be inserted
  int threshold;
}

///////////////////////////////////////////////////////////////////////////
// Static Functions
///////////////////////////////////////////////////////////////////////////

//
// Function: doFault()
//
// Description:
//  Uses random number generation to determine if a fault should be inserted.
//
// Return Value:
//  true  - A fault should be inserted.
//  false - A fault should not be inserted.
//
// Pre-conditions:
//  1) The random number generator routines should have been seeded.
//  2) The threshold variable should have been calculated.
//
static inline bool
doFault () {
  if (rand() < threshold)
    return true;
  else
    return false;
}

//
// Function: typeContainsPointer()
//
// Description:
//  This function determines whether the specified LLVM type is either a
//  pointer type or a derived type that contains a pointer.
//
// Inputs:
//  Ty      - The type created by the allocation.
//  Context - The LLVM Context in which to add integers.
//
// Outputs:
//  Indices - A vector of indices that can be used to create a GEP to the
//            pointer field of the type.  This vector is *always* modified by
//            this function, even if no pointer type is found.
//
// Return value:
//  true  - The type contains a pointer.
//  false - This function could not prove that this type contains a pointer.
//
static inline bool
typeContainsPointer (const Type * Ty, std::vector<Value *> & Indices,
                     LLVMContext * Context) {
  //
  // If this is a pointer type, stop the recursion.  We've found our pointer.
  //
  if (isa<PointerType>(Ty)) {
    return true;
  }

  //
  // If this is an array type or vector type, search within the type of
  // element.
  //
  if (const ArrayType * AT = dyn_cast<ArrayType>(Ty)) {
    Indices.push_back (ConstantInt::get (Int32Type, 0));
    return typeContainsPointer (AT->getElementType(), Indices, Context);
  }

  if (const VectorType * VT = dyn_cast<VectorType>(Ty)) {
    Indices.push_back (ConstantInt::get (Int32Type, 0));
    return typeContainsPointer (VT->getElementType(), Indices, Context);
  }

  //
  // If this is a structure type, search for a pointer within each element type
  // of the structure.
  //
  if (const StructType * ST = dyn_cast<StructType>(Ty)) {
    for (unsigned index = 0; index < ST->getNumElements(); ++index) {
      Indices.push_back (ConstantInt::get (Int32Type, index));
      if (typeContainsPointer (ST->getElementType(index), Indices, Context)) {
        return true;
      } else {
        Indices.pop_back ();
      }
    }
  }

  //
  // We don't know what this is.  Say it doesn't contain a pointer.
  //
  return false;
}

//
// Function: printSourceInfo()
//
// Description:
//  Print source file and line number information about the instruction to
//  standard output.
//
static void
printSourceInfo (std::string errorType, Instruction * I) {
  //
  // Print out where the fault will be inserted in the source code.
  // If we can't find the source line information, use a dummy line number and
  // the function name by default.
  //
  const DbgStopPointInst * StopPt = findStopPoint (I);
  std::string fname = I->getParent()->getParent()->getNameStr();
  std::string funcname = fname;
  uint64_t lineno = 0;
  if (StopPt) {
    Value * LineNumber = StopPt->getLineValue();
    Value * SourceFile = StopPt->getFileName();

    if (ConstantExpr * SrcGEP = dyn_cast<ConstantExpr>(SourceFile)) {
      if (GlobalVariable * GV = dyn_cast<GlobalVariable>(SrcGEP->getOperand(0))) {
        if (ConstantArray * CA = dyn_cast<ConstantArray>(GV->getInitializer())) {
          fname = CA->getAsString();
        }
      }
    } else {
      std::cerr << *SourceFile << std::endl;
    }
    if (ConstantInt * CI = dyn_cast<ConstantInt>(LineNumber)) {
      lineno = CI->getValue().getZExtValue();
    }
  }

  std::cout << "Inject: " << errorType << ": "
            << funcname   << ": " << fname << ": " << lineno << "\n";
  return;
}

//
// Function: getFunctionList()
//
// Description:
//  Determine which functions should be processed.
//
void
getFunctionList (Module & M, std::vector<Function *> & List) {
  //
  // If no functions were listed on the command line, then process *all*
  // functions within the module.  Otherwise, create a list of only those given
  // on the command line.
  //
  if (Funcs.size() == 0) {
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      List.push_back (F);
    }
  } else {
    for (unsigned index = 0; index < Funcs.size(); ++index) {
      if (Function * F = M.getFunction(Funcs[index]))
        List.push_back (F);
    }
  }

  //
  // Update the statistics on how many functions we'll examine.
  //
  NumFuncs += List.size();
  return;
}

//
// Method: insertEasyDanglingPointers()
//
// Description:
//  Insert dangling pointer dereferences into the code.  This is done by
//  finding load/store instructions and inserting a free on the pointer to
//  ensure the dereference (and all future dereferences) are illegal.
//
// Return value:
//  true  - The module was modified.
//  false - The module was left unmodified.
//
// Notes:
//  This code utilizes DSA to ensure that the pointer can pointer to heap
//  memory (although the pointer is allowed to alias global and stack memory).
//
bool
FaultInjector::insertEasyDanglingPointers (Function & F) {
  //
  // Ensure that we can get analysis information for this function.
  //
  if (!(TDPass->hasDSGraph(F)))
    return false;

  //
  // Scan through each instruction of the function looking for load and store
  // instructions.  Free the pointer right before.
  //
  DSGraph * DSG = TDPass->getDSGraph(F);
  for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
    BasicBlock & BB = *fI;
    for (BasicBlock::iterator bI = BB.begin(), bE = BB.end(); bI != bE; ++bI) {
      Instruction * I = bI;

      //
      // Look to see if there is an instruction that uses a pointer.  If so,
      // then free the pointer before the use.
      //
      Value * Pointer = 0;
      if (LoadInst * LI = dyn_cast<LoadInst>(I))
        Pointer = LI->getPointerOperand();
      else if (StoreInst * SI = dyn_cast<StoreInst>(I))
        Pointer = SI->getPointerOperand();
      else
        continue;

      //
      // Check to ensure that this pointer aliases with the heap.  If so, go
      // ahead and add the free.  Note that we may introduce an invalid free,
      // but we're injecting errors, so I think that's okay.
      //
      DSNode * Node = DSG->getNodeForValue(Pointer).getNode();
      if (Node && (Node->isHeapNode())) {
        //
        // Avoid free'ing pointers that are trivially stack objects or global
        // variables.
        //
        if (isa<GlobalValue>(Pointer->stripPointerCasts()) ||
            isa<AllocaInst>(Pointer->stripPointerCasts())) {
          continue;
        }

        // Skip if we should not insert a fault.
        if (!doFault()) continue;

        //
        // Print information about where the fault is being inserted.
        //
        printSourceInfo ("Easy dangling pointer", I);

        new FreeInst (Pointer, I);
        ++DPFaults;
      }
    }
  }

  return (DPFaults > 0);
}

//
// Method: insertHardDanglingPointers()
//
// Description:
//  Insert dangling pointer dereferences into the code.  This is done by
//  finding instructions that store pointers to memory and free'ing those
//  pointers before the store.  Subsequent loads and uses of the pointer will
//  cause a dangling pointer dereference.
//
// Return value:
//  true  - The module was modified.
//  false - The module was left unmodified.
//
// Notes:
//  This code utilizes DSA to ensure that the pointer can point to heap
//  memory (although the pointer is allowed to alias global and stack memory).
//
bool
FaultInjector::insertHardDanglingPointers (Function & F) {
  //
  // Ensure that we can get analysis information for this function.
  //
  if (!(TDPass->hasDSGraph(F)))
    return false;

  //
  // Scan through each instruction of the function looking for store
  // instructions that store a pointer to memory.  Free the pointer right
  // before the store instruction.
  //
  DSGraph * DSG = TDPass->getDSGraph(F);
  for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
    BasicBlock & BB = *fI;
    for (BasicBlock::iterator bI = BB.begin(), bE = BB.end(); bI != bE; ++bI) {
      Instruction * I = bI;

      //
      // Look to see if there is an instruction that stores a pointer to
      // memory.  If so, then free the pointer before the store.
      //
      if (StoreInst * SI = dyn_cast<StoreInst>(I)) {
        if (isa<PointerType>(SI->getOperand(0)->getType())) {
          Value * Pointer = SI->getOperand(0);

          //
          // Check to ensure that the pointer aliases with the heap.  If so, go
          // ahead and add the free.  Note that we may introduce an invalid
          // free, but we're injecting errors, so I think that's okay.
          //
          DSNode * Node = DSG->getNodeForValue(Pointer).getNode();
          if (Node && (Node->isHeapNode())) {
            // Skip if we should not insert a fault.
            if (!doFault()) continue;

            //
            // Print information about where the fault is being inserted.
            //
            printSourceInfo ("Hard dangling pointer", I);

            new FreeInst (Pointer, I);
            ++DPFaults;
          }
        }
      }
    }
  }

  return (DPFaults > 0);
}

//
// Method: insertRealDanglingPointers()
//
// Description:
//  Insert dangling pointer dereferences into the code.  This is done by
//  finding heap allocation instructions and adding code to free the allocated
//  pointer.  These errors will be more trivial than the hard dangling pointer
//  injection method but will also be more accurate (i.e., it will only free
//  heap objects and only cause dangling pointer errors; it will *not* insert
//  other invalid free errors).
//
// Return value:
//  true  - The module was modified.
//  false - The module was left unmodified.
//
bool
FaultInjector::insertRealDanglingPointers (Function & F) {
  //
  // Scan through each instruction of the function looking for malloc
  // instructions.  Free the pointer immediently after the allocation.
  //
  std::vector<MallocInst *> Worklist;
  for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
    BasicBlock & BB = *fI;
    for (BasicBlock::iterator bI = BB.begin(), bE = BB.end(); bI != bE; ++bI) {
      Instruction * I = bI;

      //
      // Look to see if there is an instruction that stores a pointer to
      // memory.  If so, then free the pointer before the store.
      //
      if (MallocInst * MI = dyn_cast<MallocInst>(I)) {
        // Skip if we should not insert a fault.
        if (!doFault()) continue;

        //
        // Add the malloc instruction to the list of places to insert frees.
        // We do this here to avoid iterator invalidation.
        //
        Worklist.push_back (MI);
      }
    }
  }

  //
  // Insert a free after every malloc in the work list.
  //
  while (Worklist.size()) {
    MallocInst * MI = Worklist.back();
    Worklist.pop_back();

    BasicBlock::iterator InsertPt = MI;
    ++InsertPt;

    //
    // Print information about where the fault is being inserted.
    //
    printSourceInfo ("Real dangling pointer", MI);

    //
    // Insert a call to free to deallocate the allocated memory.
    //
    new FreeInst (MI, InsertPt);
    ++DPFaults;
  }

  return (DPFaults > 0);
}

//
// Method: insertBadAllocationSizes()
//
// Description:
//  This method will look for allocations and change their size to be
//  incorrect.  It does the following:
//    o) Changes the number of array elements allocated by alloca and malloc.
//
// Return value:
//  true  - The module was modified.
//  false - The module was left unmodified.
//
bool
FaultInjector::insertBadAllocationSizes  (Function & F) {
  // Worklist of allocation sites to rewrite
  std::vector<AllocationInst * > WorkList;

  for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
    BasicBlock & BB = *fI;
    for (BasicBlock::iterator I = BB.begin(), bE = BB.end(); I != bE; ++I) {
      if (AllocationInst * AI = dyn_cast<AllocationInst>(I)) {
        if (AI->isArrayAllocation()) {
          // Skip if we should not insert a fault.
          if (!doFault()) continue;

          WorkList.push_back(AI);
        }
      }
    }
  }

  while (WorkList.size()) {
    AllocationInst * AI = WorkList.back();
    WorkList.pop_back();

    //
    // Print information about where the fault is being inserted.
    //
    printSourceInfo ("Bad allocation size", AI);

    Instruction * NewAlloc = 0;
    if (isa<MallocInst>(AI))
      NewAlloc =  new MallocInst (AI->getAllocatedType(),
                                  ConstantInt::get(Int32Type,0),
                                  AI->getAlignment(),
                                  AI->getName(),
                                  AI);
    else
      NewAlloc =  new AllocaInst (AI->getAllocatedType(),
                                  ConstantInt::get(Int32Type,0),
                                  AI->getAlignment(),
                                  AI->getName(),
                                  AI);

    AI->replaceAllUsesWith (NewAlloc);
    AI->eraseFromParent();
    ++BadSizes;
  }

  //
  // Try harder to make bad allocation sizes.
  //
  WorkList.clear();
  for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
    BasicBlock & BB = *fI;
    for (BasicBlock::iterator I = BB.begin(), bE = BB.end(); I != bE; ++I) {
      if (AllocationInst * AI = dyn_cast<AllocationInst>(I)) {
        //
        // Determine if this is a data type that we can make smaller.
        //
        if (((TD->getTypeAllocSize(AI->getAllocatedType())) > 4) && doFault()) {
          WorkList.push_back(AI);
        }
      }
    }
  }

  //
  // Replace these allocations with an allocation of an integer and cast the
  // result back into the appropriate type.
  //
  while (WorkList.size()) {
    AllocationInst * AI = WorkList.back();
    WorkList.pop_back();

    Instruction * NewAlloc = 0;
    if (isa<MallocInst>(AI))
      NewAlloc =  new MallocInst (Int32Type,
                                  AI->getArraySize(),
                                  AI->getAlignment(),
                                  AI->getName(),
                                  AI);
    else
      NewAlloc =  new AllocaInst (Int32Type,
                                  AI->getArraySize(),
                                  AI->getAlignment(),
                                  AI->getName(),
                                  AI);

    NewAlloc = castTo (NewAlloc, AI->getType(), "", AI);
    AI->replaceAllUsesWith (NewAlloc);
    AI->eraseFromParent();
    ++BadSizes;
  }

  return (BadSizes > 0);
}

//
// Methods: insertBadIndexing()
//
// Description:
//  This method modifieds GEP indexing expressions so that their indices are
//  (most likely) below the bounds of the object pointed to by the source
//  pointer.  It does this by modifying the first index to be -1.
//
// Return value:
//  true  - One or more changes were made to the program.
//  false - No changes were made to the program.
//
bool
FaultInjector::insertBadIndexing (Function & F) {
  // Worklist of allocation sites to rewrite
  std::vector<GetElementPtrInst *> WorkList;

  //
  // Find GEP instructions that index into an array.  Add these to the
  // worklist.
  //
  for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
    BasicBlock & BB = *fI;
    for (BasicBlock::iterator I = BB.begin(), bE = BB.end(); I != bE; ++I) {
      if (GetElementPtrInst * GEP = dyn_cast<GetElementPtrInst>(I)) {
        // Skip if we should not insert a fault.
        if (!doFault()) continue;

        WorkList.push_back (GEP);
      }
    }
  }

  // Flag whether the program was modified
  bool modified = (WorkList.size() > 0);

  //
  // Iterator through the worklist and transform each GEP.
  //
  while (WorkList.size()) {
    GetElementPtrInst * GEP = WorkList.back();
    WorkList.pop_back();

    //
    // Print out where the fault will be inserted in the source code.
    //
    printSourceInfo ("Bad indexing", GEP);

    // The index arguments to the new GEP
    std::vector<Value *> args;

    //
    // Create a copy of the GEP's indices.
    //
    User::op_iterator i = GEP->idx_begin();
    if (i == GEP->idx_end()) continue;
    args.push_back (ConstantInt::get (Int32Type, INT_MAX, true));
    for (++i; i != GEP->idx_end(); ++i) {
      args.push_back (*i);
    }

    //
    // Create the new GEP instruction.
    //
    Value * Pointer = GEP->getPointerOperand();
    Twine name = GEP->getName() + "badindex";
    GetElementPtrInst * NewGEP = GetElementPtrInst::Create (Pointer,
                                                            args.begin(),
                                                            args.end(),
                                                            name,
                                                            GEP);
    GEP->replaceAllUsesWith (NewGEP);
    GEP->eraseFromParent();
    ++BadIndices;
  }

  return modified;
}

//
// Method: insertUninitializedUse()
//
// Description:
//  This method will insert uses of uninitialized pointers.
//
// Inputs:
//  F - The function in which to inject errors.
//
// Return value:
//  true  - This method modified the given function.
//  false - This method did not modify the given function.
//
// Pre-conditions:
//  The seed value for the random number generator used to determine if we
//  inject faults must already have been called.
//
// Post-conditions:
//  The global statistics variable will have been updated to reflect the number
//  of uninitialized uses added.
//
bool
FaultInjector::insertUninitializedUse (Function & F) {
  // Worklist of allocation sites to instrument
  std::map<AllocationInst *, std::vector<Value *> > WorkList;

  //
  // Look for allocation instructions that allocate structures with pointers
  // in them.
  //
  for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) {
    BasicBlock & BB = *fI;
    for (BasicBlock::iterator I = BB.begin(), bE = BB.end(); I != bE; ++I) {
      if (AllocationInst * AI = dyn_cast<AllocationInst>(I)) {
        //
        // Only inject a fault if the allocated memory has a pointer in it.
        //
        std::vector<Value *> Indices;
        Indices.push_back (ConstantInt::get (Int32Type, 0));
        if (typeContainsPointer (AI->getAllocatedType(),
                                 Indices,
                                 &getGlobalContext())) {
          // Skip if we should not insert a fault.
          if (!doFault()) continue;
          WorkList.insert(std::make_pair (AI, Indices));
        }
      }
    }
  }

  //
  // Flag whether we'll have modified something.
  //
  bool modified = (WorkList.size() > 0);

  std::map<AllocationInst *, std::vector<Value *> >::iterator i;
  for (i = WorkList.begin(); i != WorkList.end(); ++i) {
    // Get the allocation instruction which we will use.
    AllocationInst * AI = i->first;

    // Get the set of indices that we found for accessing the pointer element
    std::vector<Value *> Indices = i->second;

    //
    // Print information about where the fault is being inserted.
    //
    printSourceInfo ("Uninitialized pointer", AI);

    //
    // Find the insertion point; it should be the next instruction after the
    // allocation.
    //
    BasicBlock::iterator InsertPt = AI;
    ++InsertPt;

    //
    // Insert a GEP expression for the pointer using the indices we found when
    // we went searching for a pointer value.
    //
    GetElementPtrInst * GEP = GetElementPtrInst::Create (AI,
                                                         Indices.begin(),
                                                         Indices.end(),
                                                         "gep",
                                                         InsertPt);

    //
    // Now load the uninitialized pointer.
    //
    LoadInst * BadPtr = new LoadInst (GEP, "badptr", InsertPt);

    //
    // Check to see if the type of the loaded pointer is a function pointer.
    // If so, we cannot create a load from it.
    //
    const PointerType * PT = dyn_cast<PointerType>(BadPtr->getType());
    assert (PT && "Load of non-pointer type!\n");
    if (isa<FunctionType>(PT->getElementType())) continue;

    //
    // Now my evil plan is complete!  Dereference this pointer and take the
    // first step into oblivion!
    //
    new LoadInst (BadPtr, "shouldfault", true, InsertPt);

    //
    // Update the statistics.
    //
    ++UsesBeforeInit;
  }

  return modified;
}

//
// Method: runOnModule()
//
// Description:
//  This is where the pass begin execution.
//
// Return value:
//  true  - The module was modified.
//  false - The module was left unmodified.
//
bool
FaultInjector::runOnModule(Module &M) {
  // Track whether anything has been modified
  bool modified = false;

  //
  // Create needed LLVM types.
  //
  Int32Type = IntegerType::getInt32Ty(getGlobalContext());

  // Get analysis results from DSA.
  TDPass = &getAnalysis<TDDataStructures>();

  // Get information on the target architecture for this program
  TD     = &getAnalysis<TargetData>();

  // Initialize the random number generator
  srand (Seed);

  // Calculate the threshold for when a fault should be inserted
  threshold = (RAND_MAX / 100 * Frequency);

  // List of functions to process
  std::vector<Function *> FunctionList;

  // Process each function
  getFunctionList (M, FunctionList);
  while (FunctionList.size()) {
    Function * F = FunctionList.back();
    FunctionList.pop_back();

    // Insert dangling pointer errors
    if (InjectEasyDPFaults) modified |= insertEasyDanglingPointers(*F);
    if (InjectHardDPFaults) modified |= insertHardDanglingPointers(*F);
    if (InjectRealDPFaults) modified |= insertRealDanglingPointers(*F);

    // Insert bad allocation sizes
    if (InjectBadSizes) modified |= insertBadAllocationSizes (*F);

    // Insert incorrect indices in GEPs
    if (InjectBadIndices) modified |= insertBadIndexing (*F);

    // Insert uses of uninitialized pointers
    if (InjectUninitUses) modified |= insertUninitializedUse (*F);
  }

  return modified;
}
