aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-02-19 15:13:36 -0800
committerDerek Schuff <dschuff@chromium.org>2013-02-19 15:13:36 -0800
commit06dd2371667be256a846a68e51d376349f041752 (patch)
treefe02d69310734aab59839d5f27e802117664c35a
parent50c20006ea707be7e439c3093d4a064ccfe78b7a (diff)
Move ABI type checker to its own file
R=jvoung@chromium.org,eliben@chromium.org BUG= Review URL: https://codereview.chromium.org/12302030
-rw-r--r--lib/Analysis/NaCl/CMakeLists.txt1
-rw-r--r--lib/Analysis/NaCl/CheckTypes.h130
-rw-r--r--lib/Analysis/NaCl/PNaClABITypeChecker.cpp106
-rw-r--r--lib/Analysis/NaCl/PNaClABITypeChecker.h52
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp8
-rw-r--r--lib/Analysis/NaCl/PNaClABIVerifyModule.cpp13
6 files changed, 170 insertions, 140 deletions
diff --git a/lib/Analysis/NaCl/CMakeLists.txt b/lib/Analysis/NaCl/CMakeLists.txt
index 8a5eceb3e4..7fa3a134ac 100644
--- a/lib/Analysis/NaCl/CMakeLists.txt
+++ b/lib/Analysis/NaCl/CMakeLists.txt
@@ -1,4 +1,5 @@
add_llvm_library(LLVMAnalysisNaCl
+ PNaCLABITypeChecker.cpp
PNaClABIVerifyFunctions.cpp
PNaClABIVerifyModule.cpp
)
diff --git a/lib/Analysis/NaCl/CheckTypes.h b/lib/Analysis/NaCl/CheckTypes.h
deleted file mode 100644
index 64a634cd25..0000000000
--- a/lib/Analysis/NaCl/CheckTypes.h
+++ /dev/null
@@ -1,130 +0,0 @@
-//===- CheckTypes.h - Verify PNaCl ABI rules --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Common type-checking code for module and function-level passes
-//
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LIB_ANALYSIS_NACL_CHECKTYPES_H
-#define LIB_ANALYSIS_NACL_CHECKTYPES_H
-
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/Support/raw_ostream.h"
-
-class TypeChecker {
- public:
- bool isValidType(const llvm::Type *Ty) {
- if (VisitedTypes.count(Ty))
- return VisitedTypes[Ty];
-
- unsigned Width;
- bool Valid = false;
- switch (Ty->getTypeID()) {
- // Allowed primitive types
- case llvm::Type::VoidTyID:
- case llvm::Type::FloatTyID:
- case llvm::Type::DoubleTyID:
- case llvm::Type::LabelTyID:
- case llvm::Type::MetadataTyID:
- Valid = true;
- break;
- // Disallowed primitive types
- case llvm::Type::HalfTyID:
- case llvm::Type::X86_FP80TyID:
- case llvm::Type::FP128TyID:
- case llvm::Type::PPC_FP128TyID:
- case llvm::Type::X86_MMXTyID:
- Valid = false;
- break;
- // Derived types
- case llvm::Type::VectorTyID:
- Valid = false;
- break;
- case llvm::Type::IntegerTyID:
- Width = llvm::cast<const llvm::IntegerType>(Ty)->getBitWidth();
- Valid = (Width == 1 || Width == 8 || Width == 16 ||
- Width == 32 || Width == 64);
- break;
- case llvm::Type::FunctionTyID:
- case llvm::Type::StructTyID:
- case llvm::Type::ArrayTyID:
- case llvm::Type::PointerTyID:
- // These types are valid if their contained or pointed-to types are
- // valid. Since struct/pointer subtype relationships may be circular,
- // mark the current type as valid to avoid infinite recursion
- Valid = true;
- VisitedTypes[Ty] = true;
- for (llvm::Type::subtype_iterator I = Ty->subtype_begin(),
- E = Ty->subtype_end(); I != E; ++I)
- Valid &= isValidType(*I);
- break;
- // Handle NumTypeIDs, and no default case,
- // so we get a warning if new types are added
- case llvm::Type::NumTypeIDs:
- Valid = false;
- break;
- }
-
- VisitedTypes[Ty] = Valid;
- return Valid;
- }
-
- // If the value contains an invalid type, return a pointer to the type.
- // Return null if there are no invalid types.
- llvm::Type *checkTypesInValue(const llvm::Value *V) {
- // TODO: Checking types in values probably belongs in its
- // own value checker which also handles the various types of
- // constexpr (in particular, blockaddr constexprs cause this code
- // to assert rather than go off and try to verify the BBs of a function)
- // But this code is in a good consistent checkpoint-able state.
- assert(llvm::isa<llvm::Constant>(V));
- if (VisitedConstants.count(V))
- return VisitedConstants[V];
-
- if (!isValidType(V->getType())) {
- VisitedConstants[V] = V->getType();
- return V->getType();
- }
-
- // Operand values must also be valid. Values may be circular, so
- // mark the current value as valid to avoid infinite recursion.
- VisitedConstants[V] = NULL;
- const llvm::User *U = llvm::cast<llvm::User>(V);
- for (llvm::Constant::const_op_iterator I = U->op_begin(),
- E = U->op_end(); I != E; ++I) {
- llvm::Type *Invalid = checkTypesInValue(*I);
- if (Invalid) {
- VisitedConstants[V] = Invalid;
- return Invalid;
- }
- }
- VisitedConstants[V] = NULL;
- return NULL;
- }
-
- // There's no built-in way to get the name of a type, so use a
- // string ostream to print it.
- static std::string getTypeName(const llvm::Type *T) {
- std::string TypeName;
- llvm::raw_string_ostream N(TypeName);
- T->print(N);
- return N.str();
- }
-
- private:
- // To avoid walking constexprs and types multiple times, keep a cache of
- // what we have seen. This is also used to prevent infinite recursion e.g.
- // in case of structures like linked lists with pointers to themselves.
- llvm::DenseMap<const llvm::Value*, llvm::Type*> VisitedConstants;
- llvm::DenseMap<const llvm::Type*, bool> VisitedTypes;
-};
-
-#endif // LIB_ANALYSIS_NACL_CHECKTYPES_H
diff --git a/lib/Analysis/NaCl/PNaClABITypeChecker.cpp b/lib/Analysis/NaCl/PNaClABITypeChecker.cpp
new file mode 100644
index 0000000000..3a18129588
--- /dev/null
+++ b/lib/Analysis/NaCl/PNaClABITypeChecker.cpp
@@ -0,0 +1,106 @@
+//===- PNaClABICheckTypes.h - Verify PNaCl ABI rules --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common type-checking code for module and function-level passes
+//
+//
+//===----------------------------------------------------------------------===//
+
+#include "PNaClABITypeChecker.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/DerivedTypes.h"
+
+using namespace llvm;
+
+bool PNaClABITypeChecker::isValidType(const Type *Ty) {
+ if (VisitedTypes.count(Ty))
+ return VisitedTypes[Ty];
+
+ unsigned Width;
+ bool Valid = false;
+ switch (Ty->getTypeID()) {
+ // Allowed primitive types
+ case Type::VoidTyID:
+ case Type::FloatTyID:
+ case Type::DoubleTyID:
+ case Type::LabelTyID:
+ case Type::MetadataTyID:
+ Valid = true;
+ break;
+ // Disallowed primitive types
+ case Type::HalfTyID:
+ case Type::X86_FP80TyID:
+ case Type::FP128TyID:
+ case Type::PPC_FP128TyID:
+ case Type::X86_MMXTyID:
+ Valid = false;
+ break;
+ // Derived types
+ case Type::VectorTyID:
+ Valid = false;
+ break;
+ case Type::IntegerTyID:
+ Width = cast<const IntegerType>(Ty)->getBitWidth();
+ Valid = (Width == 1 || Width == 8 || Width == 16 ||
+ Width == 32 || Width == 64);
+ break;
+ case Type::FunctionTyID:
+ case Type::StructTyID:
+ case Type::ArrayTyID:
+ case Type::PointerTyID:
+ // These types are valid if their contained or pointed-to types are
+ // valid. Since struct/pointer subtype relationships may be circular,
+ // mark the current type as valid to avoid infinite recursion
+ Valid = true;
+ VisitedTypes[Ty] = true;
+ for (Type::subtype_iterator I = Ty->subtype_begin(),
+ E = Ty->subtype_end(); I != E; ++I)
+ Valid &= isValidType(*I);
+ break;
+ // Handle NumTypeIDs, and no default case,
+ // so we get a warning if new types are added
+ case Type::NumTypeIDs:
+ Valid = false;
+ break;
+ }
+
+ VisitedTypes[Ty] = Valid;
+ return Valid;
+}
+
+Type *PNaClABITypeChecker::checkTypesInValue(const Value *V) {
+ // TODO: Checking types in values probably belongs in its
+ // own value checker which also handles the various types of
+ // constexpr (in particular, blockaddr constexprs cause this code
+ // to assert rather than go off and try to verify the BBs of a function)
+ // But this code is in a good consistent checkpoint-able state.
+ assert(isa<Constant>(V));
+ if (VisitedConstants.count(V))
+ return VisitedConstants[V];
+
+ if (!isValidType(V->getType())) {
+ VisitedConstants[V] = V->getType();
+ return V->getType();
+ }
+
+ // Operand values must also be valid. Values may be circular, so
+ // mark the current value as valid to avoid infinite recursion.
+ VisitedConstants[V] = NULL;
+ const User *U = cast<User>(V);
+ for (Constant::const_op_iterator I = U->op_begin(),
+ E = U->op_end(); I != E; ++I) {
+ Type *Invalid = checkTypesInValue(*I);
+ if (Invalid) {
+ VisitedConstants[V] = Invalid;
+ return Invalid;
+ }
+ }
+ VisitedConstants[V] = NULL;
+ return NULL;
+}
diff --git a/lib/Analysis/NaCl/PNaClABITypeChecker.h b/lib/Analysis/NaCl/PNaClABITypeChecker.h
new file mode 100644
index 0000000000..1249bf04cd
--- /dev/null
+++ b/lib/Analysis/NaCl/PNaClABITypeChecker.h
@@ -0,0 +1,52 @@
+//===- CheckTypes.h - Verify PNaCl ABI rules --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Common type-checking code for module and function-level passes
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIB_ANALYSIS_NACL_CHECKTYPES_H
+#define LIB_ANALYSIS_NACL_CHECKTYPES_H
+
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+class Value;
+
+class PNaClABITypeChecker {
+ public:
+ // Returns true if Ty is a valid type for PNaCl.
+ bool isValidType(const Type *Ty);
+
+ // If the value contains an invalid type, return a pointer to the type.
+ // Return null if there are no invalid types.
+ Type *checkTypesInValue(const Value *V);
+
+ // There's no built-in way to get the name of a type, so use a
+ // string ostream to print it.
+ static std::string getTypeName(const Type *T) {
+ std::string TypeName;
+ raw_string_ostream N(TypeName);
+ T->print(N);
+ return N.str();
+ }
+
+ private:
+ // To avoid walking constexprs and types multiple times, keep a cache of
+ // what we have seen. This is also used to prevent infinite recursion e.g.
+ // in case of structures like linked lists with pointers to themselves.
+ DenseMap<const Value*, Type*> VisitedConstants;
+ DenseMap<const Type*, bool> VisitedTypes;
+};
+} // namespace llvm
+
+#endif // LIB_ANALYSIS_NACL_CHECKTYPES_H
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
index df57cfbbce..97278d95cc 100644
--- a/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
+++ b/lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp
@@ -19,7 +19,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Analysis/NaCl.h"
-#include "CheckTypes.h"
+#include "PNaClABITypeChecker.h"
using namespace llvm;
namespace {
@@ -31,9 +31,9 @@ class PNaClABIVerifyFunctions : public FunctionPass {
static char ID;
PNaClABIVerifyFunctions() : FunctionPass(ID), Errors(ErrorsString) {}
bool runOnFunction(Function &F);
- virtual void print(llvm::raw_ostream &O, const Module *M) const;
+ virtual void print(raw_ostream &O, const Module *M) const;
private:
- TypeChecker TC;
+ PNaClABITypeChecker TC;
std::string ErrorsString;
raw_string_ostream Errors;
};
@@ -126,7 +126,7 @@ bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
if (!TC.isValidType(BBI->getType())) {
Errors << "Function " + F.getName() +
" has instruction with disallowed type: " +
- TypeChecker::getTypeName(BBI->getType()) + "\n";
+ PNaClABITypeChecker::getTypeName(BBI->getType()) + "\n";
}
}
}
diff --git a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
index afe42434e7..54666378b3 100644
--- a/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
+++ b/lib/Analysis/NaCl/PNaClABIVerifyModule.cpp
@@ -20,7 +20,7 @@
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
-#include "CheckTypes.h"
+#include "PNaClABITypeChecker.h"
using namespace llvm;
namespace {
@@ -30,11 +30,11 @@ class PNaClABIVerifyModule : public ModulePass {
static char ID;
PNaClABIVerifyModule();
bool runOnModule(Module &M);
- virtual void print(llvm::raw_ostream &O, const Module *M) const;
+ virtual void print(raw_ostream &O, const Module *M) const;
private:
- TypeChecker TC;
+ PNaClABITypeChecker TC;
std::string ErrorsString;
- llvm::raw_string_ostream Errors;
+ raw_string_ostream Errors;
};
static const char *linkageName(GlobalValue::LinkageTypes LT) {
@@ -76,14 +76,15 @@ bool PNaClABIVerifyModule::runOnModule(Module &M) {
// GVs are pointers, so print the pointed-to type for clarity
Errors << "Variable " + MI->getName() +
" has disallowed type: " +
- TypeChecker::getTypeName(MI->getType()->getContainedType(0)) + "\n";
+ PNaClABITypeChecker::getTypeName(MI->getType()->getContainedType(0))
+ + "\n";
} else if (MI->hasInitializer()) {
// If the type of the global is bad, no point in checking its initializer
Type *T = TC.checkTypesInValue(MI->getInitializer());
if (T)
Errors << "Initializer for " + MI->getName() +
" has disallowed type: " +
- TypeChecker::getTypeName(T) + "\n";
+ PNaClABITypeChecker::getTypeName(T) + "\n";
}
// Check GV linkage types