[llvm] [llubi] Add support for poison-generating/UB-implying annotations (PR #195339)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sun May 3 03:46:37 PDT 2026
================
@@ -924,10 +1086,117 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
return AnyValue();
}
+ /// Handle both poison-generating and UB-implying attributes for parameters
+ /// and return values.
+ void handleAttributes(Type *Ty, AnyValue &V, AttributeSet AttrsAtCallSite,
+ AttributeSet AttrsAtCallee) {
+ if (Ty->isIntOrIntVectorTy()) {
+ if (auto CRAttr = AttrsAtCallSite.getAttribute(Attribute::Range);
+ CRAttr.isValid())
+ applyRangeAttr(V, CRAttr.getRange());
+ if (auto CRAttr = AttrsAtCallee.getAttribute(Attribute::Range);
+ CRAttr.isValid())
+ applyRangeAttr(V, CRAttr.getRange());
+ }
+ if (AttributeFuncs::isNoFPClassCompatibleType(Ty)) {
+ if (auto CRAttr = AttrsAtCallSite.getAttribute(Attribute::NoFPClass);
+ CRAttr.isValid())
+ applyNoFPClassAttr(V, CRAttr.getNoFPClass());
+ if (auto CRAttr = AttrsAtCallee.getAttribute(Attribute::NoFPClass);
+ CRAttr.isValid())
+ applyNoFPClassAttr(V, CRAttr.getNoFPClass());
+ }
+ if (Ty->isPointerTy()) {
+ if (AttrsAtCallSite.hasAttribute(Attribute::NonNull) ||
+ AttrsAtCallee.hasAttribute(Attribute::NonNull))
+ applyNonNullAttr(V);
+ }
+ if (Ty->isPtrOrPtrVectorTy()) {
+ if (MaybeAlign Align = AttrsAtCallSite.getAlignment())
+ applyAlignAttr(V, *Align);
+ if (MaybeAlign Align = AttrsAtCallee.getAlignment())
+ applyAlignAttr(V, *Align);
+ }
+ if ((AttrsAtCallSite.hasAttribute(Attribute::NoUndef) ||
+ AttrsAtCallee.hasAttribute(Attribute::NoUndef)) &&
+ applyNoUndefAttr(V)) {
+ reportImmediateUB() << "The value " << V
+ << " violates noundef attribute.";
+ return;
+ }
+ if (Ty->isPointerTy()) {
+ if (uint64_t DereferenceableBytes =
+ std::max(AttrsAtCallSite.getDereferenceableBytes(),
+ AttrsAtCallee.getDereferenceableBytes())) {
+ if (applyDereferenceableBytesAttr(V, DereferenceableBytes,
+ /*OrNull=*/false))
+ reportImmediateUB()
+ << "The value " << V << " violates dereferenceable("
+ << DereferenceableBytes << ") attribute.";
+ } else if (uint64_t DereferenceableOrNullBytes =
+ std::max(AttrsAtCallSite.getDereferenceableOrNullBytes(),
+ AttrsAtCallee.getDereferenceableOrNullBytes())) {
+ if (applyDereferenceableBytesAttr(V, DereferenceableOrNullBytes,
+ /*OrNull=*/true))
+ reportImmediateUB() << "The value " << V
+ << " violates "
+ "dereferenceable_or_null("
+ << DereferenceableOrNullBytes << ") attribute.";
+ }
+ }
+ }
+
+ /// Handle both poison-generating and UB-implying metadata on instructions.
+ void handleMetadata(Type *Ty, AnyValue &V, Instruction &I) {
+ auto ExtractFirstIntOperand = [](const MDNode *Node) {
+ return mdconst::extract<ConstantInt>(Node->getOperand(0))->getZExtValue();
+ };
+
+ if (Ty->isIntOrIntVectorTy()) {
+ if (MDNode *Ranges = I.getMetadata(LLVMContext::MD_range))
+ applyRangeAttr(V, getConstantRangeFromMetadata(*Ranges));
----------------
nikic wrote:
FIXME: Don't approximate with ConstantRange, check individual range pairs.
https://github.com/llvm/llvm-project/pull/195339
More information about the llvm-commits
mailing list