Don't use PassInfo* as a type identifier for passes. Instead, use the address of...
[oota-llvm.git] / lib / Analysis / Lint.cpp
index 1e836af1c5ca5cb4e921a3d053e475bce6af37b9..a9d972435f5fb8bbcea035b8d3d586f3283127fa 100644 (file)
@@ -19,7 +19,8 @@
 // 
 // Another limitation is that it assumes all code will be executed. A store
 // through a null pointer in a basic block which is never reached is harmless,
-// but this pass will warn about it anyway.
+// but this pass will warn about it anyway. This is the main reason why most
+// of these checks live here instead of in the Verifier pass.
 //
 // Optimization passes may make conditions that this pass checks for more or
 // less obvious. If an optimization pass appears to be introducing a warning,
@@ -107,7 +108,7 @@ namespace {
     raw_string_ostream MessagesStr;
 
     static char ID; // Pass identification, replacement for typeid
-    Lint() : FunctionPass(&ID), MessagesStr(Messages) {}
+    Lint() : FunctionPass(ID), MessagesStr(Messages) {}
 
     virtual bool runOnFunction(Function &F);
 
@@ -166,8 +167,7 @@ namespace {
 }
 
 char Lint::ID = 0;
-static RegisterPass<Lint>
-X("lint", "Statically lint-checks LLVM IR", false, true);
+INITIALIZE_PASS(Lint, "lint", "Statically lint-checks LLVM IR", false, true);
 
 // Assert - We know that cond should be true, if not print an error message.
 #define Assert(C, M) \
@@ -200,6 +200,8 @@ void Lint::visitFunction(Function &F) {
   // fairly common mistake to neglect to name a function.
   Assert1(F.hasName() || F.hasLocalLinkage(),
           "Unusual: Unnamed function with non-local linkage", &F);
+
+  // TODO: Check for irreducible control flow.
 }
 
 void Lint::visitCallSite(CallSite CS) {
@@ -215,7 +217,6 @@ void Lint::visitCallSite(CallSite CS) {
 
     const FunctionType *FT = F->getFunctionType();
     unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin());
-    std::vector<Value *> NoAliasVals;
 
     Assert1(FT->isVarArg() ?
               FT->getNumParams() <= NumActualArgs :
@@ -223,7 +224,12 @@ void Lint::visitCallSite(CallSite CS) {
             "Undefined behavior: Call argument count mismatches callee "
             "argument count", &I);
 
+    Assert1(FT->getReturnType() == I.getType(),
+            "Undefined behavior: Call return type mismatches "
+            "callee return type", &I);
+
     // Check argument types (in case the callee was casted) and attributes.
+    // TODO: Verify that caller and callee attributes are compatible.
     Function::arg_iterator PI = F->arg_begin(), PE = F->arg_end();
     CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
     for (; AI != AE; ++AI) {
@@ -233,8 +239,18 @@ void Lint::visitCallSite(CallSite CS) {
         Assert1(Formal->getType() == Actual->getType(),
                 "Undefined behavior: Call argument type mismatches "
                 "callee parameter type", &I);
+
+        // Check that noalias arguments don't alias other arguments. The
+        // AliasAnalysis API isn't expressive enough for what we really want
+        // to do. Known partial overlap is not distinguished from the case
+        // where nothing is known.
         if (Formal->hasNoAliasAttr() && Actual->getType()->isPointerTy())
-          NoAliasVals.push_back(Actual);
+          for (CallSite::arg_iterator BI = CS.arg_begin(); BI != AE; ++BI) {
+            Assert1(AI == BI || AA->alias(*AI, *BI) != AliasAnalysis::MustAlias,
+                    "Unusual: noalias argument aliases another argument", &I);
+          }
+
+        // Check that an sret argument points to valid memory.
         if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) {
           const Type *Ty =
             cast<PointerType>(Formal->getType())->getElementType();
@@ -244,16 +260,6 @@ void Lint::visitCallSite(CallSite CS) {
         }
       }
     }
-
-    // Check that the noalias arguments don't overlap. The AliasAnalysis API
-    // isn't expressive enough for what we really want to do. Known partial
-    // overlap is not distinguished from the case where nothing is known.
-    for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
-         AI != AE; ++AI)
-      for (std::vector<Value *>::iterator J = NoAliasVals.begin(),
-           E = NoAliasVals.end(); J != E; ++J)
-        Assert1(AA->alias(*J, ~0u, *AI, ~0u) != AliasAnalysis::MustAlias,
-                "Unusual: noalias argument aliases another argument", &I);
   }
 
   if (CS.isCall() && cast<CallInst>(CS.getInstruction())->isTailCall())
@@ -360,6 +366,7 @@ void Lint::visitReturnInst(ReturnInst &I) {
 }
 
 // TODO: Check that the reference is in bounds.
+// TODO: Check readnone/readonly function attributes.
 void Lint::visitMemoryReference(Instruction &I,
                                 Value *Ptr, unsigned Size, unsigned Align,
                                 const Type *Ty, unsigned Flags) {
@@ -500,6 +507,8 @@ void Lint::visitAllocaInst(AllocaInst &I) {
     // This isn't undefined behavior, it's just an obvious pessimization.
     Assert1(&I.getParent()->getParent()->getEntryBlock() == I.getParent(),
             "Pessimization: Static alloca outside of entry block", &I);
+
+  // TODO: Check for an unusual size (MSB set?)
 }
 
 void Lint::visitVAArgInst(VAArgInst &I) {
@@ -509,6 +518,9 @@ void Lint::visitVAArgInst(VAArgInst &I) {
 
 void Lint::visitIndirectBrInst(IndirectBrInst &I) {
   visitMemoryReference(I, I.getAddress(), ~0u, 0, 0, MemRef::Branchee);
+
+  Assert1(I.getNumDestinations() != 0,
+          "Undefined behavior: indirectbr with no destinations", &I);
 }
 
 void Lint::visitExtractElementInst(ExtractElementInst &I) {