aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2024-03-28 00:02:11 +0100
committerMarc Poulhiès <poulhies@adacore.com>2024-05-21 09:27:57 +0200
commitbf69349b8d974ff2a2518976e69724d21aa1f423 (patch)
treeb9b8e71fe4e2d73cf8862f957f234a4a6444a6fb
parentccdef2aef6463159a596ef1a4afe6ddce9d0f2ea (diff)
downloadgcc-bf69349b8d974ff2a2518976e69724d21aa1f423.zip
gcc-bf69349b8d974ff2a2518976e69724d21aa1f423.tar.gz
gcc-bf69349b8d974ff2a2518976e69724d21aa1f423.tar.bz2
ada: Fix internal error on discriminated record with Atomic aspect in Ada 2022
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.
-rw-r--r--gcc/ada/gcc-interface/utils2.cc13
1 files changed, 12 insertions, 1 deletions
diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc
index c1346cf..8fb86ab 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. */