Author: Pavel Skripkin Date: 2024-07-29T18:43:50+02:00 New Revision: 150bf637baad2ba4df6369600b65d897ed9b31a7
URL: https://github.com/llvm/llvm-project/commit/150bf637baad2ba4df6369600b65d897ed9b31a7 DIFF: https://github.com/llvm/llvm-project/commit/150bf637baad2ba4df6369600b65d897ed9b31a7.diff LOG: [Clang][Sema] Disallow applying `onwership_returns` to functions that return non-pointers (#99564) `onwership_returns` works only with pointers, since it models user-defined memory allocation functions. Make semantics more clear and report an error if attribute is attached to wrong function. Closes #99501 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDeclAttr.cpp clang/test/AST/attr-print-emit.cpp clang/test/Sema/attr-ownership.c clang/test/Sema/attr-ownership.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 92f0a44c5ad72..dad44f45a847f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -273,6 +273,10 @@ Crash and bug fixes Improvements ^^^^^^^^^^^^ +- Improved the handling of the ``ownership_returns`` attribute. Now, Clang reports an + error if the attribute is attached to a function that returns a non-pointer value. + Fixes (#GH99501) + Moved checkers ^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9e6d85c469d64..581434d33c5c9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3330,6 +3330,8 @@ 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_takes_return_type : Error< + "'ownership_returns' attribute only applies to functions that return a pointer">; 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< diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 003d7a24f0150..98e3df9083516 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1481,6 +1481,14 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) { break; } + // Allow only pointers to be return type for functions with ownership_returns + // attribute. This matches with current OwnershipAttr::Takes semantics + if (K == OwnershipAttr::Returns && + !getFunctionOrMethodResultType(D)->isPointerType()) { + S.Diag(AL.getLoc(), diag::err_ownership_takes_return_type) << AL; + return; + } + IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident; StringRef ModuleName = Module->getName(); diff --git a/clang/test/AST/attr-print-emit.cpp b/clang/test/AST/attr-print-emit.cpp index 8c8a2b2080599..d8e62ed5f6cd1 100644 --- a/clang/test/AST/attr-print-emit.cpp +++ b/clang/test/AST/attr-print-emit.cpp @@ -32,8 +32,8 @@ int *aa(int i) __attribute__((alloc_align(1))); void ownt(int *, int *) __attribute__((ownership_takes(foo, 1, 2))); // CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2))); void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2))); -// CHECK: void ownr(int) __attribute__((ownership_returns(foo, 1))); -void ownr(int) __attribute__((ownership_returns(foo, 1))); +// CHECK: void *ownr(int) __attribute__((ownership_returns(foo, 1))); +void *ownr(int) __attribute__((ownership_returns(foo, 1))); // CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2))); void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2))); @@ -65,8 +65,8 @@ class C { void ownt(int *, int *) __attribute__((ownership_takes(foo, 2, 3))); // CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3))); void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3))); - // CHECK: void ownr(int) __attribute__((ownership_returns(foo, 2))); - void ownr(int) __attribute__((ownership_returns(foo, 2))); + // CHECK: void *ownr(int) __attribute__((ownership_returns(foo, 2))); + void *ownr(int) __attribute__((ownership_returns(foo, 2))); // CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3))); void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3))); diff --git a/clang/test/Sema/attr-ownership.c b/clang/test/Sema/attr-ownership.c index 084624353315c..d2e40538a40f0 100644 --- a/clang/test/Sema/attr-ownership.c +++ b/clang/test/Sema/attr-ownership.c @@ -18,7 +18,7 @@ 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_takes' and 'ownership_holds' attributes are not compatible}} -void f15(int, int) +void *f15(int, int) __attribute__((ownership_returns(foo, 1))) // expected-error {{'ownership_returns' attribute index does not match; here it is 1}} __attribute__((ownership_returns(foo, 2))); // expected-note {{declared with index 2 here}} void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_holds(foo, 1))); // OK, same index @@ -28,3 +28,6 @@ void f18() __attribute__((ownership_takes(foo, 1))); // expected-warning {{'own int f19(void *) __attribute__((ownership_takes(foo, 1))) // expected-error {{'ownership_takes' attribute class does not match; here it is 'foo'}} __attribute__((ownership_takes(foo1, 1))); // expected-note {{declared with class 'foo1' here}} + +void f20(void) __attribute__((ownership_returns(foo))); // expected-error {{'ownership_returns' attribute only applies to functions that return a pointer}} +int f21(void) __attribute__((ownership_returns(foo))); // expected-error {{'ownership_returns' attribute only applies to functions that return a pointer}} diff --git a/clang/test/Sema/attr-ownership.cpp b/clang/test/Sema/attr-ownership.cpp index 7381285e2da48..0626efa5aaf9a 100644 --- a/clang/test/Sema/attr-ownership.cpp +++ b/clang/test/Sema/attr-ownership.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only class C { - void f(int, int) - __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}} - __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}} + void *f(int, int) + __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}} + __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}} }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits