X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Feval.c;h=17af1b51df246e592d868bb5a2046a9dba84226b;hb=5b6d1e4fa4fc6827c7b3f0e99ff120dfa14d65d2;hp=021503e9dd94f7b481e3e96952a5699a0efa961b;hpb=3e5ef9a4de7919971130f7f2ca3052898a069e76;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/eval.c b/gdb/eval.c index 021503e9dd..17af1b51df 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1,6 +1,6 @@ /* Evaluate expressions for GDB. - Copyright (C) 1986-2018 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -42,9 +42,6 @@ #include "typeprint.h" #include -/* This is defined in valops.c */ -extern int overload_resolution; - /* Prototypes for local functions. */ static struct value *evaluate_subexp_for_sizeof (struct expression *, int *, @@ -74,14 +71,14 @@ evaluate_subexp (struct type *expect_type, struct expression *exp, gdb::optional stack_temporaries; if (*pos == 0 && target_has_execution && exp->language_defn->la_language == language_cplus - && !thread_stack_temporaries_enabled_p (inferior_ptid)) - stack_temporaries.emplace (inferior_ptid); + && !thread_stack_temporaries_enabled_p (inferior_thread ())) + stack_temporaries.emplace (inferior_thread ()); retval = (*exp->language_defn->la_exp_desc->evaluate_exp) (expect_type, exp, pos, noside); if (stack_temporaries.has_value () - && value_in_thread_stack_temporaries (retval, inferior_ptid)) + && value_in_thread_stack_temporaries (retval, inferior_thread ())) retval = value_non_lval (retval); return retval; @@ -123,7 +120,7 @@ parse_and_eval (const char *exp) struct value * parse_to_comma_and_eval (const char **expp) { - expression_up expr = parse_exp_1 (expp, 0, (struct block *) 0, 1); + expression_up expr = parse_exp_1 (expp, 0, nullptr, 1); return evaluate_expression (expr.get ()); } @@ -179,14 +176,14 @@ evaluate_subexpression_type (struct expression *exp, int subexp) set to any referenced values. *VALP will never be a lazy value. This is the value which we store in struct breakpoint. - If VAL_CHAIN is non-NULL, *VAL_CHAIN will be released from the - value chain. The caller must free the values individually. If - VAL_CHAIN is NULL, all generated values will be left on the value - chain. */ + If VAL_CHAIN is non-NULL, the values put into *VAL_CHAIN will be + released from the value chain. If VAL_CHAIN is NULL, all generated + values will be left on the value chain. */ void fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, - struct value **resultp, struct value **val_chain, + struct value **resultp, + std::vector *val_chain, int preserve_errors) { struct value *mark, *new_mark, *result; @@ -195,17 +192,17 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, if (resultp) *resultp = NULL; if (val_chain) - *val_chain = NULL; + val_chain->clear (); /* Evaluate the expression. */ mark = value_mark (); result = NULL; - TRY + try { result = evaluate_subexp (NULL_TYPE, exp, pc, EVAL_NORMAL); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { /* Ignore memory errors if we want watchpoints pointing at inaccessible memory to still be created; otherwise, throw the @@ -215,12 +212,12 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, case MEMORY_ERROR: if (!preserve_errors) break; + /* Fall through. */ default: - throw_exception (ex); + throw; break; } } - END_CATCH new_mark = value_mark (); if (mark == new_mark) @@ -237,15 +234,14 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, else { - TRY + try { value_fetch_lazy (result); *valp = result; } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { } - END_CATCH } } @@ -253,8 +249,7 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp, { /* Return the chain of intermediate values. We use this to decide which addresses to watch. */ - *val_chain = new_mark; - value_release_to_mark (mark); + *val_chain = value_release_to_mark (mark); } } @@ -347,7 +342,7 @@ evaluate_struct_tuple (struct value *struct_val, /* Recursive helper function for setting elements of array tuples. The target is ARRAY (which has bounds LOW_BOUND to HIGH_BOUND); the element value is ELEMENT; EXP, POS and NOSIDE are as usual. - Evaluates index expresions and sets the specified element(s) of + Evaluates index expressions and sets the specified element(s) of ARRAY to ELEMENT. Returns last index value. */ static LONGEST @@ -423,7 +418,7 @@ unop_promote (const struct language_defn *language, struct gdbarch *gdbarch, { default: /* Perform integral promotion for ANSI C/C++. - If not appropropriate for any particular language + If not appropriate for any particular language it needs to modify this function. */ { struct type *builtin_int = builtin_type (gdbarch)->builtin_int; @@ -567,20 +562,20 @@ binop_promote (const struct language_defn *language, struct gdbarch *gdbarch, break; case language_opencl: if (result_len <= TYPE_LENGTH (lookup_signed_typename - (language, gdbarch, "int"))) + (language, "int"))) { promoted_type = (unsigned_operation - ? lookup_unsigned_typename (language, gdbarch, "int") - : lookup_signed_typename (language, gdbarch, "int")); + ? lookup_unsigned_typename (language, "int") + : lookup_signed_typename (language, "int")); } else if (result_len <= TYPE_LENGTH (lookup_signed_typename - (language, gdbarch, "long"))) + (language, "long"))) { promoted_type = (unsigned_operation - ? lookup_unsigned_typename (language, gdbarch, "long") - : lookup_signed_typename (language, gdbarch,"long")); + ? lookup_unsigned_typename (language, "long") + : lookup_signed_typename (language,"long")); } break; default: @@ -683,9 +678,13 @@ fake_method::fake_method (type_instance_flags flags, } } + /* We don't use TYPE_ZALLOC here to allocate space as TYPE is owned by + neither an objfile nor a gdbarch. As a result we must manually + allocate memory for auxiliary fields, and free the memory ourselves + when we are done with it. */ TYPE_NFIELDS (type) = num_types; TYPE_FIELDS (type) = (struct field *) - TYPE_ZALLOC (type, sizeof (struct field) * num_types); + xzalloc (sizeof (struct field) * num_types); while (num_types-- > 0) TYPE_FIELD_TYPE (type, num_types) = param_types[num_types]; @@ -712,19 +711,18 @@ evaluate_var_value (enum noside noside, const block *blk, symbol *var) struct value *ret = NULL; - TRY + try { ret = value_of_variable (var, blk); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { if (noside != EVAL_AVOID_SIDE_EFFECTS) - throw_exception (except); + throw; ret = value_zero (SYMBOL_TYPE (var), not_lval); } - END_CATCH return ret; } @@ -735,17 +733,13 @@ value * evaluate_var_msym_value (enum noside noside, struct objfile *objfile, minimal_symbol *msymbol) { - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - type *the_type = find_minsym_type_and_address (msymbol, objfile, NULL); - return value_zero (the_type, not_lval); - } + CORE_ADDR address; + type *the_type = find_minsym_type_and_address (msymbol, objfile, &address); + + if (noside == EVAL_AVOID_SIDE_EFFECTS && !TYPE_GNU_IFUNC (the_type)) + return value_zero (the_type, not_lval); else - { - CORE_ADDR address; - type *the_type = find_minsym_type_and_address (msymbol, objfile, &address); - return value_at_lazy (the_type, address); - } + return value_at_lazy (the_type, address); } /* Helper for returning a value when handling EVAL_SKIP. */ @@ -789,7 +783,9 @@ eval_call (expression *exp, enum noside noside, else if (TYPE_CODE (ftype) == TYPE_CODE_XMETHOD) { type *return_type - = result_type_of_xmethod (argvec[0], nargs, argvec + 1); + = result_type_of_xmethod (argvec[0], + gdb::make_array_view (argvec + 1, + nargs)); if (return_type == NULL) error (_("Xmethod is missing return type.")); @@ -798,6 +794,15 @@ eval_call (expression *exp, enum noside noside, else if (TYPE_CODE (ftype) == TYPE_CODE_FUNC || TYPE_CODE (ftype) == TYPE_CODE_METHOD) { + if (TYPE_GNU_IFUNC (ftype)) + { + CORE_ADDR address = value_address (argvec[0]); + type *resolved_type = find_gnu_ifunc_target_type (address); + + if (resolved_type != NULL) + ftype = resolved_type; + } + type *return_type = TYPE_TARGET_TYPE (ftype); if (return_type == NULL) @@ -818,10 +823,10 @@ eval_call (expression *exp, enum noside noside, return call_internal_function (exp->gdbarch, exp->language_defn, argvec[0], nargs, argvec + 1); case TYPE_CODE_XMETHOD: - return call_xmethod (argvec[0], nargs, argvec + 1); + return call_xmethod (argvec[0], gdb::make_array_view (argvec + 1, nargs)); default: return call_function_by_hand (argvec[0], default_return_type, - nargs, argvec + 1); + gdb::make_array_view (argvec + 1, nargs)); } } @@ -946,19 +951,18 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos, while (unop_user_defined_p (op, arg2)) { struct value *value = NULL; - TRY + try { value = value_x_unop (arg2, op, noside); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { if (except.error == NOT_FOUND_ERROR) break; else - throw_exception (except); + throw; } - END_CATCH arg2 = value; } @@ -985,13 +989,13 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos, function_name = NULL; if (TYPE_CODE (type) == TYPE_CODE_NAMESPACE) { - function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type), + function = cp_lookup_symbol_namespace (TYPE_NAME (type), name, get_selected_block (0), VAR_DOMAIN).symbol; if (function == NULL) error (_("No symbol \"%s\" in namespace \"%s\"."), - name, TYPE_TAG_NAME (type)); + name, TYPE_NAME (type)); tem = 1; /* arg2 is left as NULL on purpose. */ @@ -1040,12 +1044,12 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos, if (op == OP_VAR_MSYM_VALUE) { minimal_symbol *msym = exp->elts[*pos + 2].msymbol; - var_func_name = MSYMBOL_PRINT_NAME (msym); + var_func_name = msym->print_name (); } else if (op == OP_VAR_VALUE) { symbol *sym = exp->elts[*pos + 2].symbol; - var_func_name = SYMBOL_PRINT_NAME (sym); + var_func_name = sym->print_name (); } argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside); @@ -1091,7 +1095,8 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos, func_name = (char *) alloca (name_len + 1); strcpy (func_name, &exp->elts[string_pc + 1].string); - find_overload_match (&argvec[1], nargs, func_name, + find_overload_match (gdb::make_array_view (&argvec[1], nargs), + func_name, NON_METHOD, /* not method */ NULL, NULL, /* pass NULL symbol since symbol is unknown */ @@ -1127,7 +1132,8 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos, evaluation. */ struct value *valp = NULL; - (void) find_overload_match (&argvec[1], nargs, tstr, + (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs), + tstr, METHOD, /* method */ &arg2, /* the object */ NULL, &valp, NULL, @@ -1198,7 +1204,7 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos, if (op == OP_VAR_VALUE) function = exp->elts[save_pos1+2].symbol; - (void) find_overload_match (&argvec[1], nargs, + (void) find_overload_match (gdb::make_array_view (&argvec[1], nargs), NULL, /* no need for name */ NON_METHOD, /* not method */ NULL, function, /* the function */ @@ -1229,6 +1235,19 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos, return eval_call (exp, noside, nargs, argvec, var_func_name, expect_type); } +/* Helper for skipping all the arguments in an undetermined argument list. + This function was designed for use in the OP_F77_UNDETERMINED_ARGLIST + case of evaluate_subexp_standard as multiple, but not all, code paths + require a generic skip. */ + +static void +skip_undetermined_arglist (int nargs, struct expression *exp, int *pos, + enum noside noside) +{ + for (int i = 0; i < nargs; ++i) + evaluate_subexp (NULL_TYPE, exp, pos, noside); +} + struct value * evaluate_subexp_standard (struct type *expect_type, struct expression *exp, int *pos, @@ -1277,16 +1296,19 @@ evaluate_subexp_standard (struct type *expect_type, case OP_ADL_FUNC: case OP_VAR_VALUE: - (*pos) += 3; - if (noside == EVAL_SKIP) - return eval_skip_value (exp); - { + (*pos) += 3; symbol *var = exp->elts[pc + 2].symbol; if (TYPE_CODE (SYMBOL_TYPE (var)) == TYPE_CODE_ERROR) - error_unknown_type (SYMBOL_PRINT_NAME (var)); - - return evaluate_var_value (noside, exp->elts[pc + 1].block, var); + error_unknown_type (var->print_name ()); + if (noside != EVAL_SKIP) + return evaluate_var_value (noside, exp->elts[pc + 1].block, var); + else + { + /* Return a dummy value of the correct type when skipping, so + that parent functions know what is to be skipped. */ + return allocate_value (SYMBOL_TYPE (var)); + } } case OP_VAR_MSYM_VALUE: @@ -1301,7 +1323,7 @@ evaluate_subexp_standard (struct type *expect_type, type = value_type (val); if (TYPE_CODE (type) == TYPE_CODE_ERROR && (noside != EVAL_AVOID_SIDE_EFFECTS || pc != 0)) - error_unknown_type (MSYMBOL_PRINT_NAME (msymbol)); + error_unknown_type (msymbol->print_name ()); return val; } @@ -1320,7 +1342,7 @@ evaluate_subexp_standard (struct type *expect_type, if (SYMBOL_COMPUTED_OPS (sym) == NULL || SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry == NULL) error (_("Symbol \"%s\" does not have any specific entry value"), - SYMBOL_PRINT_NAME (sym)); + sym->print_name ()); frame = get_selected_frame (NULL); return SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry (sym, frame); @@ -1370,8 +1392,7 @@ evaluate_subexp_standard (struct type *expect_type, So for these registers, we fetch the register value regardless of the evaluation mode. */ if (noside == EVAL_AVOID_SIDE_EFFECTS - && regno < gdbarch_num_regs (exp->gdbarch) - + gdbarch_num_pseudo_regs (exp->gdbarch)) + && regno < gdbarch_num_cooked_regs (exp->gdbarch)) val = value_zero (register_type (exp->gdbarch, regno), not_lval); else val = value_of_register (regno, get_selected_frame (NULL)); @@ -1526,7 +1547,7 @@ evaluate_subexp_standard (struct type *expect_type, { int bit_index = (unsigned) range_low % TARGET_CHAR_BIT; - if (gdbarch_bits_big_endian (exp->gdbarch)) + if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG) bit_index = TARGET_CHAR_BIT - 1 - bit_index; valaddr[(unsigned) range_low / TARGET_CHAR_BIT] |= 1 << bit_index; @@ -1649,7 +1670,7 @@ evaluate_subexp_standard (struct type *expect_type, only). */ if (gnu_runtime) { - struct type *type = selector_type; + type = selector_type; type = lookup_function_type (type); type = lookup_pointer_type (type); @@ -1704,12 +1725,12 @@ evaluate_subexp_standard (struct type *expect_type, argvec[3] = value_from_longest (long_type, selector); argvec[4] = 0; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); if (gnu_runtime) { /* Function objc_msg_lookup returns a pointer. */ argvec[0] = ret; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); } if (value_as_long (ret) == 0) error (_("Target does not respond to this message selector.")); @@ -1726,11 +1747,11 @@ evaluate_subexp_standard (struct type *expect_type, argvec[3] = value_from_longest (long_type, selector); argvec[4] = 0; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); if (gnu_runtime) { argvec[0] = ret; - ret = call_function_by_hand (argvec[0], NULL, 3, argvec + 1); + ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3}); } /* ret should now be the selector. */ @@ -1743,7 +1764,7 @@ evaluate_subexp_standard (struct type *expect_type, /* The address might point to a function descriptor; resolve it to the actual code address instead. */ addr = gdbarch_convert_from_func_ptr_addr (exp->gdbarch, addr, - ¤t_target); + current_top_target ()); /* Is it a high_level symbol? */ sym = find_pc_function (addr); @@ -1836,18 +1857,18 @@ evaluate_subexp_standard (struct type *expect_type, it's opinion (ie. through "whatis"), it won't offer it. */ - struct type *type = value_type (called_method); + struct type *callee_type = value_type (called_method); - if (type && TYPE_CODE (type) == TYPE_CODE_PTR) - type = TYPE_TARGET_TYPE (type); - type = TYPE_TARGET_TYPE (type); + if (callee_type && TYPE_CODE (callee_type) == TYPE_CODE_PTR) + callee_type = TYPE_TARGET_TYPE (callee_type); + callee_type = TYPE_TARGET_TYPE (callee_type); - if (type) + if (callee_type) { - if ((TYPE_CODE (type) == TYPE_CODE_ERROR) && expect_type) + if ((TYPE_CODE (callee_type) == TYPE_CODE_ERROR) && expect_type) return allocate_value (expect_type); else - return allocate_value (type); + return allocate_value (callee_type); } else error (_("Expression of type other than " @@ -1866,17 +1887,17 @@ evaluate_subexp_standard (struct type *expect_type, argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside); argvec[tem + 3] = 0; + auto call_args = gdb::make_array_view (argvec + 1, nargs + 2); + if (gnu_runtime && (method != NULL)) { /* Function objc_msg_lookup returns a pointer. */ deprecated_set_value_type (argvec[0], lookup_pointer_type (lookup_function_type (value_type (argvec[0])))); - argvec[0] - = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1); + argvec[0] = call_function_by_hand (argvec[0], NULL, call_args); } - ret = call_function_by_hand (argvec[0], NULL, nargs + 2, argvec + 1); - return ret; + return call_function_by_hand (argvec[0], NULL, call_args); } break; @@ -1924,19 +1945,34 @@ evaluate_subexp_standard (struct type *expect_type, if (exp->elts[*pos].opcode == OP_RANGE) return value_f90_subarray (arg1, exp, pos, noside); else - goto multi_f77_subscript; + { + if (noside == EVAL_SKIP) + { + skip_undetermined_arglist (nargs, exp, pos, noside); + /* Return the dummy value with the correct type. */ + return arg1; + } + goto multi_f77_subscript; + } case TYPE_CODE_STRING: if (exp->elts[*pos].opcode == OP_RANGE) return value_f90_subarray (arg1, exp, pos, noside); else { + if (noside == EVAL_SKIP) + { + skip_undetermined_arglist (nargs, exp, pos, noside); + /* Return the dummy value with the correct type. */ + return arg1; + } arg2 = evaluate_subexp_with_coercion (exp, pos, noside); return value_subscript (arg1, value_as_long (arg2)); } case TYPE_CODE_PTR: case TYPE_CODE_FUNC: + case TYPE_CODE_INTERNAL_FUNCTION: /* It's a function call. */ /* Allocate arg vector, including space for the function to be called in argvec[0] and a terminating NULL. */ @@ -1945,7 +1981,23 @@ evaluate_subexp_standard (struct type *expect_type, argvec[0] = arg1; tem = 1; for (; tem <= nargs; tem++) - argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); + { + argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); + /* Arguments in Fortran are passed by address. Coerce the + arguments here rather than in value_arg_coerce as otherwise + the call to malloc to place the non-lvalue parameters in + target memory is hit by this Fortran specific logic. This + results in malloc being called with a pointer to an integer + followed by an attempt to malloc the arguments to malloc in + target memory. Infinite recursion ensues. */ + if (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC) + { + bool is_artificial + = TYPE_FIELD_ARTIFICIAL (value_type (arg1), tem - 1); + argvec[tem] = fortran_argument_convert (argvec[tem], + is_artificial); + } + } argvec[tem] = 0; /* signal end of arglist */ if (noside == EVAL_SKIP) return eval_skip_value (exp); @@ -1988,19 +2040,18 @@ evaluate_subexp_standard (struct type *expect_type, while (unop_user_defined_p (op, arg1)) { struct value *value = NULL; - TRY + try { value = value_x_unop (arg1, op, noside); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { if (except.error == NOT_FOUND_ERROR) break; else - throw_exception (except); + throw; } - END_CATCH arg1 = value; } @@ -2009,15 +2060,15 @@ evaluate_subexp_standard (struct type *expect_type, with rtti type in order to continue on with successful lookup of member / method only available in the rtti type. */ { - struct type *type = value_type (arg1); + struct type *arg_type = value_type (arg1); struct type *real_type; int full, using_enc; LONGEST top; struct value_print_options opts; get_user_print_options (&opts); - if (opts.objectprint && TYPE_TARGET_TYPE(type) - && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)) + if (opts.objectprint && TYPE_TARGET_TYPE (arg_type) + && (TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_STRUCT)) { real_type = value_rtti_indirect_type (arg1, &full, &top, &using_enc); @@ -2082,9 +2133,10 @@ evaluate_subexp_standard (struct type *expect_type, for (ix = 0; ix < nargs; ++ix) arg_types[ix] = exp->elts[pc + 2 + ix + 1].type; - fake_method expect_type (flags, nargs, arg_types); + fake_method fake_expect_type (flags, nargs, arg_types); *(pos) += 4 + nargs; - return evaluate_subexp_standard (expect_type.type (), exp, pos, noside); + return evaluate_subexp_standard (fake_expect_type.type (), exp, pos, + noside); } case BINOP_CONCAT: @@ -2099,7 +2151,14 @@ evaluate_subexp_standard (struct type *expect_type, case BINOP_ASSIGN: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); + /* Special-case assignments where the left-hand-side is a + convenience variable -- in these, don't bother setting an + expected type. This avoids a weird case where re-assigning a + string or array to an internal variable could error with "Too + many array elements". */ + arg2 = evaluate_subexp (VALUE_LVAL (arg1) == lval_internalvar + ? NULL_TYPE : value_type (arg1), + exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; @@ -2663,6 +2722,18 @@ evaluate_subexp_standard (struct type *expect_type, } return evaluate_subexp_for_sizeof (exp, pos, noside); + case UNOP_ALIGNOF: + { + type = value_type (evaluate_subexp (NULL_TYPE, exp, pos, + EVAL_AVOID_SIDE_EFFECTS)); + /* FIXME: This should be size_t. */ + struct type *size_type = builtin_type (exp->gdbarch)->builtin_int; + ULONGEST align = type_align (type); + if (align == 0) + error (_("could not determine alignment of type")); + return value_from_longest (size_type, align); + } + case UNOP_CAST: (*pos) += 2; type = exp->elts[pc + 1].type; @@ -2853,7 +2924,7 @@ evaluate_subexp_standard (struct type *expect_type, || sub_op == STRUCTOP_PTR || sub_op == OP_SCOPE)) { - struct type *type = value_type (result); + type = value_type (result); if (!TYPE_IS_REFERENCE (type)) { @@ -3127,6 +3198,10 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos, { val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL); type = value_type (val); + if (TYPE_CODE (type) == TYPE_CODE_ARRAY + && is_dynamic_type (TYPE_INDEX_TYPE (type)) + && TYPE_HIGH_BOUND_UNDEFINED (TYPE_INDEX_TYPE (type))) + return allocate_optimized_out_value (size_type); } else (*pos) += 4; @@ -3137,13 +3212,13 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos, (*pos) += 4; minimal_symbol *msymbol = exp->elts[pc + 2].msymbol; - value *val = evaluate_var_msym_value (noside, - exp->elts[pc + 1].objfile, - msymbol); + value *mval = evaluate_var_msym_value (noside, + exp->elts[pc + 1].objfile, + msymbol); - type = value_type (val); + type = value_type (mval); if (TYPE_CODE (type) == TYPE_CODE_ERROR) - error_unknown_type (MSYMBOL_PRINT_NAME (msymbol)); + error_unknown_type (msymbol->print_name ()); return value_from_longest (size_type, TYPE_LENGTH (type)); } @@ -3151,14 +3226,14 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos, /* Deal with the special case if NOSIDE is EVAL_NORMAL and the resulting type of the subscript is a variable length array type. In this case we - must re-evaluate the right hand side of the subcription to allow + must re-evaluate the right hand side of the subscription to allow side-effects. */ case BINOP_SUBSCRIPT: if (noside == EVAL_NORMAL) { - int pc = (*pos) + 1; + int npc = (*pos) + 1; - val = evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS); + val = evaluate_subexp (NULL_TYPE, exp, &npc, EVAL_AVOID_SIDE_EFFECTS); type = check_typedef (value_type (val)); if (TYPE_CODE (type) == TYPE_CODE_ARRAY) {