Commit fe4e7c65 by Andrew Haley Committed by Andrew Haley

re PR java/1305 ([JSR133] GCJ ignores volatile modifier)

2006-06-19  Andrew Haley  <aph@redhat.com>

        PR java/1305
        PR java/27908
        * expr.c (java_modify_addr_for_volatile): New function.
        (expand_java_field_op): Handle volatile fields.
        * java-gimplify.c (java_gimplify_component_ref): Call
        java_modify_addr_for_volatile to give the field_ref the correct
        volatile type.
        (java_gimplify_modify_expr): Likewise.
        * java-tree.h (java_modify_addr_for_volatile): New decl.

From-SVN: r114778
parent 3c618f87
2006-06-19 Andrew Haley <aph@redhat.com>
PR java/1305
PR java/27908
* expr.c (java_modify_addr_for_volatile): New function.
(expand_java_field_op): Handle volatile fields.
* java-gimplify.c (java_gimplify_component_ref): Call
java_modify_addr_for_volatile to give the field_ref the correct
volatile type.
(java_gimplify_modify_expr): Likewise.
* java-tree.h (java_modify_addr_for_volatile): New decl.
2006-06-17 Karl Berry <karl@gnu.org> 2006-06-17 Karl Berry <karl@gnu.org>
* gcj.texi (@dircategory): Use "Software development" instead * gcj.texi (@dircategory): Use "Software development" instead
......
...@@ -2742,6 +2742,25 @@ build_jni_stub (tree method) ...@@ -2742,6 +2742,25 @@ build_jni_stub (tree method)
return bind; return bind;
} }
/* Given lvalue EXP, return a volatile expression that references the
same object. */
tree
java_modify_addr_for_volatile (tree exp)
{
tree exp_type = TREE_TYPE (exp);
tree v_type
= build_qualified_type (exp_type,
TYPE_QUALS (exp_type) | TYPE_QUAL_VOLATILE);
tree addr = build_fold_addr_expr (exp);
v_type = build_pointer_type (v_type);
addr = fold_convert (v_type, addr);
exp = build_fold_indirect_ref (addr);
return exp;
}
/* Expand an operation to extract from or store into a field. /* Expand an operation to extract from or store into a field.
IS_STATIC is 1 iff the field is static. IS_STATIC is 1 iff the field is static.
IS_PUTTING is 1 for putting into a field; 0 for getting from the field. IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
...@@ -2765,6 +2784,7 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index) ...@@ -2765,6 +2784,7 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
int is_error = 0; int is_error = 0;
tree original_self_type = self_type; tree original_self_type = self_type;
tree field_decl; tree field_decl;
tree modify_expr;
if (! CLASS_LOADED_P (self_type)) if (! CLASS_LOADED_P (self_type))
load_class (self_type, 1); load_class (self_type, 1);
...@@ -2785,6 +2805,13 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index) ...@@ -2785,6 +2805,13 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
field_type, flags); field_type, flags);
DECL_ARTIFICIAL (field_decl) = 1; DECL_ARTIFICIAL (field_decl) = 1;
DECL_IGNORED_P (field_decl) = 1; DECL_IGNORED_P (field_decl) = 1;
#if 0
/* FIXME: We should be pessimistic about volatility. We
don't know one way or another, but this is safe.
However, doing this has bad effects on code quality. We
need to look at better ways to do this. */
TREE_THIS_VOLATILE (field_decl) = 1;
#endif
} }
else else
{ {
...@@ -2835,12 +2862,45 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index) ...@@ -2835,12 +2862,45 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
warning (0, "assignment to final field %q+D not in constructor", warning (0, "assignment to final field %q+D not in constructor",
field_decl); field_decl);
} }
} }
java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (field_ref),
field_ref, new_value)); if (TREE_THIS_VOLATILE (field_decl))
field_ref = java_modify_addr_for_volatile (field_ref);
modify_expr = build2 (MODIFY_EXPR, TREE_TYPE (field_ref),
field_ref, new_value);
if (TREE_THIS_VOLATILE (field_decl))
java_add_stmt
(build3
(CALL_EXPR, void_type_node,
build_address_of (built_in_decls[BUILT_IN_SYNCHRONIZE]),
NULL_TREE, NULL_TREE));
java_add_stmt (modify_expr);
} }
else else
push_value (field_ref); {
tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (field_ref));
java_add_local_var (temp);
if (TREE_THIS_VOLATILE (field_decl))
field_ref = java_modify_addr_for_volatile (field_ref);
modify_expr
= build2 (MODIFY_EXPR, TREE_TYPE (field_ref), temp, field_ref);
java_add_stmt (modify_expr);
if (TREE_THIS_VOLATILE (field_decl))
java_add_stmt
(build3
(CALL_EXPR, void_type_node,
build_address_of (built_in_decls[BUILT_IN_SYNCHRONIZE]),
NULL_TREE, NULL_TREE));
push_value (temp);
}
TREE_THIS_VOLATILE (field_ref) = TREE_THIS_VOLATILE (field_decl);
} }
void void
......
...@@ -223,7 +223,8 @@ java_gimplify_exit_block_expr (tree expr) ...@@ -223,7 +223,8 @@ java_gimplify_exit_block_expr (tree expr)
static enum gimplify_status static enum gimplify_status
java_gimplify_component_ref (tree *expr_p, tree *pre_p, tree *post_p) java_gimplify_component_ref (tree *expr_p, tree *pre_p, tree *post_p)
{ {
if (TREE_THIS_VOLATILE (TREE_OPERAND (*expr_p, 1)) if (CLASS_FROM_SOURCE_P (output_class)
&& TREE_THIS_VOLATILE (TREE_OPERAND (*expr_p, 1))
&& ! TREE_THIS_VOLATILE (*expr_p)) && ! TREE_THIS_VOLATILE (*expr_p))
{ {
enum gimplify_status stat; enum gimplify_status stat;
...@@ -246,6 +247,7 @@ java_gimplify_component_ref (tree *expr_p, tree *pre_p, tree *post_p) ...@@ -246,6 +247,7 @@ java_gimplify_component_ref (tree *expr_p, tree *pre_p, tree *post_p)
*/ */
TREE_THIS_VOLATILE (*expr_p) = 1; TREE_THIS_VOLATILE (*expr_p) = 1;
*expr_p = java_modify_addr_for_volatile (*expr_p);
stat = gimplify_expr (expr_p, pre_p, post_p, stat = gimplify_expr (expr_p, pre_p, post_p,
is_gimple_formal_tmp_var, fb_rvalue); is_gimple_formal_tmp_var, fb_rvalue);
if (stat == GS_ERROR) if (stat == GS_ERROR)
...@@ -273,7 +275,8 @@ java_gimplify_modify_expr (tree *modify_expr_p, tree *pre_p, tree *post_p) ...@@ -273,7 +275,8 @@ java_gimplify_modify_expr (tree *modify_expr_p, tree *pre_p, tree *post_p)
tree rhs = TREE_OPERAND (modify_expr, 1); tree rhs = TREE_OPERAND (modify_expr, 1);
tree lhs_type = TREE_TYPE (lhs); tree lhs_type = TREE_TYPE (lhs);
if (TREE_CODE (lhs) == COMPONENT_REF if (CLASS_FROM_SOURCE_P (output_class)
&& TREE_CODE (lhs) == COMPONENT_REF
&& TREE_THIS_VOLATILE (TREE_OPERAND (lhs, 1))) && TREE_THIS_VOLATILE (TREE_OPERAND (lhs, 1)))
{ {
/* Special handling for volatile fields. /* Special handling for volatile fields.
...@@ -308,6 +311,7 @@ java_gimplify_modify_expr (tree *modify_expr_p, tree *pre_p, tree *post_p) ...@@ -308,6 +311,7 @@ java_gimplify_modify_expr (tree *modify_expr_p, tree *pre_p, tree *post_p)
sync_expr, rhs); sync_expr, rhs);
TREE_SIDE_EFFECTS (rhs) = 1; TREE_SIDE_EFFECTS (rhs) = 1;
TREE_THIS_VOLATILE (lhs) = 1; TREE_THIS_VOLATILE (lhs) = 1;
lhs = java_modify_addr_for_volatile (lhs);
TREE_OPERAND (modify_expr, 0) = lhs; TREE_OPERAND (modify_expr, 0) = lhs;
TREE_OPERAND (modify_expr, 1) = rhs; TREE_OPERAND (modify_expr, 1) = rhs;
} }
......
...@@ -1250,6 +1250,7 @@ extern tree build_invokeinterface (tree, tree); ...@@ -1250,6 +1250,7 @@ extern tree build_invokeinterface (tree, tree);
extern tree build_jni_stub (tree); extern tree build_jni_stub (tree);
extern tree invoke_build_dtable (int, tree); extern tree invoke_build_dtable (int, tree);
extern tree build_field_ref (tree, tree, tree); extern tree build_field_ref (tree, tree, tree);
extern tree java_modify_addr_for_volatile (tree);
extern void pushdecl_force_head (tree); extern void pushdecl_force_head (tree);
extern tree build_java_binop (enum tree_code, tree, tree, tree); extern tree build_java_binop (enum tree_code, tree, tree, tree);
extern tree build_java_soft_divmod (enum tree_code, tree, tree, tree); extern tree build_java_soft_divmod (enum tree_code, tree, tree, tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment