diff options
author | Jay Foad <jay.foad@gmail.com> | 2011-01-11 15:07:38 +0000 |
---|---|---|
committer | Jay Foad <jay.foad@gmail.com> | 2011-01-11 15:07:38 +0000 |
commit | 67c619ba3eae68dcdb3f9340d82b33173aa0c256 (patch) | |
tree | 3c0745fca275d5e4e31f1da2a5a84553fe69bd4a /include/llvm/OperandTraits.h | |
parent | 65fdded3197461232d8428af7ddd0107e4a9f946 (diff) | |
download | llvm-67c619ba3eae68dcdb3f9340d82b33173aa0c256.tar.gz llvm-67c619ba3eae68dcdb3f9340d82b33173aa0c256.tar.bz2 llvm-67c619ba3eae68dcdb3f9340d82b33173aa0c256.tar.xz |
FixedNumOperandTraits and VariadicOperandTraits assumed that, given a
"this" pointer for any subclass of User, you could static_cast it to
User* and then reinterpret_cast that to Use* to get the end of the
operand list. This isn't a safe assumption in general, because the
static_cast might adjust the "this" pointer. Fixed by having these
OperandTraits classes take an extra template parameter, which is the
subclass of User. This is groundwork for PR889.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123235 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/OperandTraits.h')
-rw-r--r-- | include/llvm/OperandTraits.h | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/include/llvm/OperandTraits.h b/include/llvm/OperandTraits.h index b614ccbc37..dbdb1a1549 100644 --- a/include/llvm/OperandTraits.h +++ b/include/llvm/OperandTraits.h @@ -27,12 +27,12 @@ namespace llvm { /// when it is a prefix to the User object, and the number of Use objects is /// known at compile time. -template <unsigned ARITY> +template <typename SubClass, unsigned ARITY> struct FixedNumOperandTraits { - static Use *op_begin(User* U) { + static Use *op_begin(SubClass* U) { return reinterpret_cast<Use*>(U) - ARITY; } - static Use *op_end(User* U) { + static Use *op_end(SubClass* U) { return reinterpret_cast<Use*>(U); } static unsigned operands(const User*) { @@ -57,8 +57,8 @@ struct FixedNumOperandTraits { /// OptionalOperandTraits - when the number of operands may change at runtime. /// Naturally it may only decrease, because the allocations may not change. -template <unsigned ARITY = 1> -struct OptionalOperandTraits : public FixedNumOperandTraits<ARITY> { +template <typename SubClass, unsigned ARITY = 1> +struct OptionalOperandTraits : public FixedNumOperandTraits<SubClass, ARITY> { static unsigned operands(const User *U) { return U->getNumOperands(); } @@ -72,12 +72,12 @@ struct OptionalOperandTraits : public FixedNumOperandTraits<ARITY> { /// when it is a prefix to the User object, and the number of Use objects is /// only known at allocation time. -template <unsigned MINARITY = 0> +template <typename SubClass, unsigned MINARITY = 0> struct VariadicOperandTraits { - static Use *op_begin(User* U) { - return reinterpret_cast<Use*>(U) - U->getNumOperands(); + static Use *op_begin(SubClass* U) { + return reinterpret_cast<Use*>(U) - static_cast<User*>(U)->getNumOperands(); } - static Use *op_end(User* U) { + static Use *op_end(SubClass* U) { return reinterpret_cast<Use*>(U); } static unsigned operands(const User *U) { |