[llvm] r294271 - [ADT] Defend against getting slightly wrong template arguments passed
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 6 19:15:12 PST 2017
Author: chandlerc
Date: Mon Feb 6 21:15:12 2017
New Revision: 294271
URL: http://llvm.org/viewvc/llvm-project?rev=294271&view=rev
Log:
[ADT] Defend against getting slightly wrong template arguments passed
into CRTP base classes.
This can sometimes happen and not cause an immediate failure when the
derived class is, itself, a template. You can end up essentially calling
methods on the wrong derived type but a type where many things will
appear to "work".
To fail fast and with a clear error message we can use a static_assert,
but we have to stash that static_assert inside a method body or nested
type that won't need to be completed while building the base class. I've
tried to pick a reasonably small number of places that seemed like
reliably places for this to be instantiated.
Modified:
llvm/trunk/include/llvm/ADT/DenseMap.h
llvm/trunk/include/llvm/ADT/iterator.h
Modified: llvm/trunk/include/llvm/ADT/DenseMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=294271&r1=294270&r2=294271&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/DenseMap.h (original)
+++ llvm/trunk/include/llvm/ADT/DenseMap.h Mon Feb 6 21:15:12 2017
@@ -389,6 +389,8 @@ protected:
return KeyInfoT::getHashValue(Val);
}
static const KeyT getEmptyKey() {
+ static_assert(std::is_base_of<DenseMapBase, DerivedT>::value,
+ "Must pass the derived type to this template!");
return KeyInfoT::getEmptyKey();
}
static const KeyT getTombstoneKey() {
Modified: llvm/trunk/include/llvm/ADT/iterator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/iterator.h?rev=294271&r1=294270&r2=294271&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/iterator.h (original)
+++ llvm/trunk/include/llvm/ADT/iterator.h Mon Feb 6 21:15:12 2017
@@ -91,6 +91,8 @@ protected:
public:
DerivedT operator+(DifferenceTypeT n) const {
+ static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
+ "Must pass the derived type to this template!");
static_assert(
IsRandomAccess,
"The '+' operator is only defined for random access iterators.");
@@ -114,6 +116,8 @@ public:
}
DerivedT &operator++() {
+ static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
+ "Must pass the derived type to this template!");
return static_cast<DerivedT *>(this)->operator+=(1);
}
DerivedT operator++(int) {
@@ -202,7 +206,10 @@ protected:
iterator_adaptor_base() = default;
- explicit iterator_adaptor_base(WrappedIteratorT u) : I(std::move(u)) {}
+ explicit iterator_adaptor_base(WrappedIteratorT u) : I(std::move(u)) {
+ static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
+ "Must pass the derived type to this template!");
+ }
const WrappedIteratorT &wrapped() const { return I; }
More information about the llvm-commits
mailing list