[PATCH] D100676: [nofree] Attempt to further refine concurrency/capture requirements

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 16 11:55:43 PDT 2021


reames created this revision.
reames added reviewers: jdoerfert, nlopes, nhaehnle.
Herald added a subscriber: mcrosier.
Herald added a reviewer: bollu.
reames requested review of this revision.
Herald added a project: LLVM.

Triggered by discussion on https://reviews.llvm.org/D100141.

Key changes:

1. Reorder and use consistent wording to indicate what is specification, and what is discussion.
2. Add the requirement for a nocapture parameter to the deref discussion.  Without it, the old wording left it unclear whether the callee could capture a pointer, and then arrange for another thread to free it, while still being nofree.  (I think the answer must be yes, as otherwise, we have to prove nocapture to prove nofree.)

One gap I still see - and don't have a great suggestion on how to fix - is whether a nofree function is allowed to free an object allocated by a different thread *after* the start of execution of 'f'.  I think the answer should probably be no, I'm just not sure how to specify that in the wording.

Note that we don't currently implement the discussed deref rule, so there's no code to match this against or fix.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100676

Files:
  llvm/docs/LangRef.rst


Index: llvm/docs/LangRef.rst
===================================================================
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -1601,18 +1601,25 @@
     transitively, call a memory-deallocation function (``free``, for example)
     on a memory allocation which existed before the call.
 
-    As a result, uncaptured pointers that are known to be dereferenceable
-    prior to a call to a function with the ``nofree`` attribute are still
-    known to be dereferenceable after the call. The capturing condition is
-    necessary in environments where the function might communicate the
-    pointer to another thread which then deallocates the memory.  Alternatively,
-    ``nosync`` would ensure such communication cannot happen and even captured
-    pointers cannot be freed by the function.
-
-    A ``nofree`` function is explicitly allowed to free memory which it
-    allocated or (if not ``nosync``) arrange for another thread to free
-    memory on it's behalf.  As a result, perhaps surprisingly, a ``nofree``
-    function can return a pointer to a previously deallocated memory object.
+    A ``nofree`` function is explicitly allowed to free memory which it (or a
+    transitive callee) allocated or (if not ``nosync``) arrange for another
+    thread to free memory on its behalf.
+
+    As a result, perhaps surprisingly, a ``nofree`` function can return a
+    pointer to a previously deallocated memory object.
+
+    As a result, any pointers passed to a call to a function with the ``nofree``
+    attribute which is all of
+    a) uncaptured prior to the call,
+    b) known not to be captured by the call (e.g. only passed to ``nocapture``
+       parameters), and
+    c) known to be dereferenceable prior to a call to a function with
+    are still known to be dereferenceable after the call.
+    The capturing conditions are necessary in environments where the
+    function might communicate the pointer to another thread which then
+    deallocates the memory.  Alternatively, ``nosync`` would ensure such
+    communication cannot happen in a well defined program and even captured
+    pointers cannot be freed or arranged to be freed by the function.
 ``noimplicitfloat``
     This attributes disables implicit floating-point instructions.
 ``noinline``


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100676.338191.patch
Type: text/x-patch
Size: 2310 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210416/9e1bc190/attachment.bin>


More information about the llvm-commits mailing list