+ if (TREE_THIS_VOLATILE (TREE_OPERAND (*expr_p, 1))
+ && ! TREE_THIS_VOLATILE (*expr_p))
+ {
+ enum gimplify_status stat;
+ tree sync_expr;
+
+ /* Special handling for volatile fields.
+
+ A load has "acquire" semantics, implying that you can't move up
+ later operations. A store has "release" semantics meaning that
+ earlier operations cannot be delayed past it.
+
+ This logic only handles loads: stores are handled in
+ java_gimplify_modify_expr().
+
+ We gimplify this COMPONENT_REF, put the result in a tmp_var, and then
+ return a COMPOUND_EXPR of the form {__sync_synchronize(); tmp_var}.
+ This forces __sync_synchronize() to be placed immediately after
+ loading from the volatile field.
+
+ */
+
+ TREE_THIS_VOLATILE (*expr_p) = 1;
+ stat = gimplify_expr (expr_p, pre_p, post_p,
+ is_gimple_formal_tmp_var, fb_rvalue);
+ if (stat == GS_ERROR)
+ return stat;
+
+ sync_expr
+ = build3 (CALL_EXPR, void_type_node,
+ build_address_of (built_in_decls[BUILT_IN_SYNCHRONIZE]),
+ NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (sync_expr) = 1;
+ *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p),
+ sync_expr, *expr_p);
+ TREE_SIDE_EFFECTS (*expr_p) = 1;
+ }
+
+ return GS_UNHANDLED;
+}
+
+
+static enum gimplify_status
+java_gimplify_modify_expr (tree *modify_expr_p, tree *pre_p, tree *post_p)
+{
+ tree modify_expr = *modify_expr_p;