summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2017-02-07 03:15:12 +0000
committerChandler Carruth <chandlerc@gmail.com>2017-02-07 03:15:12 +0000
commit0aecae34529b70f6ac4b758651bf579f0a464257 (patch)
treed6db150126d79158690fa2716cc941e40cf97e10 /llvm
parent833cf8bdb6e6050337e878b9946c0752d4550ac0 (diff)
downloadbcm5719-llvm-0aecae34529b70f6ac4b758651bf579f0a464257.tar.gz
bcm5719-llvm-0aecae34529b70f6ac4b758651bf579f0a464257.zip
[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. llvm-svn: 294271
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/ADT/DenseMap.h2
-rw-r--r--llvm/include/llvm/ADT/iterator.h9
2 files changed, 10 insertions, 1 deletions
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index 0b4b09d4b73..a689bcbf151 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -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() {
diff --git a/llvm/include/llvm/ADT/iterator.h b/llvm/include/llvm/ADT/iterator.h
index 6470e09db86..9a134e1557b 100644
--- a/llvm/include/llvm/ADT/iterator.h
+++ b/llvm/include/llvm/ADT/iterator.h
@@ -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; }
OpenPOWER on IntegriCloud