diff mbox series

[COMMITTED,29/31] ada: Fix internal error on discriminated record with Atomic aspect in Ada 2022

Message ID 20240521073035.314024-29-poulhies@adacore.com
State New
Headers show
Series [COMMITTED,01/31] ada: Add new Mingw task priority mapping | expand

Commit Message

Marc Poulhiès May 21, 2024, 7:30 a.m. UTC
From: Eric Botcazou <ebotcazou@adacore.com>

It occurs in build_load_modify_store where the pattern matching logic cannot
find the atomic load that is present in the tree because it has been wrapped
in a SAVE_EXPR by gnat_protect_expr, which is unnecessary.

gcc/ada/

	* gcc-interface/utils2.cc (gnat_protect_expr): Deal specifically
	with atomic loads. Document the relationship with gnat_save_expr.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/gcc-interface/utils2.cc | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc
index c1346cfadeb..8fb86ab29e3 100644
--- a/gcc/ada/gcc-interface/utils2.cc
+++ b/gcc/ada/gcc-interface/utils2.cc
@@ -2887,7 +2887,11 @@  gnat_save_expr (tree exp)
 
 /* Protect EXP for immediate reuse.  This is a variant of gnat_save_expr that
    is optimized under the assumption that EXP's value doesn't change before
-   its subsequent reuse(s) except through its potential reevaluation.  */
+   its subsequent reuse(s) except potentially through its reevaluation.
+
+   gnat_protect_expr guarantees that multiple evaluations of the expression
+   will not generate multiple side effects, whereas gnat_save_expr further
+   guarantees that all evaluations will yield the same result.  */
 
 tree
 gnat_protect_expr (tree exp)
@@ -2932,6 +2936,13 @@  gnat_protect_expr (tree exp)
     return build3 (code, type, gnat_protect_expr (TREE_OPERAND (exp, 0)),
 		   TREE_OPERAND (exp, 1), NULL_TREE);
 
+  /* An atomic load is an INDIRECT_REF of its first argument, so apply the
+     same transformation as in the INDIRECT_REF case above.  */
+  if (code == CALL_EXPR && call_is_atomic_load (exp))
+    return build_call_expr (TREE_OPERAND (CALL_EXPR_FN (exp), 0), 2,
+			    gnat_protect_expr (CALL_EXPR_ARG (exp, 0)),
+			    CALL_EXPR_ARG (exp, 1));
+
   /* If this is a COMPONENT_REF of a fat pointer, save the entire fat pointer.
      This may be more efficient, but will also allow us to more easily find
      the match for the PLACEHOLDER_EXPR.  */