LLVM API Documentation
00001 //===- FindUnsafePointerTypes.cpp - Check pointer usage safety ------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines a pass that can be used to determine, interprocedurally, 00011 // which pointer types are accessed unsafely in a program. If there is an 00012 // "unsafe" access to a specific pointer type, transformations that depend on 00013 // type safety cannot be permitted. 00014 // 00015 // The result of running this analysis over a program is a set of unsafe pointer 00016 // types that cannot be transformed. Safe pointer types are not tracked. 00017 // 00018 // Additionally, this analysis exports a hidden command line argument that (when 00019 // enabled) prints out the reasons a type was determined to be unsafe. 00020 // 00021 // Currently, the only allowed operations on pointer types are: 00022 // alloca, malloc, free, getelementptr, load, and store 00023 // 00024 //===----------------------------------------------------------------------===// 00025 00026 #include "llvm/Analysis/FindUnsafePointerTypes.h" 00027 #include "llvm/Assembly/CachedWriter.h" 00028 #include "llvm/DerivedTypes.h" 00029 #include "llvm/Module.h" 00030 #include "llvm/Support/InstIterator.h" 00031 #include "llvm/Support/CommandLine.h" 00032 using namespace llvm; 00033 00034 static RegisterAnalysis<FindUnsafePointerTypes> 00035 X("unsafepointertypes", "Find Unsafe Pointer Types"); 00036 00037 // Provide a command line option to turn on printing of which instructions cause 00038 // a type to become invalid 00039 // 00040 static cl::opt<bool> 00041 PrintFailures("printunsafeptrinst", cl::Hidden, 00042 cl::desc("Print Unsafe Pointer Access Instructions")); 00043 00044 static inline bool isSafeInstruction(const Instruction &I) { 00045 switch (I.getOpcode()) { 00046 case Instruction::Alloca: 00047 case Instruction::Malloc: 00048 case Instruction::Free: 00049 case Instruction::Load: 00050 case Instruction::Store: 00051 case Instruction::GetElementPtr: 00052 case Instruction::Call: 00053 case Instruction::Invoke: 00054 case Instruction::PHI: 00055 return true; 00056 } 00057 return false; 00058 } 00059 00060 00061 bool FindUnsafePointerTypes::runOnModule(Module &Mod) { 00062 for (Module::iterator FI = Mod.begin(), E = Mod.end(); 00063 FI != E; ++FI) { 00064 const Function *F = FI; // We don't need/want write access 00065 for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { 00066 const Type *ITy = I->getType(); 00067 if (isa<PointerType>(ITy) && !UnsafeTypes.count((PointerType*)ITy)) 00068 if (!isSafeInstruction(*I)) { 00069 UnsafeTypes.insert((PointerType*)ITy); 00070 00071 if (PrintFailures) { 00072 CachedWriter CW(F->getParent(), std::cerr); 00073 std::cerr << "FindUnsafePointerTypes: Type '"; 00074 CW << *ITy; 00075 std::cerr << "' marked unsafe in '" << F->getName() << "' by:\n"; 00076 CW << *I; 00077 } 00078 } 00079 } 00080 } 00081 00082 return false; 00083 } 00084 00085 00086 // printResults - Loop over the results of the analysis, printing out unsafe 00087 // types. 00088 // 00089 void FindUnsafePointerTypes::print(std::ostream &o, const Module *M) const { 00090 if (UnsafeTypes.empty()) { 00091 o << "SafePointerAccess Analysis: No unsafe types found!\n"; 00092 return; 00093 } 00094 00095 CachedWriter CW(M, o); 00096 00097 o << "SafePointerAccess Analysis: Found these unsafe types:\n"; 00098 unsigned Counter = 1; 00099 for (std::set<PointerType*>::const_iterator I = getUnsafeTypes().begin(), 00100 E = getUnsafeTypes().end(); I != E; ++I, ++Counter) { 00101 00102 o << " #" << Counter << ". "; 00103 CW << **I << "\n"; 00104 } 00105 } 00106