[libc++] Avoid creating temporaries in unary expressions involving valarray

Currently, unary expressions involving valarray will create a temporary.
This leads to dangling references in expressions like `-a * b`, because
`-a` is a temporary and the resulting expression will refer to it. This
patch fixes the problem by creating a lazy expression to perform the unary
operation instead of eagerly creating a temporary valarray. This is
permitted by the Standard, which does not specify the exact type of
most expressions involving valarrays.

This is technically an ABI break, however I believe the actual potential
for breakage is very low.

rdar://90152242

Differential Revision: https://reviews.llvm.org/D125019

NOKEYCHECK=True
GitOrigin-RevId: b8f6f9e741c60a06cbe14adf890db0889b3b333f
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index f6bca74..c2a43a6 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -122,6 +122,17 @@
   token used when constructing a ``std::random_device`` will now be ignored instead of
   interpreted as a file to read entropy from.
 
+- ``std::valarray``'s unary operators ``!``, ``+``, ``~`` and ``-`` now return an expression
+  object instead of a ``valarray``. This was done to fix an issue where any expression involving
+  other ``valarray`` operators and one of these unary operators would end up with a dangling
+  reference. This is a potential ABI break for code that exposes ``std::valarray`` on an ABI
+  boundary, specifically if the return type of an ABI-boundary function is ``auto``-deduced
+  from an expression involving unary operators on ``valarray``. If you are concerned by this,
+  you can audit whether your executable or library exports any function that returns a
+  ``valarray``, and if so ensure that any such function uses ``std::valarray`` directly
+  as a return type instead of relying on the type of ``valarray``-expressions, which is
+  not guaranteed by the Standard anyway.
+
 Build System Changes
 --------------------