On Thu, Nov 23, 2023 at 04:21:50PM +0100, Tobias Burnus wrote: > @@ -21663,7 +21666,25 @@ c_parser_omp_depobj (c_parser *parser) > clause = error_mark_node; > } > else if (!strcmp ("destroy", p)) > - kind = OMP_CLAUSE_DEPEND_LAST; > + { > + matching_parens c_parens; > + kind = OMP_CLAUSE_DEPEND_LAST; > + if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) > + && c_parens.require_open (parser)) > + { > + tree destobj = c_parser_expr_no_commas (parser, NULL).value; > + if (!lvalue_p (destobj)) > + error_at (EXPR_LOC_OR_LOC (destobj, c_loc), > + "%<destrory%> expression is not lvalue expression"); > + else if (depobj != error_mark_node > + && !operand_equal_p (destobj, depobj, > + OEP_MATCH_SIDE_EFFECTS))
There is also OEP_LEXICOGRAPHIC which could be used in addition to that. The question is if we want to consider say #pragma depobj (a[++i]) destroy (a[++i]) as same or different (similarly a[foo ()] in both cases). A function could at least in theory return the same value, for other side-effects there is some wiggle room in unspecified number of times how many the side-effects of clauses are evaluated (and for destroy we really don't intend to evaluate them at all for the clause, just for the directive argument). Jakub