Skip to content

Instantly share code, notes, and snippets.

@nikic
Created July 2, 2021 19:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/d1ce3f7a7488be786974e040648a65e0 to your computer and use it in GitHub Desktop.
Save nikic/d1ce3f7a7488be786974e040648a65e0 to your computer and use it in GitHub Desktop.
commit f377c520ee27e5e284a16597226a44095842c490
Author: Nikita Popov <nikita.ppv@gmail.com>
Date: Fri Jul 2 21:03:31 2021 +0200
Add AttributeSet::impliesNonNull()
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 50047e25f69d..f4ae08eb9053 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -338,6 +338,13 @@ public:
std::pair<unsigned, unsigned> getVScaleRangeArgs() const;
std::string getAsString(bool InAttrGrp = false) const;
+ /// Whether this attribute set implies that an argument is non-null.
+ /// NullPointerIsDefined determines whether the null pointer is
+ /// dereferenceable. If AllowPoison is true, then a null argument merely
+ /// results in poison. If it is false, a null argument results in undefined
+ /// behavior.
+ bool impliesNonNull(bool NullPointerIsDefined, bool AllowPoison) const;
+
/// Return true if this attribute set belongs to the LLVMContext.
bool hasParentContext(LLVMContext &C) const;
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 27b5835c8558..0a7aa115274a 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -863,6 +863,14 @@ std::string AttributeSet::getAsString(bool InAttrGrp) const {
return SetNode ? SetNode->getAsString(InAttrGrp) : "";
}
+bool AttributeSet::impliesNonNull(bool NullPointerIsDefined,
+ bool AllowPoison) const {
+ if (hasAttribute(Attribute::NonNull) &&
+ (AllowPoison || hasAttribute(Attribute::NoUndef)))
+ return true;
+ return getDereferenceableBytes() > 0 && !NullPointerIsDefined;
+}
+
bool AttributeSet::hasParentContext(LLVMContext &C) const {
assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
FoldingSetNodeID ID;
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index b502e5c48dbc..fd0b5edea372 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -96,15 +96,10 @@ void Argument::setParent(Function *parent) {
bool Argument::hasNonNullAttr(bool AllowUndefOrPoison) const {
if (!getType()->isPointerTy()) return false;
- if (getParent()->hasParamAttribute(getArgNo(), Attribute::NonNull) &&
- (AllowUndefOrPoison ||
- getParent()->hasParamAttribute(getArgNo(), Attribute::NoUndef)))
- return true;
- else if (getDereferenceableBytes() > 0 &&
- !NullPointerIsDefined(getParent(),
- getType()->getPointerAddressSpace()))
- return true;
- return false;
+ bool NullDefined = NullPointerIsDefined(getParent(),
+ getType()->getPointerAddressSpace());
+ return getParent()->getAttributes().getParamAttributes(getArgNo())
+ .impliesNonNull(NullDefined, AllowUndefOrPoison);
}
bool Argument::hasByValAttr() const {
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index bf88a6baccf0..be9d007db7fd 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -325,12 +325,14 @@ bool CallBase::isReturnNonNull() const {
bool CallBase::paramIsNonNull(unsigned ArgNo, bool AllowUndefOrPoison) const {
Type *ArgType = getArgOperand(ArgNo)->getType();
if (!ArgType->isPointerTy()) return false;
- if (paramHasAttr(ArgNo, Attribute::NonNull) &&
- (AllowUndefOrPoison || paramHasAttr(ArgNo, Attribute::NoUndef)))
- return true;
- if (getDereferenceableBytes(ArgNo) > 0 &&
- !NullPointerIsDefined(getFunction(), ArgType->getPointerAddressSpace()))
+ bool NullDefined = NullPointerIsDefined(getFunction(),
+ ArgType->getPointerAddressSpace());
+ if (Attrs.getParamAttributes(ArgNo)
+ .impliesNonNull(NullDefined, AllowUndefOrPoison))
return true;
+ if (const Function *F = getCalledFunction())
+ return F->getAttributes().getParamAttributes(ArgNo)
+ .impliesNonNull(NullDefined, AllowUndefOrPoison);
return false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment