diff options
author | Andrew Haley <aph@redhat.com> | 2006-06-19 17:38:08 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2006-06-19 17:38:08 +0000 |
commit | fe4e7c6527eb4452c33a8df24e7d76b82ce1a18a (patch) | |
tree | 3b4b80cba4b272464d1b60f8d164c7cd515a34ef | |
parent | 3c618f8732814407a5c98146fa24761ba7dddd78 (diff) | |
download | gcc-fe4e7c6527eb4452c33a8df24e7d76b82ce1a18a.zip gcc-fe4e7c6527eb4452c33a8df24e7d76b82ce1a18a.tar.gz gcc-fe4e7c6527eb4452c33a8df24e7d76b82ce1a18a.tar.bz2 |
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
-rw-r--r-- | gcc/java/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/java/expr.c | 68 | ||||
-rw-r--r-- | gcc/java/java-gimplify.c | 8 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 1 |
4 files changed, 83 insertions, 6 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index b0c414f..45fd012 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -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 diff --git a/gcc/java/expr.c b/gcc/java/expr.c index cb3d506..329e363 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -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 diff --git a/gcc/java/java-gimplify.c b/gcc/java/java-gimplify.c index 21c0641..54900d3 100644 --- a/gcc/java/java-gimplify.c +++ b/gcc/java/java-gimplify.c @@ -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; } diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 7f483d4..98aca58 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -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); |