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
This commit is contained in:
Andrew Haley 2006-06-19 17:38:08 +00:00 committed by Andrew Haley
parent 3c618f8732
commit fe4e7c6527
4 changed files with 83 additions and 6 deletions

View File

@ -1,3 +1,15 @@
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>
* gcj.texi (@dircategory): Use "Software development" instead

View File

@ -2742,6 +2742,25 @@ build_jni_stub (tree method)
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.
IS_STATIC is 1 iff the field is static.
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)
int is_error = 0;
tree original_self_type = self_type;
tree field_decl;
tree modify_expr;
if (! CLASS_LOADED_P (self_type))
load_class (self_type, 1);
@ -2785,6 +2805,13 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
field_type, flags);
DECL_ARTIFICIAL (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
{
@ -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",
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
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

View File

@ -223,7 +223,8 @@ java_gimplify_exit_block_expr (tree expr)
static enum gimplify_status
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))
{
enum gimplify_status stat;
@ -246,6 +247,7 @@ java_gimplify_component_ref (tree *expr_p, tree *pre_p, tree *post_p)
*/
TREE_THIS_VOLATILE (*expr_p) = 1;
*expr_p = java_modify_addr_for_volatile (*expr_p);
stat = gimplify_expr (expr_p, pre_p, post_p,
is_gimple_formal_tmp_var, fb_rvalue);
if (stat == GS_ERROR)
@ -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 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)))
{
/* Special handling for volatile fields.
@ -308,6 +311,7 @@ java_gimplify_modify_expr (tree *modify_expr_p, tree *pre_p, tree *post_p)
sync_expr, rhs);
TREE_SIDE_EFFECTS (rhs) = 1;
TREE_THIS_VOLATILE (lhs) = 1;
lhs = java_modify_addr_for_volatile (lhs);
TREE_OPERAND (modify_expr, 0) = lhs;
TREE_OPERAND (modify_expr, 1) = rhs;
}

View File

@ -1250,6 +1250,7 @@ extern tree build_invokeinterface (tree, tree);
extern tree build_jni_stub (tree);
extern tree invoke_build_dtable (int, tree);
extern tree build_field_ref (tree, tree, tree);
extern tree java_modify_addr_for_volatile (tree);
extern void pushdecl_force_head (tree);
extern tree build_java_binop (enum tree_code, tree, tree, tree);
extern tree build_java_soft_divmod (enum tree_code, tree, tree, tree);