Author: Daniel Paoliello Date: 2026-01-16T18:23:25-08:00 New Revision: 483c6834a213249ca27dc3569dd0ddb040356b2f
URL: https://github.com/llvm/llvm-project/commit/483c6834a213249ca27dc3569dd0ddb040356b2f DIFF: https://github.com/llvm/llvm-project/commit/483c6834a213249ca27dc3569dd0ddb040356b2f.diff LOG: [NFC][win] Use an enum for the cfguard module flag (#176461) Currently the `cfguard` module flag can be set to 1 (emit tables only, no checks) or 2 (emit tables and checks). This change formalizes that definition by moving these values into an enum, instead of just having them documented in comments. Split out from #176276 Added: Modified: clang/lib/CodeGen/CodeGenModule.cpp llvm/include/llvm/IR/Module.h llvm/include/llvm/Support/CodeGen.h llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/CFGuardLongjmp.cpp llvm/lib/IR/Module.cpp llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp llvm/lib/Transforms/CFGuard/CFGuard.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 614bca627e03c..dc8a31b7f7f0d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1122,11 +1122,15 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Warning, "CodeViewGHash", 1); } if (CodeGenOpts.ControlFlowGuard) { - // Function ID tables and checks for Control Flow Guard (cfguard=2). - getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 2); + // Function ID tables and checks for Control Flow Guard. + getModule().addModuleFlag( + llvm::Module::Warning, "cfguard", + static_cast<unsigned>(llvm::ControlFlowGuardMode::Enabled)); } else if (CodeGenOpts.ControlFlowGuardNoChecks) { - // Function ID tables for Control Flow Guard (cfguard=1). - getModule().addModuleFlag(llvm::Module::Warning, "cfguard", 1); + // Function ID tables for Control Flow Guard. + getModule().addModuleFlag( + llvm::Module::Warning, "cfguard", + static_cast<unsigned>(llvm::ControlFlowGuardMode::TableOnly)); } if (CodeGenOpts.EHContGuard) { // Function ID tables for EH Continuation Guard. diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index ac6c20b81d68c..7156a83c9f3cc 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -1056,6 +1056,9 @@ class LLVM_ABI Module { /// Get how unwind v2 (epilog) information should be generated for x64 /// Windows. WinX64EHUnwindV2Mode getWinX64EHUnwindV2Mode() const; + + /// Gets the Control Flow Guard mode. + ControlFlowGuardMode getControlFlowGuardMode() const; }; /// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h index 848796ef574f8..65d262a087378 100644 --- a/llvm/include/llvm/Support/CodeGen.h +++ b/llvm/include/llvm/Support/CodeGen.h @@ -173,6 +173,16 @@ namespace llvm { Required = 2, }; + enum class ControlFlowGuardMode { + // Don't enable Control Flow Guard. + Disabled = 0, + // Emit the Control Flow Guard tables in the binary, but don't emit any + // checks. + TableOnly = 1, + // Enable Control Flow Guard checks and emit the tables. + Enabled = 2, + }; + } // namespace llvm #endif diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d96294e06d579..3c758ed006bf5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -664,8 +664,8 @@ bool AsmPrinter::doInitialization(Module &M) { if (ES) Handlers.push_back(std::unique_ptr<EHStreamer>(ES)); - // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2). - if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard"))) + // All CFG modes required the tables emitted. + if (M.getControlFlowGuardMode() != ControlFlowGuardMode::Disabled) EHHandlers.push_back(std::make_unique<WinCFGuard>(this)); for (auto &Handler : Handlers) @@ -5088,7 +5088,7 @@ void AsmPrinter::emitCOFFFeatureSymbol(Module &M) { Feat00Value |= COFF::Feat00Flags::SafeSEH; } - if (M.getModuleFlag("cfguard")) { + if (M.getControlFlowGuardMode() != ControlFlowGuardMode::Disabled) { // Object is CFG-aware. Feat00Value |= COFF::Feat00Flags::GuardCF; } diff --git a/llvm/lib/CodeGen/CFGuardLongjmp.cpp b/llvm/lib/CodeGen/CFGuardLongjmp.cpp index 04de011400568..639d0537c2cc1 100644 --- a/llvm/lib/CodeGen/CFGuardLongjmp.cpp +++ b/llvm/lib/CodeGen/CFGuardLongjmp.cpp @@ -62,7 +62,8 @@ FunctionPass *llvm::createCFGuardLongjmpPass() { return new CFGuardLongjmp(); } bool CFGuardLongjmp::runOnMachineFunction(MachineFunction &MF) { // Skip modules for which the cfguard flag is not set. - if (!MF.getFunction().getParent()->getModuleFlag("cfguard")) + if (MF.getFunction().getParent()->getControlFlowGuardMode() == + ControlFlowGuardMode::Disabled) return false; // Skip functions that do not have calls to _setjmp. diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 7360d0fa1f86a..11dc68e0e4751 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -940,3 +940,10 @@ WinX64EHUnwindV2Mode Module::getWinX64EHUnwindV2Mode() const { return static_cast<WinX64EHUnwindV2Mode>(CI->getZExtValue()); return WinX64EHUnwindV2Mode::Disabled; } + +ControlFlowGuardMode Module::getControlFlowGuardMode() const { + Metadata *MD = getModuleFlag("cfguard"); + if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD)) + return static_cast<ControlFlowGuardMode>(CI->getZExtValue()); + return ControlFlowGuardMode::Disabled; +} diff --git a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp index d0c4b1b9f83fd..c27a693ceecc1 100644 --- a/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp @@ -75,7 +75,7 @@ class AArch64Arm64ECCallLowering : public ModulePass { bool runOnModule(Module &M) override; private: - int cfguard_module_flag = 0; + ControlFlowGuardMode CFGuardModuleFlag = ControlFlowGuardMode::Disabled; FunctionType *GuardFnType = nullptr; FunctionType *DispatchFnType = nullptr; Constant *GuardFnCFGlobal = nullptr; @@ -758,7 +758,8 @@ void AArch64Arm64ECCallLowering::lowerCall(CallBase *CB) { // Load the global symbol as a pointer to the check function. Value *GuardFn; - if (cfguard_module_flag == 2 && !CB->hasFnAttr("guard_nocf")) + if ((CFGuardModuleFlag == ControlFlowGuardMode::Enabled) && + !CB->hasFnAttr("guard_nocf")) GuardFn = GuardFnCFGlobal; else GuardFn = GuardFnGlobal; @@ -794,9 +795,7 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) { M = &Mod; // Check if this module has the cfguard flag and read its value. - if (auto *MD = - mdconst::extract_or_null<ConstantInt>(M->getModuleFlag("cfguard"))) - cfguard_module_flag = MD->getZExtValue(); + CFGuardModuleFlag = M->getControlFlowGuardMode(); PtrTy = PointerType::getUnqual(M->getContext()); I64Ty = Type::getInt64Ty(M->getContext()); diff --git a/llvm/lib/Transforms/CFGuard/CFGuard.cpp b/llvm/lib/Transforms/CFGuard/CFGuard.cpp index 5c2d9ddaa76db..28d0eddca7ce2 100644 --- a/llvm/lib/Transforms/CFGuard/CFGuard.cpp +++ b/llvm/lib/Transforms/CFGuard/CFGuard.cpp @@ -146,8 +146,8 @@ class CFGuardImpl { bool runOnFunction(Function &F); private: - // Only add checks if the module has the cfguard=2 flag. - int CFGuardModuleFlag = 0; + // Only add checks if the module has them enabled. + ControlFlowGuardMode CFGuardModuleFlag = ControlFlowGuardMode::Disabled; StringRef GuardFnName; Mechanism GuardMechanism = Mechanism::Check; FunctionType *GuardFnType = nullptr; @@ -233,12 +233,10 @@ void CFGuardImpl::insertCFGuardDispatch(CallBase *CB) { bool CFGuardImpl::doInitialization(Module &M) { // Check if this module has the cfguard flag and read its value. - if (auto *MD = - mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard"))) - CFGuardModuleFlag = MD->getZExtValue(); + CFGuardModuleFlag = M.getControlFlowGuardMode(); // Skip modules for which CFGuard checks have been disabled. - if (CFGuardModuleFlag != 2) + if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled) return false; // Set up prototypes for the guard check and dispatch functions. @@ -260,7 +258,7 @@ bool CFGuardImpl::doInitialization(Module &M) { bool CFGuardImpl::runOnFunction(Function &F) { // Skip modules for which CFGuard checks have been disabled. - if (CFGuardModuleFlag != 2) + if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled) return false; SmallVector<CallBase *, 8> IndirectCalls; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
