[llvm] 3481898 - [IR Verifier] didn't check if switch case is constant, align IR Verifier's check with LLParser.
Peter Rong via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 3 15:29:13 PDT 2022
Author: Peter Rong
Date: 2022-11-03T15:26:54-07:00
New Revision: 348189880b7bc9513ccdd0ea3a1e255b4d3190e7
URL: https://github.com/llvm/llvm-project/commit/348189880b7bc9513ccdd0ea3a1e255b4d3190e7
DIFF: https://github.com/llvm/llvm-project/commit/348189880b7bc9513ccdd0ea3a1e255b4d3190e7.diff
LOG: [IR Verifier] didn't check if switch case is constant, align IR Verifier's check with LLParser.
If a programmer incorrectly `Switch->setOperand()` and `Verifier` will pass, causing problems when dumping this `Module`
This patch aligns SwitchInst's check with LLParser. It also includes a test to justify the patch.
Differential Revision: https://reviews.llvm.org/D136656
Added:
Modified:
llvm/lib/IR/Verifier.cpp
llvm/unittests/IR/VerifierTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 0614f206981a1..e7c2eb9e8818b 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2879,6 +2879,8 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
Type *SwitchTy = SI.getCondition()->getType();
SmallPtrSet<ConstantInt*, 32> Constants;
for (auto &Case : SI.cases()) {
+ Check(isa<ConstantInt>(SI.getOperand(Case.getCaseIndex() * 2 + 2)),
+ "Case value is not a constant integer.", &SI);
Check(Case.getCaseValue()->getType() == SwitchTy,
"Switch constants must all be same type as switch value!", &SI);
Check(Constants.insert(Case.getCaseValue()).second,
diff --git a/llvm/unittests/IR/VerifierTest.cpp b/llvm/unittests/IR/VerifierTest.cpp
index 5f34463a345eb..c4977a9ecd55a 100644
--- a/llvm/unittests/IR/VerifierTest.cpp
+++ b/llvm/unittests/IR/VerifierTest.cpp
@@ -270,5 +270,35 @@ TEST(VerifierTest, AttributesWrongContext) {
EXPECT_TRUE(verifyFunction(*F2));
}
+TEST(VerifierTest, SwitchInst) {
+ LLVMContext C;
+ Module M("M", C);
+ IntegerType *Int32Ty = Type::getInt32Ty(C);
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {Int32Ty, Int32Ty},
+ /*isVarArg=*/false);
+ Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", M);
+ BasicBlock *Entry = BasicBlock::Create(C, "entry", F);
+ BasicBlock *Default = BasicBlock::Create(C, "default", F);
+ BasicBlock *OnOne = BasicBlock::Create(C, "on_one", F);
+ BasicBlock *OnTwo = BasicBlock::Create(C, "on_two", F);
+
+ BasicBlock *Exit = BasicBlock::Create(C, "exit", F);
+
+ BranchInst::Create(Exit, Default);
+ BranchInst::Create(Exit, OnTwo);
+ BranchInst::Create(Exit, OnOne);
+ ReturnInst::Create(C, Exit);
+
+ Value *Cond = F->getArg(0);
+ SwitchInst *Switch = SwitchInst::Create(Cond, Default, 2, Entry);
+ Switch->addCase(ConstantInt::get(Int32Ty, 1), OnOne);
+ Switch->addCase(ConstantInt::get(Int32Ty, 2), OnTwo);
+
+ EXPECT_FALSE(verifyFunction(*F));
+ // set one case value to function argument.
+ Switch->setOperand(2, F->getArg(1));
+ EXPECT_TRUE(verifyFunction(*F));
+}
+
} // end anonymous namespace
} // end namespace llvm
More information about the llvm-commits
mailing list