aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2006-06-19 17:38:08 +0000
committerAndrew Haley <aph@gcc.gnu.org>2006-06-19 17:38:08 +0000
commitfe4e7c6527eb4452c33a8df24e7d76b82ce1a18a (patch)
tree3b4b80cba4b272464d1b60f8d164c7cd515a34ef
parent3c618f8732814407a5c98146fa24761ba7dddd78 (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/java/expr.c68
-rw-r--r--gcc/java/java-gimplify.c8
-rw-r--r--gcc/java/java-tree.h1
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);