forked from OSchip/llvm-project
Implemented a diagnostic to handle multiple, distinct ownership_return attributes on the same declaration. This removes a FIXME from the code.
llvm-svn: 214436
This commit is contained in:
parent
914efc7239
commit
ef7aef8fe5
|
@ -1949,6 +1949,10 @@ def err_attribute_invalid_implicit_this_argument : Error<
|
|||
"%0 attribute is invalid for the implicit this argument">;
|
||||
def err_ownership_type : Error<
|
||||
"%0 attribute only applies to %select{pointer|integer}1 arguments">;
|
||||
def err_ownership_returns_index_mismatch : Error<
|
||||
"'ownership_returns' attribute index does not match; here it is %0">;
|
||||
def note_ownership_returns_index_mismatch : Note<
|
||||
"declared with index %0 here">;
|
||||
def err_format_strftime_third_parameter : Error<
|
||||
"strftime format attribute requires 3rd parameter to be 0">;
|
||||
def err_format_attribute_requires_variadic : Error<
|
||||
|
|
|
@ -1292,13 +1292,26 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
|
|||
|
||||
// Check we don't have a conflict with another ownership attribute.
|
||||
for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
|
||||
// FIXME: A returns attribute should conflict with any returns attribute
|
||||
// with a different index too.
|
||||
// Cannot have two ownership attributes of different kinds for the same
|
||||
// index.
|
||||
if (I->getOwnKind() != K && I->args_end() !=
|
||||
std::find(I->args_begin(), I->args_end(), Idx)) {
|
||||
S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
|
||||
<< AL.getName() << I;
|
||||
return;
|
||||
} else if (K == OwnershipAttr::Returns &&
|
||||
I->getOwnKind() == OwnershipAttr::Returns) {
|
||||
// A returns attribute conflicts with any other returns attribute using
|
||||
// a different index. Note, diagnostic reporting is 1-based, but stored
|
||||
// argument indexes are 0-based.
|
||||
if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) {
|
||||
S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
|
||||
<< *(I->args_begin()) + 1;
|
||||
if (I->args_size())
|
||||
S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
|
||||
<< (unsigned)Idx + 1 << Ex->getSourceRange();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
OwnershipArgs.push_back(Idx);
|
||||
|
|
|
@ -17,3 +17,8 @@ void *f12(float i, int k, int f, int *j) __attribute__((ownership_returns(foo, 4
|
|||
|
||||
void f13(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_takes(foo, 2)));
|
||||
void f14(int i, int j, int *k) __attribute__((ownership_holds(foo, 3))) __attribute__((ownership_takes(foo, 3))); // expected-error {{'ownership_holds' and 'ownership_takes' attributes are not compatible}}
|
||||
|
||||
void f15(int, int)
|
||||
__attribute__((ownership_returns(foo, 1))) // expected-note {{declared with index 1 here}}
|
||||
__attribute__((ownership_returns(foo, 2))); // expected-error {{'ownership_returns' attribute index does not match; here it is 2}}
|
||||
void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_holds(foo, 1))); // OK, same index
|
||||
|
|
Loading…
Reference in New Issue