diff options
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 256 |
1 files changed, 75 insertions, 181 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 798de08..0d17370 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2622,7 +2622,6 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, tree alloc_fn; tree cookie_expr, init_expr; int nothrow, check_new; - int use_java_new = 0; /* If non-NULL, the number of extra bytes to allocate at the beginning of the storage allocated for an array-new expression in order to store the number of elements. */ @@ -2866,149 +2865,97 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, bool member_new_p = false; /* Allocate the object. */ - if (vec_safe_is_empty (*placement) && TYPE_FOR_JAVA (elt_type)) - { - tree class_addr; - tree class_decl; - static const char alloc_name[] = "_Jv_AllocObject"; + tree fnname; + tree fns; - if (!MAYBE_CLASS_TYPE_P (elt_type)) - { - error ("%qT isn%'t a valid Java class type", elt_type); - return error_mark_node; - } + fnname = ansi_opname (array_p ? VEC_NEW_EXPR : NEW_EXPR); - class_decl = build_java_class_ref (elt_type); - if (class_decl == error_mark_node) - return error_mark_node; + member_new_p = !globally_qualified_p + && CLASS_TYPE_P (elt_type) + && (array_p + ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type) + : TYPE_HAS_NEW_OPERATOR (elt_type)); - use_java_new = 1; - if (!get_global_value_if_present (get_identifier (alloc_name), - &alloc_fn)) + if (member_new_p) + { + /* Use a class-specific operator new. */ + /* If a cookie is required, add some extra space. */ + if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type)) + size = size_binop (PLUS_EXPR, size, cookie_size); + else { - if (complain & tf_error) - error ("call to Java constructor with %qs undefined", alloc_name); - return error_mark_node; + cookie_size = NULL_TREE; + /* No size arithmetic necessary, so the size check is + not needed. */ + if (outer_nelts_check != NULL && inner_size == 1) + outer_nelts_check = NULL_TREE; } - else if (really_overloaded_fn (alloc_fn)) + /* Perform the overflow check. */ + tree errval = TYPE_MAX_VALUE (sizetype); + if (cxx_dialect >= cxx11 && flag_exceptions) + errval = throw_bad_array_new_length (); + if (outer_nelts_check != NULL_TREE) + size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check, + size, errval); + /* Create the argument list. */ + vec_safe_insert (*placement, 0, size); + /* Do name-lookup to find the appropriate operator. */ + fns = lookup_fnfields (elt_type, fnname, /*protect=*/2); + if (fns == NULL_TREE) { - if (complain & tf_error) - error ("%qD should never be overloaded", alloc_fn); + if (complain & tf_error) + error ("no suitable %qD found in class %qT", fnname, elt_type); return error_mark_node; } - alloc_fn = OVL_CURRENT (alloc_fn); - if (TREE_CODE (alloc_fn) != FUNCTION_DECL - || TREE_CODE (TREE_TYPE (alloc_fn)) != FUNCTION_TYPE - || !POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (alloc_fn)))) + if (TREE_CODE (fns) == TREE_LIST) { if (complain & tf_error) - error ("%qD is not a function returning a pointer", alloc_fn); + { + error ("request for member %qD is ambiguous", fnname); + print_candidates (fns); + } return error_mark_node; } - class_addr = build1 (ADDR_EXPR, jclass_node, class_decl); - alloc_call = cp_build_function_call_nary (alloc_fn, complain, - class_addr, NULL_TREE); - } - else if (TYPE_FOR_JAVA (elt_type) && MAYBE_CLASS_TYPE_P (elt_type)) - { - error ("Java class %q#T object allocated using placement new", elt_type); - return error_mark_node; + tree dummy = build_dummy_object (elt_type); + alloc_call = NULL_TREE; + if (align_arg) + { + vec<tree, va_gc> *align_args + = vec_copy_and_insert (*placement, align_arg, 1); + alloc_call + = build_new_method_call (dummy, fns, &align_args, + /*conversion_path=*/NULL_TREE, + LOOKUP_NORMAL, &alloc_fn, tf_none); + /* If no matching function is found and the allocated object type + has new-extended alignment, the alignment argument is removed + from the argument list, and overload resolution is performed + again. */ + if (alloc_call == error_mark_node) + alloc_call = NULL_TREE; + } + if (!alloc_call) + alloc_call = build_new_method_call (dummy, fns, placement, + /*conversion_path=*/NULL_TREE, + LOOKUP_NORMAL, + &alloc_fn, complain); } else { - tree fnname; - tree fns; - - fnname = ansi_opname (array_p ? VEC_NEW_EXPR : NEW_EXPR); - - member_new_p = !globally_qualified_p - && CLASS_TYPE_P (elt_type) - && (array_p - ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type) - : TYPE_HAS_NEW_OPERATOR (elt_type)); - - if (member_new_p) + /* Use a global operator new. */ + /* See if a cookie might be required. */ + if (!(array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))) { - /* Use a class-specific operator new. */ - /* If a cookie is required, add some extra space. */ - if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type)) - size = size_binop (PLUS_EXPR, size, cookie_size); - else - { - cookie_size = NULL_TREE; - /* No size arithmetic necessary, so the size check is - not needed. */ - if (outer_nelts_check != NULL && inner_size == 1) - outer_nelts_check = NULL_TREE; - } - /* Perform the overflow check. */ - tree errval = TYPE_MAX_VALUE (sizetype); - if (cxx_dialect >= cxx11 && flag_exceptions) - errval = throw_bad_array_new_length (); - if (outer_nelts_check != NULL_TREE) - size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check, - size, errval); - /* Create the argument list. */ - vec_safe_insert (*placement, 0, size); - /* Do name-lookup to find the appropriate operator. */ - fns = lookup_fnfields (elt_type, fnname, /*protect=*/2); - if (fns == NULL_TREE) - { - if (complain & tf_error) - error ("no suitable %qD found in class %qT", fnname, elt_type); - return error_mark_node; - } - if (TREE_CODE (fns) == TREE_LIST) - { - if (complain & tf_error) - { - error ("request for member %qD is ambiguous", fnname); - print_candidates (fns); - } - return error_mark_node; - } - tree dummy = build_dummy_object (elt_type); - alloc_call = NULL_TREE; - if (align_arg) - { - vec<tree, va_gc> *align_args - = vec_copy_and_insert (*placement, align_arg, 1); - alloc_call - = build_new_method_call (dummy, fns, &align_args, - /*conversion_path=*/NULL_TREE, - LOOKUP_NORMAL, &alloc_fn, tf_none); - /* If no matching function is found and the allocated object type - has new-extended alignment, the alignment argument is removed - from the argument list, and overload resolution is performed - again. */ - if (alloc_call == error_mark_node) - alloc_call = NULL_TREE; - } - if (!alloc_call) - alloc_call = build_new_method_call (dummy, fns, placement, - /*conversion_path=*/NULL_TREE, - LOOKUP_NORMAL, - &alloc_fn, complain); + cookie_size = NULL_TREE; + /* No size arithmetic necessary, so the size check is + not needed. */ + if (outer_nelts_check != NULL && inner_size == 1) + outer_nelts_check = NULL_TREE; } - else - { - /* Use a global operator new. */ - /* See if a cookie might be required. */ - if (!(array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))) - { - cookie_size = NULL_TREE; - /* No size arithmetic necessary, so the size check is - not needed. */ - if (outer_nelts_check != NULL && inner_size == 1) - outer_nelts_check = NULL_TREE; - } - alloc_call = build_operator_new_call (fnname, placement, - &size, &cookie_size, - align_arg, - outer_nelts_check, - &alloc_fn, complain); - } + alloc_call = build_operator_new_call (fnname, placement, + &size, &cookie_size, + align_arg, outer_nelts_check, + &alloc_fn, complain); } if (alloc_call == error_mark_node) @@ -3111,7 +3058,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, So check for a null exception spec on the op new we just called. */ nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn)); - check_new = (flag_check_new || nothrow) && ! use_java_new; + check_new = (flag_check_new || nothrow); if (cookie_size) { @@ -3290,7 +3237,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, unambiguous matching deallocation function can be found, propagating the exception does not cause the object's memory to be freed. */ - if (flag_exceptions && ! use_java_new) + if (flag_exceptions) { enum tree_code dcode = array_p ? VEC_DELETE_EXPR : DELETE_EXPR; tree cleanup; @@ -3531,59 +3478,6 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts, return rval; } - -/* Given a Java class, return a decl for the corresponding java.lang.Class. */ - -tree -build_java_class_ref (tree type) -{ - tree name = NULL_TREE, class_decl; - static tree CL_suffix = NULL_TREE; - if (CL_suffix == NULL_TREE) - CL_suffix = get_identifier("class$"); - if (jclass_node == NULL_TREE) - { - jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass")); - if (jclass_node == NULL_TREE) - { - error ("call to Java constructor, while %<jclass%> undefined"); - return error_mark_node; - } - jclass_node = TREE_TYPE (jclass_node); - } - - /* Mangle the class$ field. */ - { - tree field; - for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - if (DECL_NAME (field) == CL_suffix) - { - mangle_decl (field); - name = DECL_ASSEMBLER_NAME (field); - break; - } - if (!field) - { - error ("can%'t find %<class$%> in %qT", type); - return error_mark_node; - } - } - - class_decl = IDENTIFIER_GLOBAL_VALUE (name); - if (class_decl == NULL_TREE) - { - class_decl = build_decl (input_location, - VAR_DECL, name, TREE_TYPE (jclass_node)); - TREE_STATIC (class_decl) = 1; - DECL_EXTERNAL (class_decl) = 1; - TREE_PUBLIC (class_decl) = 1; - DECL_ARTIFICIAL (class_decl) = 1; - DECL_IGNORED_P (class_decl) = 1; - pushdecl_top_level (class_decl); - make_decl_rtl (class_decl); - } - return class_decl; -} static tree build_vec_delete_1 (tree base, tree maxindex, tree type, |