[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