[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