[llvm] [BPF] Report Undefined Behavior from IR (PR #126858)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 14 08:56:08 PST 2025
================
@@ -0,0 +1,98 @@
+//===---------------- BPFAdjustOpt.cpp - Adjust Optimization --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Check 'unreachable' IRs and issue proper warnings.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BPF.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Pass.h"
+
+#define DEBUG_TYPE "bpf-check-undef-ir"
+
+using namespace llvm;
+
+namespace {
+
+class BPFCheckUndefIR final : public ModulePass {
+ bool runOnModule(Module &F) override;
+
+public:
+ static char ID;
+ BPFCheckUndefIR() : ModulePass(ID) {}
+
+private:
+ void BPFCheckUndefIRImpl(Function &F);
+ void BPFCheckInst(Function &F, BasicBlock &BB, Instruction &I);
+ void HandleUnreachableInsn(Function &F, BasicBlock &BB, Instruction &I);
+};
+} // End anonymous namespace
+
+char BPFCheckUndefIR::ID = 0;
+INITIALIZE_PASS(BPFCheckUndefIR, DEBUG_TYPE, "BPF Check Undef IRs", false,
+ false)
+
+ModulePass *llvm::createBPFCheckUndefIR() { return new BPFCheckUndefIR(); }
+
+void BPFCheckUndefIR::HandleUnreachableInsn(Function &F, BasicBlock &BB,
+ Instruction &I) {
+ // LLVM may create a switch statement with default to a 'unreachable' basic
+ // block. Do not warn for such cases.
+ unsigned NumNoSwitches = 0, NumSwitches = 0;
+ for (BasicBlock *Pred : predecessors(&BB)) {
+ const Instruction *Term = Pred->getTerminator();
+ if (Term && Term->getOpcode() == Instruction::Switch) {
+ NumSwitches++;
+ continue;
+ }
+ NumNoSwitches++;
+ }
+ if (NumSwitches > 0 && NumNoSwitches == 0)
+ return;
+
+ // If the previous insn is no return, do not warn for such cases.
+ // One example is __bpf_unreachable from libbpf bpf_headers.h.
+ Instruction *PrevI = I.getPrevNonDebugInstruction();
+ if (PrevI) {
+ auto *CI = dyn_cast<CallInst>(PrevI);
+ if (CI && CI->doesNotReturn())
+ return;
+ }
+
+ dbgs() << "WARNING: unreachable in func " << F.getName()
+ << ", due to uninitialized variable?\n";
----------------
nikic wrote:
dbgs() is not a suitable method to report user-visible warnings. This needs to go through DiagnosticInfo.
https://github.com/llvm/llvm-project/pull/126858
More information about the llvm-commits
mailing list