From: Aaron Ballman Date: Thu, 31 Jul 2014 20:44:26 +0000 (+0000) Subject: Implemented a diagnostic to handle multiple, distinct ownership_return attributes... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e3faa8fffecf47d58aee102668c46d7b70038e6e;p=clang Implemented a diagnostic to handle multiple, distinct ownership_return attributes on the same declaration. This removes a FIXME from the code. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@214436 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 87032b8a5c..24145317c9 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index b7ca9924ef..ff4192e91d 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -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()) { - // 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); diff --git a/test/Sema/attr-ownership.c b/test/Sema/attr-ownership.c index 2aa9f9f27c..d2e48c65a2 100644 --- a/test/Sema/attr-ownership.c +++ b/test/Sema/attr-ownership.c @@ -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