about summary refs log tree commit diff homepage
path: root/lib/Module/Passes.h
diff options
context:
space:
mode:
authorDan Liew <daniel.liew@imperial.ac.uk>2013-08-29 17:30:33 +0100
committerDan Liew <daniel.liew@imperial.ac.uk>2013-09-02 16:45:47 +0100
commit4b477f8108a2a92012ff138725f6c6f26ccb23e5 (patch)
tree31349b361d8db8e03b511b67e8abb3ba470e6882 /lib/Module/Passes.h
parentf8301282120cc3cc58d641ddc99f92b14d894692 (diff)
downloadklee-4b477f8108a2a92012ff138725f6c6f26ccb23e5.tar.gz
Implemented runtime check for overshift (controllable with --check-overshift
command line argument).

Overshift is where a Shl, AShr or LShr has a shift width greater
than the bit width of the first operand. This is undefined behaviour
in LLVM so we report this as an error.
Diffstat (limited to 'lib/Module/Passes.h')
-rw-r--r--lib/Module/Passes.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/Module/Passes.h b/lib/Module/Passes.h
index b3c46124..b0d4c363 100644
--- a/lib/Module/Passes.h
+++ b/lib/Module/Passes.h
@@ -137,6 +137,31 @@ public:
   virtual bool runOnModule(llvm::Module &M);
 };
 
+/// This pass injects checks to check for overshifting.
+///
+/// Overshifting is where a Shl, LShr or AShr is performed
+/// where the shift amount is greater than width of the bitvector
+/// being shifted.
+/// In LLVM (and in C/C++) this undefined behaviour!
+///
+/// Example:
+/// \code
+///     unsigned char x=15;
+///     x << 4 ; // Defined behaviour
+///     x << 8 ; // Undefined behaviour
+///     x << 255 ; // Undefined behaviour
+/// \endcode
+class OvershiftCheckPass : public llvm::ModulePass {
+  static char ID;
+public:
+#if LLVM_VERSION_CODE < LLVM_VERSION(2, 8)
+  OvershiftCheckPass(): ModulePass((intptr_t) &ID) {}
+#else
+  OvershiftCheckPass(): ModulePass(ID) {}
+#endif
+  virtual bool runOnModule(llvm::Module &M);
+};
+
 /// LowerSwitchPass - Replace all SwitchInst instructions with chained branch
 /// instructions.  Note that this cannot be a BasicBlock pass because it
 /// modifies the CFG!