Index: gcc/java/java-tree.h =================================================================== *** gcc/java/java-tree.h (revision 121818) --- gcc/java/java-tree.h (working copy) *************** extern tree *type_map; *** 1626,1645 **** #define BUILD_MONITOR_ENTER(WHERE, ARG) \ { \ ! (WHERE) = build3 (CALL_EXPR, int_type_node, \ ! build_address_of (soft_monitorenter_node), \ ! build_tree_list (NULL_TREE, (ARG)), \ ! NULL_TREE); \ TREE_SIDE_EFFECTS (WHERE) = 1; \ } ! #define BUILD_MONITOR_EXIT(WHERE, ARG) \ ! { \ ! (WHERE) = build3 (CALL_EXPR, int_type_node, \ ! build_address_of (soft_monitorexit_node), \ ! build_tree_list (NULL_TREE, (ARG)), \ ! NULL_TREE); \ ! TREE_SIDE_EFFECTS (WHERE) = 1; \ } /* True when we can perform static class initialization optimization */ --- 1626,1643 ---- #define BUILD_MONITOR_ENTER(WHERE, ARG) \ { \ ! (WHERE) = build_call_nary (int_type_node, \ ! build_address_of (soft_monitorenter_node), \ ! 1, (ARG)); \ TREE_SIDE_EFFECTS (WHERE) = 1; \ } ! #define BUILD_MONITOR_EXIT(WHERE, ARG) \ ! { \ ! (WHERE) = build_call_nary (int_type_node, \ ! build_address_of (soft_monitorexit_node), \ ! 1, (ARG)); \ ! TREE_SIDE_EFFECTS (WHERE) = 1; \ } /* True when we can perform static class initialization optimization */ Index: gcc/java/java-gimplify.c =================================================================== *** gcc/java/java-gimplify.c (revision 121818) --- gcc/java/java-gimplify.c (working copy) *************** java_gimplify_component_ref (tree *expr_ *** 212,221 **** if (stat == GS_ERROR) return stat; ! sync_expr ! = build3 (CALL_EXPR, void_type_node, ! build_address_of (built_in_decls[BUILT_IN_SYNCHRONIZE]), ! NULL_TREE, NULL_TREE); TREE_SIDE_EFFECTS (sync_expr) = 1; *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), sync_expr, *expr_p); --- 212,218 ---- if (stat == GS_ERROR) return stat; ! sync_expr = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0); TREE_SIDE_EFFECTS (sync_expr) = 1; *expr_p = build2 (COMPOUND_EXPR, TREE_TYPE (*expr_p), sync_expr, *expr_p); *************** java_gimplify_modify_expr (tree *modify_ *** 255,264 **** */ enum gimplify_status stat; ! tree sync_expr ! = build3 (CALL_EXPR, void_type_node, ! build_address_of (built_in_decls[BUILT_IN_SYNCHRONIZE]), ! NULL_TREE, NULL_TREE); TREE_SIDE_EFFECTS (sync_expr) = 1; stat = gimplify_expr (&rhs, pre_p, post_p, --- 252,259 ---- */ enum gimplify_status stat; ! tree sync_expr = ! build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0); TREE_SIDE_EFFECTS (sync_expr) = 1; stat = gimplify_expr (&rhs, pre_p, post_p, Index: gcc/java/class.c =================================================================== *** gcc/java/class.c (revision 121818) --- gcc/java/class.c (working copy) *************** cache_this_class_ref (tree fndecl) *** 1039,1048 **** && ! DECL_CLINIT_P (fndecl) && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl)))) { ! tree init = build3 (CALL_EXPR, void_type_node, ! build_address_of (soft_initclass_node), ! build_tree_list (NULL_TREE, this_classdollar), ! NULL_TREE); java_add_stmt (init); } } --- 1039,1046 ---- && ! DECL_CLINIT_P (fndecl) && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl)))) { ! tree init = build_call_expr (soft_initclass_node, 1, ! this_classdollar); java_add_stmt (init); } } *************** build_static_field_ref (tree fdecl) *** 1177,1196 **** int cpool_index = alloc_constant_fieldref (output_class, fdecl); tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl); ! tree test ! = build3 (CALL_EXPR, boolean_type_node, ! build_address_of (built_in_decls[BUILT_IN_EXPECT]), ! tree_cons (NULL_TREE, build2 (EQ_EXPR, boolean_type_node, ! cache_entry, null_pointer_node), ! build_tree_list (NULL_TREE, boolean_false_node)), ! NULL_TREE); tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index); tree init ! = build3 (CALL_EXPR, ptr_type_node, ! build_address_of (soft_resolvepoolentry_node), ! tree_cons (NULL_TREE, build_class_ref (output_class), ! build_tree_list (NULL_TREE, cpool_index_cst)), ! NULL_TREE); init = build2 (MODIFY_EXPR, ptr_type_node, cache_entry, init); init = build3 (COND_EXPR, ptr_type_node, test, init, cache_entry); init = fold_convert (build_pointer_type (TREE_TYPE (fdecl)), init); --- 1175,1190 ---- int cpool_index = alloc_constant_fieldref (output_class, fdecl); tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl); ! tree test ! = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, ! build2 (EQ_EXPR, boolean_type_node, ! cache_entry, null_pointer_node), ! boolean_false_node); tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index); tree init ! = build_call_expr (soft_resolvepoolentry_node, 2, ! build_class_ref (output_class), ! cpool_index_cst); init = build2 (MODIFY_EXPR, ptr_type_node, cache_entry, init); init = build3 (COND_EXPR, ptr_type_node, test, init, cache_entry); init = fold_convert (build_pointer_type (TREE_TYPE (fdecl)), init); *************** emit_indirect_register_classes (tree *li *** 2693,2700 **** TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; register_class_fn = t; ! t = tree_cons (NULL, reg_class_list, NULL); ! t = build_function_call_expr (register_class_fn, t); append_to_statement_list (t, list_p); } --- 2687,2693 ---- TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; register_class_fn = t; ! t = build_call_expr (register_class_fn, 1, reg_class_list); append_to_statement_list (t, list_p); } *************** emit_register_classes (tree *list_p) *** 2759,2766 **** for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i) { t = build_fold_addr_expr (klass); ! t = tree_cons (NULL, t, NULL); ! t = build_function_call_expr (register_class_fn, t); append_to_statement_list (t, list_p); } } --- 2752,2758 ---- for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i) { t = build_fold_addr_expr (klass); ! t = build_call_expr (register_class_fn, 1, t); append_to_statement_list (t, list_p); } } Index: gcc/java/resource.c =================================================================== *** gcc/java/resource.c (revision 121818) --- gcc/java/resource.c (working copy) *************** write_resource_constructor (tree *list_p *** 116,123 **** for (iter = nreverse (resources); iter ; iter = TREE_CHAIN (iter)) { t = build_fold_addr_expr (TREE_VALUE (iter)); ! t = tree_cons (NULL, t, NULL); ! t = build_function_call_expr (register_resource_fn, t); append_to_statement_list (t, list_p); } } --- 116,122 ---- for (iter = nreverse (resources); iter ; iter = TREE_CHAIN (iter)) { t = build_fold_addr_expr (TREE_VALUE (iter)); ! t = build_call_expr (register_resource_fn, 1, t); append_to_statement_list (t, list_p); } } Index: gcc/java/builtins.c =================================================================== *** gcc/java/builtins.c (revision 121818) --- gcc/java/builtins.c (working copy) *************** static tree VMSupportsCS8_builtin (tree, *** 60,66 **** /* Functions of this type are used to inline a given call. Such a function should either return an expression, if the call is to be inlined, or NULL_TREE if a real call should be emitted. Arguments ! are method return type and arguments to call. */ typedef tree builtin_creator_function (tree, tree); /* Hold a char*, before initialization, or a tree, after --- 60,67 ---- /* Functions of this type are used to inline a given call. Such a function should either return an expression, if the call is to be inlined, or NULL_TREE if a real call should be emitted. Arguments ! are method return type and the original CALL_EXPR containing the ! arguments to the call. */ typedef tree builtin_creator_function (tree, tree); /* Hold a char*, before initialization, or a tree, after *************** static GTY(()) struct builtin_record jav *** 130,179 **** /* Internal functions which implement various builtin conversions. */ static tree ! max_builtin (tree method_return_type, tree method_arguments) { /* MAX_EXPR does not handle -0.0 in the Java style. */ if (TREE_CODE (method_return_type) == REAL_TYPE) return NULL_TREE; return fold_build2 (MAX_EXPR, method_return_type, ! TREE_VALUE (method_arguments), ! TREE_VALUE (TREE_CHAIN (method_arguments))); } static tree ! min_builtin (tree method_return_type, tree method_arguments) { /* MIN_EXPR does not handle -0.0 in the Java style. */ if (TREE_CODE (method_return_type) == REAL_TYPE) return NULL_TREE; return fold_build2 (MIN_EXPR, method_return_type, ! TREE_VALUE (method_arguments), ! TREE_VALUE (TREE_CHAIN (method_arguments))); } static tree ! abs_builtin (tree method_return_type, tree method_arguments) { return fold_build1 (ABS_EXPR, method_return_type, ! TREE_VALUE (method_arguments)); } ! /* Mostly copied from ../builtins.c. */ static tree ! java_build_function_call_expr (tree fn, tree arglist) { ! tree call_expr; ! ! call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); ! return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), ! call_expr, arglist, NULL_TREE); } static tree ! convert_real (tree method_return_type, tree method_arguments) { return build1 (VIEW_CONVERT_EXPR, method_return_type, ! TREE_VALUE (method_arguments)); } --- 131,203 ---- /* Internal functions which implement various builtin conversions. */ static tree ! max_builtin (tree method_return_type, tree orig_call) { /* MAX_EXPR does not handle -0.0 in the Java style. */ if (TREE_CODE (method_return_type) == REAL_TYPE) return NULL_TREE; return fold_build2 (MAX_EXPR, method_return_type, ! CALL_EXPR_ARG (orig_call, 0), ! CALL_EXPR_ARG (orig_call, 1)); } static tree ! min_builtin (tree method_return_type, tree orig_call) { /* MIN_EXPR does not handle -0.0 in the Java style. */ if (TREE_CODE (method_return_type) == REAL_TYPE) return NULL_TREE; return fold_build2 (MIN_EXPR, method_return_type, ! CALL_EXPR_ARG (orig_call, 0), ! CALL_EXPR_ARG (orig_call, 1)); } static tree ! abs_builtin (tree method_return_type, tree orig_call) { return fold_build1 (ABS_EXPR, method_return_type, ! CALL_EXPR_ARG (orig_call, 0)); } ! /* Construct a new call to FN using the arguments from ORIG_CALL. */ ! static tree ! java_build_function_call_expr (tree fn, tree orig_call) { ! int nargs = call_expr_nargs (orig_call); ! switch (nargs) ! { ! /* Although we could handle the 0-3 argument cases using the general ! logic in the default case, splitting them out permits folding to ! be performed without constructing a temporary CALL_EXPR. */ ! case 0: ! return build_call_expr (fn, 0); ! case 1: ! return build_call_expr (fn, 1, CALL_EXPR_ARG (orig_call, 0)); ! case 2: ! return build_call_expr (fn, 2, ! CALL_EXPR_ARG (orig_call, 0), ! CALL_EXPR_ARG (orig_call, 1)); ! case 3: ! return build_call_expr (fn, 3, ! CALL_EXPR_ARG (orig_call, 0), ! CALL_EXPR_ARG (orig_call, 1), ! CALL_EXPR_ARG (orig_call, 2)); ! default: ! { ! tree fntype = TREE_TYPE (fn); ! fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fn); ! return fold (build_call_array (TREE_TYPE (fntype), ! fn, nargs, CALL_EXPR_ARGP (orig_call))); ! } ! } } static tree ! convert_real (tree method_return_type, tree orig_call) { return build1 (VIEW_CONVERT_EXPR, method_return_type, ! CALL_EXPR_ARG (orig_call, 0)); } *************** convert_real (tree method_return_type, t *** 191,266 **** */ ! /* Macros to unmarshal arguments from a TREE_LIST into a few variables. We also convert the offset arg from a long to an integer that is the same size as a pointer. */ ! #define UNMARSHAL3(METHOD_ARGUMENTS) \ tree this_arg, obj_arg, offset_arg; \ do \ { \ ! tree chain = METHOD_ARGUMENTS; \ ! this_arg = TREE_VALUE (chain); \ ! chain = TREE_CHAIN (chain); \ ! obj_arg = TREE_VALUE (chain); \ ! chain = TREE_CHAIN (chain); \ offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \ ! TREE_VALUE (chain)); \ } \ while (0) ! #define UNMARSHAL4(METHOD_ARGUMENTS) \ tree value_type, this_arg, obj_arg, offset_arg, value_arg; \ do \ { \ ! tree chain = METHOD_ARGUMENTS; \ ! this_arg = TREE_VALUE (chain); \ ! chain = TREE_CHAIN (chain); \ ! obj_arg = TREE_VALUE (chain); \ ! chain = TREE_CHAIN (chain); \ offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \ ! TREE_VALUE (chain)); \ ! chain = TREE_CHAIN (chain); \ ! value_arg = TREE_VALUE (chain); \ value_type = TREE_TYPE (value_arg); \ } \ while (0) ! #define UNMARSHAL5(METHOD_ARGUMENTS) \ tree value_type, this_arg, obj_arg, offset_arg, expected_arg, value_arg; \ do \ { \ ! tree chain = METHOD_ARGUMENTS; \ ! this_arg = TREE_VALUE (chain); \ ! chain = TREE_CHAIN (chain); \ ! obj_arg = TREE_VALUE (chain); \ ! chain = TREE_CHAIN (chain); \ offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \ ! TREE_VALUE (chain)); \ ! chain = TREE_CHAIN (chain); \ ! expected_arg = TREE_VALUE (chain); \ ! chain = TREE_CHAIN (chain); \ ! value_arg = TREE_VALUE (chain); \ value_type = TREE_TYPE (value_arg); \ } \ while (0) - /* Construct an arglist from a call. */ - - static tree - build_arglist_for_builtin (tree arg, ...) - { - va_list ap; - tree nextarg; - tree newarglist = build_tree_list (NULL_TREE, arg); - - va_start(ap, arg); - while ((nextarg = va_arg(ap, tree))) - newarglist = tree_cons (NULL_TREE, nextarg, newarglist); - - return nreverse (newarglist); - } - /* Add an address to an offset, forming a sum. */ static tree --- 215,265 ---- */ ! /* Macros to unmarshal arguments from a CALL_EXPR into a few variables. We also convert the offset arg from a long to an integer that is the same size as a pointer. */ ! #define UNMARSHAL3(METHOD_CALL) \ tree this_arg, obj_arg, offset_arg; \ do \ { \ ! tree orig_method_call = METHOD_CALL; \ ! this_arg = CALL_EXPR_ARG (orig_method_call, 0); \ ! obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \ offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \ ! CALL_EXPR_ARG (orig_method_call, 2)); \ } \ while (0) ! #define UNMARSHAL4(METHOD_CALL) \ tree value_type, this_arg, obj_arg, offset_arg, value_arg; \ do \ { \ ! tree orig_method_call = METHOD_CALL; \ ! this_arg = CALL_EXPR_ARG (orig_method_call, 0); \ ! obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \ offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \ ! CALL_EXPR_ARG (orig_method_call, 2)); \ ! value_arg = CALL_EXPR_ARG (orig_method_call, 3); \ value_type = TREE_TYPE (value_arg); \ } \ while (0) ! #define UNMARSHAL5(METHOD_CALL) \ tree value_type, this_arg, obj_arg, offset_arg, expected_arg, value_arg; \ do \ { \ ! tree orig_method_call = METHOD_CALL; \ ! this_arg = CALL_EXPR_ARG (orig_method_call, 0); \ ! obj_arg = CALL_EXPR_ARG (orig_method_call, 1); \ offset_arg = fold_convert (java_type_for_size (POINTER_SIZE, 0), \ ! CALL_EXPR_ARG (orig_method_call, 2)); \ ! expected_arg = CALL_EXPR_ARG (orig_method_call, 3); \ ! value_arg = CALL_EXPR_ARG (orig_method_call, 4); \ value_type = TREE_TYPE (value_arg); \ } \ while (0) /* Add an address to an offset, forming a sum. */ static tree *************** build_check_this (tree stmt, tree this_a *** 286,295 **** static tree putObject_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree method_arguments) { tree addr, stmt; ! UNMARSHAL4 (method_arguments); addr = build_addr_sum (value_type, obj_arg, offset_arg); stmt = fold_build2 (MODIFY_EXPR, value_type, --- 285,294 ---- static tree putObject_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree orig_call) { tree addr, stmt; ! UNMARSHAL4 (orig_call); addr = build_addr_sum (value_type, obj_arg, offset_arg); stmt = fold_build2 (MODIFY_EXPR, value_type, *************** putObject_builtin (tree method_return_ty *** 302,323 **** static tree compareAndSwapInt_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree method_arguments) { enum machine_mode mode = TYPE_MODE (int_type_node); if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing || sync_compare_and_swap[mode] != CODE_FOR_nothing) { ! tree newarglist, addr, stmt; ! UNMARSHAL5 (method_arguments); addr = build_addr_sum (int_type_node, obj_arg, offset_arg); ! ! newarglist ! = build_arglist_for_builtin (addr, expected_arg, value_arg, NULL_TREE); ! stmt = (build_function_call_expr ! (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_4], ! newarglist)); return build_check_this (stmt, this_arg); } --- 301,318 ---- static tree compareAndSwapInt_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree orig_call) { enum machine_mode mode = TYPE_MODE (int_type_node); if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing || sync_compare_and_swap[mode] != CODE_FOR_nothing) { ! tree addr, stmt; ! UNMARSHAL5 (orig_call); addr = build_addr_sum (int_type_node, obj_arg, offset_arg); ! stmt = build_call_expr (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_4], ! 3, addr, expected_arg, value_arg); return build_check_this (stmt, this_arg); } *************** compareAndSwapInt_builtin (tree method_r *** 326,347 **** static tree compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree method_arguments) { enum machine_mode mode = TYPE_MODE (long_type_node); if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing || sync_compare_and_swap[mode] != CODE_FOR_nothing) { ! tree newarglist, addr, stmt; ! UNMARSHAL5 (method_arguments); addr = build_addr_sum (long_type_node, obj_arg, offset_arg); ! ! newarglist ! = build_arglist_for_builtin (addr, expected_arg, value_arg, NULL_TREE); ! stmt = (build_function_call_expr ! (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_8], ! newarglist)); return build_check_this (stmt, this_arg); } --- 321,338 ---- static tree compareAndSwapLong_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree orig_call) { enum machine_mode mode = TYPE_MODE (long_type_node); if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing || sync_compare_and_swap[mode] != CODE_FOR_nothing) { ! tree addr, stmt; ! UNMARSHAL5 (orig_call); addr = build_addr_sum (long_type_node, obj_arg, offset_arg); ! stmt = build_call_expr (built_in_decls[BUILT_IN_BOOL_COMPARE_AND_SWAP_8], ! 3, addr, expected_arg, value_arg); return build_check_this (stmt, this_arg); } *************** compareAndSwapLong_builtin (tree method_ *** 349,375 **** } static tree compareAndSwapObject_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree method_arguments) { enum machine_mode mode = TYPE_MODE (ptr_type_node); if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing || sync_compare_and_swap[mode] != CODE_FOR_nothing) { ! tree newarglist, addr, stmt; int builtin; ! UNMARSHAL5 (method_arguments); builtin = (POINTER_SIZE == 32 ? BUILT_IN_BOOL_COMPARE_AND_SWAP_4 : BUILT_IN_BOOL_COMPARE_AND_SWAP_8); addr = build_addr_sum (value_type, obj_arg, offset_arg); ! ! newarglist ! = build_arglist_for_builtin (addr, expected_arg, value_arg, NULL_TREE); ! stmt = (build_function_call_expr ! (built_in_decls[builtin], ! newarglist)); return build_check_this (stmt, this_arg); } --- 340,362 ---- } static tree compareAndSwapObject_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree orig_call) { enum machine_mode mode = TYPE_MODE (ptr_type_node); if (sync_compare_and_swap_cc[mode] != CODE_FOR_nothing || sync_compare_and_swap[mode] != CODE_FOR_nothing) { ! tree addr, stmt; int builtin; ! UNMARSHAL5 (orig_call); builtin = (POINTER_SIZE == 32 ? BUILT_IN_BOOL_COMPARE_AND_SWAP_4 : BUILT_IN_BOOL_COMPARE_AND_SWAP_8); addr = build_addr_sum (value_type, obj_arg, offset_arg); ! stmt = build_call_expr (built_in_decls[builtin], ! 3, addr, expected_arg, value_arg); return build_check_this (stmt, this_arg); } *************** compareAndSwapObject_builtin (tree metho *** 378,397 **** static tree putVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree method_arguments) { ! tree newarglist, addr, stmt, modify_stmt; ! UNMARSHAL4 (method_arguments); addr = build_addr_sum (value_type, obj_arg, offset_arg); addr = fold_convert (build_pointer_type (build_type_variant (value_type, 0, 1)), addr); ! newarglist = NULL_TREE; ! stmt = (build_function_call_expr ! (built_in_decls[BUILT_IN_SYNCHRONIZE], ! newarglist)); modify_stmt = fold_build2 (MODIFY_EXPR, value_type, build_java_indirect_ref (value_type, addr, flag_check_references), --- 365,381 ---- static tree putVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree orig_call) { ! tree addr, stmt, modify_stmt; ! UNMARSHAL4 (orig_call); addr = build_addr_sum (value_type, obj_arg, offset_arg); addr = fold_convert (build_pointer_type (build_type_variant (value_type, 0, 1)), addr); ! stmt = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0); modify_stmt = fold_build2 (MODIFY_EXPR, value_type, build_java_indirect_ref (value_type, addr, flag_check_references), *************** putVolatile_builtin (tree method_return_ *** 404,423 **** static tree getVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree method_arguments) { ! tree newarglist, addr, stmt, modify_stmt, tmp; ! UNMARSHAL3 (method_arguments); addr = build_addr_sum (method_return_type, obj_arg, offset_arg); addr = fold_convert (build_pointer_type (build_type_variant (method_return_type, 0, 1)), addr); ! newarglist = NULL_TREE; ! stmt = (build_function_call_expr ! (built_in_decls[BUILT_IN_SYNCHRONIZE], ! newarglist)); tmp = build_decl (VAR_DECL, NULL, method_return_type); DECL_IGNORED_P (tmp) = 1; --- 388,404 ---- static tree getVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED, ! tree orig_call) { ! tree addr, stmt, modify_stmt, tmp; ! UNMARSHAL3 (orig_call); addr = build_addr_sum (method_return_type, obj_arg, offset_arg); addr = fold_convert (build_pointer_type (build_type_variant (method_return_type, 0, 1)), addr); ! stmt = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0); tmp = build_decl (VAR_DECL, NULL, method_return_type); DECL_IGNORED_P (tmp) = 1; *************** getVolatile_builtin (tree method_return_ *** 437,443 **** static tree VMSupportsCS8_builtin (tree method_return_type, ! tree method_arguments ATTRIBUTE_UNUSED) { enum machine_mode mode = TYPE_MODE (long_type_node); gcc_assert (method_return_type == boolean_type_node); --- 418,424 ---- static tree VMSupportsCS8_builtin (tree method_return_type, ! tree orig_call ATTRIBUTE_UNUSED) { enum machine_mode mode = TYPE_MODE (long_type_node); gcc_assert (method_return_type == boolean_type_node); *************** check_for_builtin (tree method, tree cal *** 596,602 **** if (optimize && TREE_CODE (call) == CALL_EXPR) { int i; - tree method_arguments = TREE_OPERAND (call, 1); tree method_class = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method))); tree method_name = DECL_NAME (method); tree method_return_type = TREE_TYPE (TREE_TYPE (method)); --- 577,582 ---- *************** check_for_builtin (tree method, tree cal *** 611,618 **** if (java_builtins[i].creator != NULL) { tree result ! = (*java_builtins[i].creator) (method_return_type, ! method_arguments); return result == NULL_TREE ? call : result; } --- 591,597 ---- if (java_builtins[i].creator != NULL) { tree result ! = (*java_builtins[i].creator) (method_return_type, call); return result == NULL_TREE ? call : result; } *************** check_for_builtin (tree method, tree cal *** 623,629 **** fn = built_in_decls[java_builtins[i].builtin_code]; if (fn == NULL_TREE) return call; ! return java_build_function_call_expr (fn, method_arguments); } } } --- 602,608 ---- fn = built_in_decls[java_builtins[i].builtin_code]; if (fn == NULL_TREE) return call; ! return java_build_function_call_expr (fn, call); } } } Index: gcc/java/expr.c =================================================================== *** gcc/java/expr.c (revision 121818) --- gcc/java/expr.c (working copy) *************** build_java_athrow (tree node) *** 716,726 **** { tree call; ! call = build3 (CALL_EXPR, ! void_type_node, ! build_address_of (throw_node), ! build_tree_list (NULL_TREE, node), ! NULL_TREE); TREE_SIDE_EFFECTS (call) = 1; java_add_stmt (call); java_stack_pop (stack_pointer); --- 716,724 ---- { tree call; ! call = build_call_nary (void_type_node, ! build_address_of (throw_node), ! 1, node); TREE_SIDE_EFFECTS (call) = 1; java_add_stmt (call); java_stack_pop (stack_pointer); *************** encode_newarray_type (tree type) *** 799,807 **** static tree build_java_throw_out_of_bounds_exception (tree index) { ! tree node = build3 (CALL_EXPR, int_type_node, ! build_address_of (soft_badarrayindex_node), ! build_tree_list (NULL_TREE, index), NULL_TREE); TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */ return (node); } --- 797,805 ---- static tree build_java_throw_out_of_bounds_exception (tree index) { ! tree node = build_call_nary (int_type_node, ! build_address_of (soft_badarrayindex_node), ! 1, index); TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */ return (node); } *************** java_check_reference (tree expr, int che *** 850,858 **** expr = build3 (COND_EXPR, TREE_TYPE (expr), build2 (EQ_EXPR, boolean_type_node, expr, null_pointer_node), ! build3 (CALL_EXPR, void_type_node, ! build_address_of (soft_nullpointer_node), ! NULL_TREE, NULL_TREE), expr); } --- 848,856 ---- expr = build3 (COND_EXPR, TREE_TYPE (expr), build2 (EQ_EXPR, boolean_type_node, expr, null_pointer_node), ! build_call_nary (void_type_node, ! build_address_of (soft_nullpointer_node), ! 0), expr); } *************** build_java_arraystore_check (tree array, *** 1014,1024 **** } /* Build an invocation of _Jv_CheckArrayStore */ ! check = build3 (CALL_EXPR, void_type_node, ! build_address_of (soft_checkarraystore_node), ! tree_cons (NULL_TREE, array, ! build_tree_list (NULL_TREE, object)), ! NULL_TREE); TREE_SIDE_EFFECTS (check) = 1; return check; --- 1012,1020 ---- } /* Build an invocation of _Jv_CheckArrayStore */ ! check = build_call_nary (void_type_node, ! build_address_of (soft_checkarraystore_node), ! 2, array, object); TREE_SIDE_EFFECTS (check) = 1; return check; *************** build_newarray (int atype_value, tree le *** 1060,1071 **** some work. */ type_arg = build_class_ref (prim_type); ! return build3 (CALL_EXPR, promote_type (type), ! build_address_of (soft_newarray_node), ! tree_cons (NULL_TREE, ! type_arg, ! build_tree_list (NULL_TREE, length)), ! NULL_TREE); } /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size --- 1056,1064 ---- some work. */ type_arg = build_class_ref (prim_type); ! return build_call_nary (promote_type (type), ! build_address_of (soft_newarray_node), ! 2, type_arg, length); } /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size *************** build_anewarray (tree class_type, tree l *** 1079,1091 **** host_integerp (length, 0) ? tree_low_cst (length, 0) : -1); ! return build3 (CALL_EXPR, promote_type (type), ! build_address_of (soft_anewarray_node), ! tree_cons (NULL_TREE, length, ! tree_cons (NULL_TREE, build_class_ref (class_type), ! build_tree_list (NULL_TREE, ! null_pointer_node))), ! NULL_TREE); } /* Return a node the evaluates 'new TYPE[LENGTH]'. */ --- 1072,1083 ---- host_integerp (length, 0) ? tree_low_cst (length, 0) : -1); ! return build_call_nary (promote_type (type), ! build_address_of (soft_anewarray_node), ! 3, ! length, ! build_class_ref (class_type), ! null_pointer_node); } /* Return a node the evaluates 'new TYPE[LENGTH]'. */ *************** expand_java_multianewarray (tree class_t *** 1112,1125 **** for( i = 0; i < ndim; i++ ) args = tree_cons (NULL_TREE, pop_value (int_type_node), args); ! push_value (build3 (CALL_EXPR, ! promote_type (class_type), ! build_address_of (soft_multianewarray_node), ! tree_cons (NULL_TREE, build_class_ref (class_type), ! tree_cons (NULL_TREE, ! build_int_cst (NULL_TREE, ndim), ! args)), ! NULL_TREE)); } /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that --- 1104,1118 ---- for( i = 0; i < ndim; i++ ) args = tree_cons (NULL_TREE, pop_value (int_type_node), args); ! args = tree_cons (NULL_TREE, ! build_class_ref (class_type), ! tree_cons (NULL_TREE, ! build_int_cst (NULL_TREE, ndim), ! args)); ! ! push_value (build_call_list (promote_type (class_type), ! build_address_of (soft_multianewarray_node), ! args)); } /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that *************** expand_java_array_length (void) *** 1246,1256 **** static tree build_java_monitor (tree call, tree object) { ! return build3 (CALL_EXPR, ! void_type_node, ! build_address_of (call), ! build_tree_list (NULL_TREE, object), ! NULL_TREE); } /* Emit code for one of the PUSHC instructions. */ --- 1239,1247 ---- static tree build_java_monitor (tree call, tree object) { ! return build_call_nary (void_type_node, ! build_address_of (call), ! 1, object); } /* Emit code for one of the PUSHC instructions. */ *************** java_create_object (tree type) *** 1347,1356 **** ? alloc_object_node : alloc_no_finalizer_node); ! return build3 (CALL_EXPR, promote_type (type), ! build_address_of (alloc_node), ! build_tree_list (NULL_TREE, build_class_ref (type)), ! NULL_TREE); } static void --- 1338,1346 ---- ? alloc_object_node : alloc_no_finalizer_node); ! return build_call_nary (promote_type (type), ! build_address_of (alloc_node), ! 1, build_class_ref (type)); } static void *************** expand_java_NEW (tree type) *** 1363,1372 **** if (! CLASS_LOADED_P (type)) load_class (type, 1); safe_layout_class (type); ! push_value (build3 (CALL_EXPR, promote_type (type), ! build_address_of (alloc_node), ! build_tree_list (NULL_TREE, build_class_ref (type)), ! NULL_TREE)); } /* This returns an expression which will extract the class of an --- 1353,1361 ---- if (! CLASS_LOADED_P (type)) load_class (type, 1); safe_layout_class (type); ! push_value (build_call_nary (promote_type (type), ! build_address_of (alloc_node), ! 1, build_class_ref (type))); } /* This returns an expression which will extract the class of an *************** build_instanceof (tree value, tree type) *** 1445,1456 **** } else { ! expr = build3 (CALL_EXPR, itype, ! build_address_of (soft_instanceof_node), ! tree_cons (NULL_TREE, value, ! build_tree_list (NULL_TREE, ! build_class_ref (type))), ! NULL_TREE); } TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value); return expr; --- 1434,1442 ---- } else { ! expr = build_call_nary (itype, ! build_address_of (soft_instanceof_node), ! 2, value, build_class_ref (type)); } TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value); return expr; *************** static void *** 1468,1478 **** expand_java_CHECKCAST (tree type) { tree value = pop_value (ptr_type_node); ! value = build3 (CALL_EXPR, promote_type (type), ! build_address_of (soft_checkcast_node), ! tree_cons (NULL_TREE, build_class_ref (type), ! build_tree_list (NULL_TREE, value)), ! NULL_TREE); push_value (value); } --- 1454,1462 ---- expand_java_CHECKCAST (tree type) { tree value = pop_value (ptr_type_node); ! value = build_call_nary (promote_type (type), ! build_address_of (soft_checkcast_node), ! 2, build_class_ref (type), value); push_value (value); } *************** build_java_soft_divmod (enum tree_code o *** 1527,1538 **** } gcc_assert (call); ! call = build3 (CALL_EXPR, type, ! build_address_of (call), ! tree_cons (NULL_TREE, arg1, ! build_tree_list (NULL_TREE, arg2)), ! NULL_TREE); ! return call; } --- 1511,1517 ---- } gcc_assert (call); ! call = build_call_nary (type, build_address_of (call), 2, arg1, arg2); return call; } *************** build_java_binop (enum tree_code op, tre *** 1595,1605 **** arg1 = convert (double_type_node, arg1); arg2 = convert (double_type_node, arg2); } ! call = build3 (CALL_EXPR, double_type_node, ! build_address_of (soft_fmod_node), ! tree_cons (NULL_TREE, arg1, ! build_tree_list (NULL_TREE, arg2)), ! NULL_TREE); if (type != double_type_node) call = convert (type, call); return call; --- 1574,1582 ---- arg1 = convert (double_type_node, arg1); arg2 = convert (double_type_node, arg2); } ! call = build_call_nary (double_type_node, ! build_address_of (soft_fmod_node), ! 2, arg1, arg2); if (type != double_type_node) call = convert (type, call); return call; *************** build_field_ref (tree self_value, tree s *** 1759,1768 **** = build3 (COND_EXPR, TREE_TYPE (field_offset), build2 (EQ_EXPR, boolean_type_node, field_offset, integer_zero_node), ! build3 (CALL_EXPR, void_type_node, ! build_address_of (soft_nosuchfield_node), ! build_tree_list (NULL_TREE, otable_index), ! NULL_TREE), field_offset); field_offset = fold (convert (sizetype, field_offset)); --- 1736,1744 ---- = build3 (COND_EXPR, TREE_TYPE (field_offset), build2 (EQ_EXPR, boolean_type_node, field_offset, integer_zero_node), ! build_call_nary (void_type_node, ! build_address_of (soft_nosuchfield_node), ! 1, otable_index), field_offset); field_offset = fold (convert (sizetype, field_offset)); *************** build_class_init (tree clas, tree expr) *** 1998,2007 **** if (always_initialize_class_p) { ! init = build3 (CALL_EXPR, void_type_node, ! build_address_of (soft_initclass_node), ! build_tree_list (NULL_TREE, build_class_ref (clas)), ! NULL_TREE); TREE_SIDE_EFFECTS (init) = 1; } else --- 1974,1982 ---- if (always_initialize_class_p) { ! init = build_call_nary (void_type_node, ! build_address_of (soft_initclass_node), ! 1, build_class_ref (clas)); TREE_SIDE_EFFECTS (init) = 1; } else *************** build_class_init (tree clas, tree expr) *** 2031,2040 **** *init_test_decl = decl; } ! init = build3 (CALL_EXPR, void_type_node, ! build_address_of (soft_initclass_node), ! build_tree_list (NULL_TREE, build_class_ref (clas)), ! NULL_TREE); TREE_SIDE_EFFECTS (init) = 1; init = build3 (COND_EXPR, void_type_node, build2 (EQ_EXPR, boolean_type_node, --- 2006,2014 ---- *init_test_decl = decl; } ! init = build_call_nary (void_type_node, ! build_address_of (soft_initclass_node), ! 1, build_class_ref (clas)); TREE_SIDE_EFFECTS (init) = 1; init = build3 (COND_EXPR, void_type_node, build2 (EQ_EXPR, boolean_type_node, *************** static tree *** 2084,2092 **** rewrite_arglist_getcaller (tree arglist) { tree retaddr ! = (build_function_call_expr ! (built_in_decls[BUILT_IN_RETURN_ADDRESS], ! build_tree_list (NULL_TREE, integer_zero_node))); DECL_INLINE (current_function_decl) = 0; --- 2058,2065 ---- rewrite_arglist_getcaller (tree arglist) { tree retaddr ! = build_call_expr (built_in_decls[BUILT_IN_RETURN_ADDRESS], ! 1, integer_zero_node); DECL_INLINE (current_function_decl) = 0; *************** static GTY(()) tree class_ident; *** 2356,2362 **** tree build_invokeinterface (tree dtable, tree method) { - tree lookup_arg; tree interface; tree idx; --- 2329,2334 ---- *************** build_invokeinterface (tree dtable, tree *** 2401,2413 **** interface = build_class_ref (interface); } ! lookup_arg = tree_cons (NULL_TREE, dtable, ! tree_cons (NULL_TREE, interface, ! build_tree_list (NULL_TREE, idx))); ! ! return build3 (CALL_EXPR, ptr_type_node, ! build_address_of (soft_lookupinterfacemethod_node), ! lookup_arg, NULL_TREE); } /* Expand one of the invoke_* opcodes. --- 2373,2381 ---- interface = build_class_ref (interface); } ! return build_call_nary (ptr_type_node, ! build_address_of (soft_lookupinterfacemethod_node), ! 3, dtable, interface, idx); } /* Expand one of the invoke_* opcodes. *************** expand_invoke (int opcode, int method_re *** 2590,2597 **** else func = build1 (NOP_EXPR, build_pointer_type (method_type), func); ! call = build3 (CALL_EXPR, TREE_TYPE (method_type), ! func, arg_list, NULL_TREE); TREE_SIDE_EFFECTS (call) = 1; call = check_for_builtin (method, call); --- 2558,2564 ---- else func = build1 (NOP_EXPR, build_pointer_type (method_type), func); ! call = build_call_list (TREE_TYPE (method_type), func, arg_list); TREE_SIDE_EFFECTS (call) = 1; call = check_for_builtin (method, call); *************** expand_invoke (int opcode, int method_re *** 2616,2622 **** tree build_jni_stub (tree method) { ! tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types; tree jni_func_type, tem; tree env_var, res_var = NULL_TREE, block; tree method_args, res_type; --- 2583,2590 ---- tree build_jni_stub (tree method) { ! tree jnifunc, call, args, body, method_sig, arg_types; ! tree jniarg0, jniarg1, jniarg2, jniarg3; tree jni_func_type, tem; tree env_var, res_var = NULL_TREE, block; tree method_args, res_type; *************** build_jni_stub (tree method) *** 2671,2680 **** /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */ body = build2 (MODIFY_EXPR, ptr_type_node, env_var, ! build3 (CALL_EXPR, ptr_type_node, ! build_address_of (soft_getjnienvnewframe_node), ! build_tree_list (NULL_TREE, klass), ! NULL_TREE)); CAN_COMPLETE_NORMALLY (body) = 1; /* All the arguments to this method become arguments to the --- 2639,2647 ---- /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */ body = build2 (MODIFY_EXPR, ptr_type_node, env_var, ! build_call_nary (ptr_type_node, ! build_address_of (soft_getjnienvnewframe_node), ! 1, klass)); CAN_COMPLETE_NORMALLY (body) = 1; /* All the arguments to this method become arguments to the *************** build_jni_stub (tree method) *** 2713,2730 **** /* We call _Jv_LookupJNIMethod to find the actual underlying function pointer. _Jv_LookupJNIMethod will throw the appropriate exception if this function is not found at runtime. */ - tem = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, args_size)); method_sig = build_java_signature (TREE_TYPE (method)); ! lookup_arg = tree_cons (NULL_TREE, ! build_utf8_ref (unmangle_classname ! (IDENTIFIER_POINTER (method_sig), ! IDENTIFIER_LENGTH (method_sig))), ! tem); ! tem = DECL_NAME (method); ! lookup_arg ! = tree_cons (NULL_TREE, klass, ! tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg)); ! tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types); #ifdef MODIFY_JNI_METHOD_CALL --- 2680,2693 ---- /* We call _Jv_LookupJNIMethod to find the actual underlying function pointer. _Jv_LookupJNIMethod will throw the appropriate exception if this function is not found at runtime. */ method_sig = build_java_signature (TREE_TYPE (method)); ! jniarg0 = klass; ! jniarg1 = build_utf8_ref (DECL_NAME (method)); ! jniarg2 = build_utf8_ref (unmangle_classname ! (IDENTIFIER_POINTER (method_sig), ! IDENTIFIER_LENGTH (method_sig))); ! jniarg3 = build_int_cst (NULL_TREE, args_size); ! tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types); #ifdef MODIFY_JNI_METHOD_CALL *************** build_jni_stub (tree method) *** 2736,2751 **** jnifunc = build3 (COND_EXPR, ptr_type_node, meth_var, meth_var, build2 (MODIFY_EXPR, ptr_type_node, meth_var, ! build3 (CALL_EXPR, ptr_type_node, ! build_address_of ! (soft_lookupjnimethod_node), ! lookup_arg, NULL_TREE))); /* Now we make the actual JNI call via the resulting function pointer. */ ! call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)), ! build1 (NOP_EXPR, jni_func_type, jnifunc), ! args, NULL_TREE); /* If the JNI call returned a result, capture it here. If we had to unwrap JNI object results, we would do that here. */ --- 2699,2716 ---- jnifunc = build3 (COND_EXPR, ptr_type_node, meth_var, meth_var, build2 (MODIFY_EXPR, ptr_type_node, meth_var, ! build_call_nary (ptr_type_node, ! build_address_of ! (soft_lookupjnimethod_node), ! 4, ! jniarg0, jniarg1, ! jniarg2, jniarg3))); /* Now we make the actual JNI call via the resulting function pointer. */ ! call = build_call_list (TREE_TYPE (TREE_TYPE (method)), ! build1 (NOP_EXPR, jni_func_type, jnifunc), ! args); /* If the JNI call returned a result, capture it here. If we had to unwrap JNI object results, we would do that here. */ *************** build_jni_stub (tree method) *** 2754,2763 **** /* If the call returns an object, it may return a JNI weak reference, in which case we must unwrap it. */ if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method)))) ! call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)), ! build_address_of (soft_unwrapjni_node), ! build_tree_list (NULL_TREE, call), ! NULL_TREE); call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)), res_var, call); } --- 2719,2727 ---- /* If the call returns an object, it may return a JNI weak reference, in which case we must unwrap it. */ if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method)))) ! call = build_call_nary (TREE_TYPE (TREE_TYPE (method)), ! build_address_of (soft_unwrapjni_node), ! 1, call); call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)), res_var, call); } *************** build_jni_stub (tree method) *** 2769,2778 **** TREE_SIDE_EFFECTS (body) = 1; /* Now free the environment we allocated. */ ! call = build3 (CALL_EXPR, ptr_type_node, ! build_address_of (soft_jnipopsystemframe_node), ! build_tree_list (NULL_TREE, env_var), ! NULL_TREE); TREE_SIDE_EFFECTS (call) = 1; CAN_COMPLETE_NORMALLY (call) = 1; body = build2 (COMPOUND_EXPR, void_type_node, body, call); --- 2733,2741 ---- TREE_SIDE_EFFECTS (body) = 1; /* Now free the environment we allocated. */ ! call = build_call_nary (ptr_type_node, ! build_address_of (soft_jnipopsystemframe_node), ! 1, env_var); TREE_SIDE_EFFECTS (call) = 1; CAN_COMPLETE_NORMALLY (call) = 1; body = build2 (COMPOUND_EXPR, void_type_node, body, call); *************** build_jni_stub (tree method) *** 2805,2815 **** && (! METHOD_PRIVATE (method) || INNER_CLASS_P (DECL_CONTEXT (method)))) { ! tree init = build3 (CALL_EXPR, void_type_node, ! build_address_of (soft_initclass_node), ! build_tree_list (NULL_TREE, ! klass), ! NULL_TREE); body = build2 (COMPOUND_EXPR, void_type_node, init, body); TREE_SIDE_EFFECTS (body) = 1; } --- 2768,2775 ---- && (! METHOD_PRIVATE (method) || INNER_CLASS_P (DECL_CONTEXT (method)))) { ! tree init = build_call_expr (soft_initclass_node, 1, ! klass); body = build2 (COMPOUND_EXPR, void_type_node, init, body); TREE_SIDE_EFFECTS (body) = 1; } *************** expand_java_field_op (int is_static, int *** 2943,2953 **** 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); } --- 2903,2910 ---- field_ref, new_value); if (TREE_THIS_VOLATILE (field_decl)) ! java_add_stmt ! (build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0)); java_add_stmt (modify_expr); } *************** expand_java_field_op (int is_static, int *** 2965,2974 **** 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); } --- 2922,2928 ---- if (TREE_THIS_VOLATILE (field_decl)) java_add_stmt ! (build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0)); push_value (temp); } *************** force_evaluation_order (tree node) *** 3725,3764 **** && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR)) { ! tree arg, cmp; ! arg = node; ! ! /* Position arg properly, account for wrapped around ctors. */ if (TREE_CODE (node) == COMPOUND_EXPR) ! arg = TREE_OPERAND (node, 0); ! ! arg = TREE_OPERAND (arg, 1); ! ! /* An empty argument list is ok, just ignore it. */ ! if (!arg) ! return node; ! /* Not having a list of arguments here is an error. */ ! gcc_assert (TREE_CODE (arg) == TREE_LIST); /* This reverses the evaluation order. This is a desired effect. */ ! for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg)) { /* Promote types smaller than integer. This is required by some ABIs. */ ! tree type = TREE_TYPE (TREE_VALUE (arg)); tree saved; if (targetm.calls.promote_prototypes (type) && INTEGRAL_TYPE_P (type) && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) ! TREE_VALUE (arg) = fold_convert (integer_type_node, TREE_VALUE (arg)); ! saved = save_expr (force_evaluation_order (TREE_VALUE (arg))); cmp = (cmp == NULL_TREE ? saved : build2 (COMPOUND_EXPR, void_type_node, cmp, saved)); ! TREE_VALUE (arg) = saved; } if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR) --- 3679,3714 ---- && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR)) { ! tree call, cmp; ! int i, nargs; ! /* Account for wrapped around ctors. */ if (TREE_CODE (node) == COMPOUND_EXPR) ! call = TREE_OPERAND (node, 0); ! else ! call = node; ! nargs = call_expr_nargs (call); /* This reverses the evaluation order. This is a desired effect. */ ! for (i = 0, cmp = NULL_TREE; i < nargs; i++) { + tree arg = CALL_EXPR_ARG (call, i); /* Promote types smaller than integer. This is required by some ABIs. */ ! tree type = TREE_TYPE (arg); tree saved; if (targetm.calls.promote_prototypes (type) && INTEGRAL_TYPE_P (type) && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (integer_type_node))) ! arg = fold_convert (integer_type_node, arg); ! saved = save_expr (force_evaluation_order (arg)); cmp = (cmp == NULL_TREE ? saved : build2 (COMPOUND_EXPR, void_type_node, cmp, saved)); ! ! CALL_EXPR_ARG (call, i) = saved; } if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR) Index: gcc/java/lang.c =================================================================== *** gcc/java/lang.c (revision 121818) --- gcc/java/lang.c (working copy) *************** java_get_callee_fndecl (tree call_expr) *** 989,995 **** if (TREE_CODE (call_expr) != CALL_EXPR) return NULL; ! method = TREE_OPERAND (call_expr, 0); STRIP_NOPS (method); if (TREE_CODE (method) != ARRAY_REF) return NULL; --- 989,995 ---- if (TREE_CODE (call_expr) != CALL_EXPR) return NULL; ! method = CALL_EXPR_FN (call_expr); STRIP_NOPS (method); if (TREE_CODE (method) != ARRAY_REF) return NULL;