-
Notifications
You must be signed in to change notification settings - Fork 341
🍒[Clang] Permit noescape on non-pointer types #10735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1231,37 +1231,11 @@ static void handleNoSpecializations(Sema &S, Decl *D, const ParsedAttr &AL) { | |
NoSpecializationsAttr::Create(S.Context, Message, AL)); | ||
} | ||
|
||
bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) { | ||
if (T->isDependentType()) | ||
return true; | ||
if (RefOkay) { | ||
if (T->isReferenceType()) | ||
return true; | ||
} else { | ||
T = T.getNonReferenceType(); | ||
} | ||
|
||
// The nonnull attribute, and other similar attributes, can be applied to a | ||
// transparent union that contains a pointer type. | ||
if (const RecordType *UT = T->getAsUnionType()) { | ||
if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) { | ||
RecordDecl *UD = UT->getDecl(); | ||
for (const auto *I : UD->fields()) { | ||
QualType QT = I->getType(); | ||
if (QT->isAnyPointerType() || QT->isBlockPointerType()) | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return T->isAnyPointerType() || T->isBlockPointerType(); | ||
} | ||
|
||
static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL, | ||
SourceRange AttrParmRange, | ||
SourceRange TypeRange, | ||
bool isReturnValue = false) { | ||
if (!S.isValidPointerAttrType(T)) { | ||
if (!isValidPointerAttrType(T)) { | ||
if (isReturnValue) | ||
S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) | ||
<< AL << AttrParmRange << TypeRange; | ||
|
@@ -1312,7 +1286,7 @@ static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |
for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); | ||
I != E && !AnyPointers; ++I) { | ||
QualType T = getFunctionOrMethodParamType(D, I); | ||
if (T->isDependentType() || S.isValidPointerAttrType(T)) { | ||
if (T->isDependentType() || isValidPointerAttrType(T)) { | ||
AnyPointers = true; | ||
/*TO_UPSTREAM(BoundsSafety) ON*/ | ||
if (auto DCPTy = T->getAs<CountAttributedType>()) { | ||
|
@@ -1371,10 +1345,11 @@ static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { | |
if (D->isInvalidDecl()) | ||
return; | ||
|
||
// noescape only applies to pointer types. | ||
// noescape only applies to pointer and record types. | ||
QualType T = cast<ParmVarDecl>(D)->getType(); | ||
if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) { | ||
S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only) | ||
if (!isValidPointerAttrType(T, /* RefOkay */ true) && !T->isRecordType()) { | ||
S.Diag(AL.getLoc(), | ||
diag::warn_attribute_pointer_or_reference_or_record_only) | ||
<< AL << AL.getRange() << 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is where the 0 comes from in the diagnostic. The previous diagnostic looks like this:
So we likely want to do something like |
||
return; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,5 +3,11 @@ | |
template<typename T> | ||
void test1(T __attribute__((noescape)) arr, int size); | ||
|
||
// expected-warning@+1 {{'noescape' attribute only applies to pointer arguments}} | ||
void test2(int __attribute__((noescape)) arr, int size); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing this is also the case in the original patch, but this diagnostic looks off to me. CC @Xazax-hun There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that we could improve the phrasing. Let's wait until @Xazax-hun can work on it – this PR is just making the rebranch CI happy. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I just re-read your comment again, and I now agree we should fix the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Patch up: #10747 |
||
void test2(int __attribute__((noescape)) a, int b); // expected-warning {{'noescape' attribute only applies to a pointer, reference, class, struct, or union (0 is invalid)}} | ||
|
||
struct S { int *p; }; | ||
void test3(S __attribute__((noescape)) s); | ||
|
||
#if !__has_feature(attribute_noescape_nonpointer) | ||
#error "attribute_noescape_nonpointer should be supported" | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should some of the changes like this also go to upstream clang as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeap, I think so! Gabor already started the upstreaming work in llvm#117344.