diff options
author | Jakub Kuderski <kubak@google.com> | 2021-11-03 20:47:57 -0400 |
---|---|---|
committer | Jakub Kuderski <kubak@google.com> | 2021-11-03 20:52:21 -0400 |
commit | 3348b841d36e6a189e1bcb30de41b7a8ec8c6991 (patch) | |
tree | 296b6c7e367ba83455d56da99c7652e881dd8334 /llvm/unittests/IR/ConstantRangeTest.cpp | |
parent | 0986433401067c72816450e64d73a79f16cc3c5e (diff) | |
download | llvm-3348b841d36e6a189e1bcb30de41b7a8ec8c6991.zip llvm-3348b841d36e6a189e1bcb30de41b7a8ec8c6991.tar.gz llvm-3348b841d36e6a189e1bcb30de41b7a8ec8c6991.tar.bz2 |
Make enum iteration with seq safe by default
By default `llvm::seq` would happily iterate over enums, which may be unsafe if the enum values are not continuous. This patch disable enum iteration with `llvm::seq` and `llvm::seq_inclusive` and adds two new functions: `enum_seq` and `enum_seq_inclusive`.
To make sure enum iteration is safe, we require users to declare their enum types as iterable by specializing `enum_iteration_traits<SomeEnum>`. Because it's not always possible to add these traits next to enum definition (e.g., for enums defined in external libraries), we provide an escape hatch to allow iteration on per-callsite basis by passing `force_iteration_on_noniterable_enum`.
The main benefit of this approach is that these global declarations via traits can appear just next to enum definitions, making easy to spot when enums are miss-labeled, e.g., after introducing new enum values, whereas `force_iteration_on_noniterable_enum` should stand out and be easy to grep for.
This emerged from a discussion with gchatelet@ about reusing llvm's `Sequence.h` in lieu of https://github.com/GPUOpen-Drivers/llpc/blob/dev/lgc/interface/lgc/EnumIterator.h.
Reviewed By: dblaikie, gchatelet, aaron.ballman
Differential Revision: https://reviews.llvm.org/D107378
Diffstat (limited to 'llvm/unittests/IR/ConstantRangeTest.cpp')
-rw-r--r-- | llvm/unittests/IR/ConstantRangeTest.cpp | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/llvm/unittests/IR/ConstantRangeTest.cpp b/llvm/unittests/IR/ConstantRangeTest.cpp index 7bf7e0b..f88e986 100644 --- a/llvm/unittests/IR/ConstantRangeTest.cpp +++ b/llvm/unittests/IR/ConstantRangeTest.cpp @@ -1572,8 +1572,7 @@ void ICmpTestImpl(CmpInst::Predicate Pred) { } TEST(ConstantRange, ICmp) { - for (auto Pred : seq_inclusive(CmpInst::Predicate::FIRST_ICMP_PREDICATE, - CmpInst::Predicate::LAST_ICMP_PREDICATE)) + for (auto Pred : ICmpInst::predicates()) ICmpTestImpl(Pred); } @@ -2531,8 +2530,7 @@ void testConstantRangeICmpPredEquivalence(ICmpInst::Predicate SrcPred, T Func) { } TEST_F(ConstantRangeTest, areInsensitiveToSignednessOfICmpPredicate) { - for (auto Pred : seq_inclusive(ICmpInst::Predicate::FIRST_ICMP_PREDICATE, - ICmpInst::Predicate::LAST_ICMP_PREDICATE)) { + for (auto Pred : ICmpInst::predicates()) { if (ICmpInst::isEquality(Pred)) continue; ICmpInst::Predicate FlippedSignednessPred = @@ -2548,8 +2546,7 @@ TEST_F(ConstantRangeTest, areInsensitiveToSignednessOfICmpPredicate) { } TEST_F(ConstantRangeTest, areInsensitiveToSignednessOfInvertedICmpPredicate) { - for (auto Pred : seq_inclusive(ICmpInst::Predicate::FIRST_ICMP_PREDICATE, - ICmpInst::Predicate::LAST_ICMP_PREDICATE)) { + for (auto Pred : ICmpInst::predicates()) { if (ICmpInst::isEquality(Pred)) continue; ICmpInst::Predicate InvertedFlippedSignednessPred = @@ -2567,8 +2564,7 @@ TEST_F(ConstantRangeTest, areInsensitiveToSignednessOfInvertedICmpPredicate) { } TEST_F(ConstantRangeTest, getEquivalentPredWithFlippedSignedness) { - for (auto Pred : seq_inclusive(ICmpInst::Predicate::FIRST_ICMP_PREDICATE, - ICmpInst::Predicate::LAST_ICMP_PREDICATE)) { + for (auto Pred : ICmpInst::predicates()) { if (ICmpInst::isEquality(Pred)) continue; testConstantRangeICmpPredEquivalence( |