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``