2006-06-19 Andrew Haley <aph@redhat.com>
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Jun 2006 17:38:08 +0000 (17:38 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Jun 2006 17:38:08 +0000 (17:38 +0000)
        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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114778 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/java/ChangeLog
gcc/java/expr.c
gcc/java/java-gimplify.c
gcc/java/java-tree.h

index b0c414f..45fd012 100644 (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
index cb3d506..329e363 100644 (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
index 21c0641..54900d3 100644 (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;
     }
index 7f483d4..98aca58 100644 (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);