-
-
Save nikic/d1ce3f7a7488be786974e040648a65e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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