PR java/1305: [JSR133] GCJ ignores volatile modifier
Andrew Haley
aph@redhat.com
Mon Jun 19 16:49:00 GMT 2006
Same again, this time for compiling from .class files.
Also, there were some type mismatches in my orginal patch that I've
fixed.
Andrew.
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.
Index: gcc/java/java-gimplify.c
===================================================================
--- gcc/java/java-gimplify.c (revision 114772)
+++ gcc/java/java-gimplify.c (working copy)
@@ -223,7 +223,8 @@
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 @@
*/
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 @@
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 @@
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;
}
Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c (revision 114772)
+++ gcc/java/expr.c (working copy)
@@ -2742,6 +2742,25 @@
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 @@
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 @@
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,47 @@
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;
+
+ 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
Index: gcc/java/java-tree.h
===================================================================
--- gcc/java/java-tree.h (revision 114772)
+++ gcc/java/java-tree.h (working copy)
@@ -1250,6 +1250,7 @@
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);
More information about the Gcc-patches
mailing list