aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog26
-rw-r--r--gdb/ax-gdb.c50
-rw-r--r--gdb/compile/compile-c-types.c15
-rw-r--r--gdb/dwarf2read.c3
-rw-r--r--gdb/eval.c137
-rw-r--r--gdb/gdbtypes.c19
-rw-r--r--gdb/testsuite/ChangeLog16
-rw-r--r--gdb/testsuite/gdb.asm/asm-source.exp8
-rw-r--r--gdb/testsuite/gdb.base/nodebug.c7
-rw-r--r--gdb/testsuite/gdb.base/nodebug.exp78
-rw-r--r--gdb/testsuite/gdb.base/solib-display.exp16
-rw-r--r--gdb/testsuite/gdb.compile/compile-ifunc.exp5
-rw-r--r--gdb/testsuite/gdb.cp/m-static.exp4
-rw-r--r--gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp2
-rw-r--r--gdb/testsuite/gdb.threads/tls-nodebug.exp5
-rw-r--r--gdb/testsuite/gdb.trace/entry-values.exp6
-rw-r--r--gdb/typeprint.c9
-rw-r--r--gdb/typeprint.h5
18 files changed, 343 insertions, 68 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 7859c64..4e08489 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,31 @@
2017-09-04 Pedro Alves <palves@redhat.com>
+ * ax-gdb.c: Include "typeprint.h".
+ (gen_expr_for_cast): New function.
+ (gen_expr) <OP_CAST, OP_CAST_TYPE>: Use it.
+ <OP_VAR_VALUE, OP_MSYM_VAR_VALUE>: Error out if the variable's
+ type is unknown.
+ * dwarf2read.c (new_symbol_full): Fallback to int instead of
+ nodebug_data_symbol.
+ * eval.c: Include "typeprint.h".
+ (evaluate_subexp_standard) <OP_VAR_VALUE, OP_VAR_MSYM_VALUE>:
+ Error out if symbol has unknown type.
+ <UNOP_CAST, UNOP_CAST_TYPE>: Common bits factored out to
+ evaluate_subexp_for_cast.
+ (evaluate_subexp_for_address, evaluate_subexp_for_sizeof): Handle
+ OP_VAR_MSYM_VALUE.
+ (evaluate_subexp_for_cast): New function.
+ * gdbtypes.c (init_nodebug_var_type): New function.
+ (objfile_type): Use it to initialize types of variables with no
+ debug info.
+ * typeprint.c (error_unknown_type): New.
+ * typeprint.h (error_unknown_type): New declaration.
+ * compile/compile-c-types.c (convert_type_basic): Handle
+ TYPE_CODE_ERROR; warn and fallback to int for variables with
+ unknown type.
+
+2017-09-04 Pedro Alves <palves@redhat.com>
+
* eval.c (evaluate_var_value): New function, factored out from ...
(evaluate_subexp_standard): ... here.
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 3fdf81a..2b5e481 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -42,7 +42,7 @@
#include "linespec.h"
#include "location.h"
#include "objfiles.h"
-
+#include "typeprint.h"
#include "valprint.h"
#include "c-lang.h"
@@ -1765,6 +1765,40 @@ gen_sizeof (struct expression *exp, union exp_element **pc,
}
+/* Generate bytecode for a cast to TO_TYPE. Advance *PC over the
+ subexpression. */
+
+static void
+gen_expr_for_cast (struct expression *exp, union exp_element **pc,
+ struct agent_expr *ax, struct axs_value *value,
+ struct type *to_type)
+{
+ enum exp_opcode op = (*pc)[0].opcode;
+
+ /* Don't let symbols be handled with gen_expr because that throws an
+ "unknown type" error for no-debug data symbols. Instead, we want
+ the cast to reinterpret such symbols. */
+ if (op == OP_VAR_MSYM_VALUE || op == OP_VAR_VALUE)
+ {
+ if (op == OP_VAR_VALUE)
+ {
+ gen_var_ref (ax, value, (*pc)[2].symbol);
+
+ if (value->optimized_out)
+ error (_("`%s' has been optimized out, cannot use"),
+ SYMBOL_PRINT_NAME ((*pc)[2].symbol));
+ }
+ else
+ gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
+ if (TYPE_CODE (value->type) == TYPE_CODE_ERROR)
+ value->type = to_type;
+ (*pc) += 4;
+ }
+ else
+ gen_expr (exp, pc, ax, value);
+ gen_cast (ax, value, to_type);
+}
+
/* Generating bytecode from GDB expressions: general recursive thingy */
/* XXX: i18n */
@@ -1978,11 +2012,18 @@ gen_expr (struct expression *exp, union exp_element **pc,
error (_("`%s' has been optimized out, cannot use"),
SYMBOL_PRINT_NAME ((*pc)[2].symbol));
+ if (TYPE_CODE (value->type) == TYPE_CODE_ERROR)
+ error_unknown_type (SYMBOL_PRINT_NAME ((*pc)[2].symbol));
+
(*pc) += 4;
break;
case OP_VAR_MSYM_VALUE:
gen_msym_var_ref (ax, value, (*pc)[2].msymbol, (*pc)[1].objfile);
+
+ if (TYPE_CODE (value->type) == TYPE_CODE_ERROR)
+ error_unknown_type (MSYMBOL_PRINT_NAME ((*pc)[2].msymbol));
+
(*pc) += 4;
break;
@@ -2043,8 +2084,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
struct type *type = (*pc)[1].type;
(*pc) += 3;
- gen_expr (exp, pc, ax, value);
- gen_cast (ax, value, type);
+ gen_expr_for_cast (exp, pc, ax, value, type);
}
break;
@@ -2059,9 +2099,7 @@ gen_expr (struct expression *exp, union exp_element **pc,
val = evaluate_subexp (NULL, exp, &offset, EVAL_AVOID_SIDE_EFFECTS);
type = value_type (val);
*pc = &exp->elts[offset];
-
- gen_expr (exp, pc, ax, value);
- gen_cast (ax, value, type);
+ gen_expr_for_cast (exp, pc, ax, value, type);
}
break;
diff --git a/gdb/compile/compile-c-types.c b/gdb/compile/compile-c-types.c
index 2bfa72d..b53a3c4 100644
--- a/gdb/compile/compile-c-types.c
+++ b/gdb/compile/compile-c-types.c
@@ -383,6 +383,21 @@ convert_type_basic (struct compile_c_instance *context, struct type *type)
case TYPE_CODE_COMPLEX:
return convert_complex (context, type);
+
+ case TYPE_CODE_ERROR:
+ {
+ /* Ideally, if we get here due to a cast expression, we'd use
+ the cast-to type as the variable's type, like GDB's
+ built-in parser does. For now, assume "int" like GDB's
+ built-in parser used to do, but at least warn. */
+ struct type *fallback;
+ if (TYPE_OBJFILE_OWNED (type))
+ fallback = objfile_type (TYPE_OWNER (type).objfile)->builtin_int;
+ else
+ fallback = builtin_type (TYPE_OWNER (type).gdbarch)->builtin_int;
+ warning (_("variable has unknown type; assuming int"));
+ return convert_int (context, fallback);
+ }
}
return C_CTX (context)->c_ops->error (C_CTX (context),
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ead4f3c..893e04d 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -19139,8 +19139,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
variables with missing type entries. Change the
misleading `void' type to something sensible. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
- SYMBOL_TYPE (sym)
- = objfile_type (objfile)->nodebug_data_symbol;
+ SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
attr = dwarf2_attr (die, DW_AT_const_value, cu);
/* In the case of DW_TAG_member, we should only be called for
diff --git a/gdb/eval.c b/gdb/eval.c
index a97f4a9..75d3c86 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -39,6 +39,7 @@
#include "valprint.h"
#include "gdb_obstack.h"
#include "objfiles.h"
+#include "typeprint.h"
#include <ctype.h>
/* This is defined in valops.c */
@@ -52,6 +53,10 @@ static struct value *evaluate_subexp_for_sizeof (struct expression *, int *,
static struct value *evaluate_subexp_for_address (struct expression *,
int *, enum noside);
+static value *evaluate_subexp_for_cast (expression *exp, int *pos,
+ enum noside noside,
+ struct type *type);
+
static struct value *evaluate_struct_tuple (struct value *,
struct expression *, int *,
enum noside, int);
@@ -796,14 +801,30 @@ evaluate_subexp_standard (struct type *expect_type,
(*pos) += 3;
if (noside == EVAL_SKIP)
return eval_skip_value (exp);
- return evaluate_var_value (noside,
- exp->elts[pc + 1].block,
- exp->elts[pc + 2].symbol);
+
+ {
+ 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);
+ }
+
case OP_VAR_MSYM_VALUE:
- (*pos) += 3;
- return evaluate_var_msym_value (noside,
- exp->elts[pc + 1].objfile,
- exp->elts[pc + 2].msymbol);
+ {
+ (*pos) += 3;
+
+ minimal_symbol *msymbol = exp->elts[pc + 2].msymbol;
+ value *val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ msymbol);
+
+ 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));
+ return val;
+ }
case OP_VAR_ENTRY_VALUE:
(*pos) += 2;
@@ -2589,22 +2610,12 @@ evaluate_subexp_standard (struct type *expect_type,
case UNOP_CAST:
(*pos) += 2;
type = exp->elts[pc + 1].type;
- arg1 = evaluate_subexp (type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
- if (type != value_type (arg1))
- arg1 = value_cast (type, arg1);
- return arg1;
+ return evaluate_subexp_for_cast (exp, pos, noside, type);
case UNOP_CAST_TYPE:
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
type = value_type (arg1);
- arg1 = evaluate_subexp (type, exp, pos, noside);
- if (noside == EVAL_SKIP)
- return eval_skip_value (exp);
- if (type != value_type (arg1))
- arg1 = value_cast (type, arg1);
- return arg1;
+ return evaluate_subexp_for_cast (exp, pos, noside, type);
case UNOP_DYNAMIC_CAST:
arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
@@ -2927,6 +2938,22 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
else
return address_of_variable (var, exp->elts[pc + 1].block);
+ case OP_VAR_MSYM_VALUE:
+ {
+ (*pos) += 4;
+
+ value *val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ exp->elts[pc + 2].msymbol);
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ struct type *type = lookup_pointer_type (value_type (val));
+ return value_zero (type, not_lval);
+ }
+ else
+ return value_addr (val);
+ }
+
case OP_SCOPE:
tem = longest_to_int (exp->elts[pc + 2].longconst);
(*pos) += 5 + BYTES_TO_EXP_ELEM (tem + 1);
@@ -3065,6 +3092,23 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
(*pos) += 4;
break;
+ case OP_VAR_MSYM_VALUE:
+ {
+ (*pos) += 4;
+
+ minimal_symbol *msymbol = exp->elts[pc + 2].msymbol;
+ value *val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ msymbol);
+
+ type = value_type (val);
+ if (TYPE_CODE (type) == TYPE_CODE_ERROR)
+ error_unknown_type (MSYMBOL_PRINT_NAME (msymbol));
+
+ return value_from_longest (size_type, TYPE_LENGTH (type));
+ }
+ break;
+
/* 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
@@ -3112,6 +3156,61 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
}
+/* Evaluate a subexpression of EXP, at index *POS, and return a value
+ for that subexpression cast to TO_TYPE. Advance *POS over the
+ subexpression. */
+
+static value *
+evaluate_subexp_for_cast (expression *exp, int *pos,
+ enum noside noside,
+ struct type *to_type)
+{
+ int pc = *pos;
+
+ /* Don't let symbols be evaluated with evaluate_subexp because that
+ throws an "unknown type" error for no-debug data symbols.
+ Instead, we want the cast to reinterpret the symbol. */
+ if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE
+ || exp->elts[pc].opcode == OP_VAR_VALUE)
+ {
+ (*pos) += 4;
+
+ value *val;
+ if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (to_type, not_lval);
+
+ val = evaluate_var_msym_value (noside,
+ exp->elts[pc + 1].objfile,
+ exp->elts[pc + 2].msymbol);
+ }
+ else
+ val = evaluate_var_value (noside,
+ exp->elts[pc + 1].block,
+ exp->elts[pc + 2].symbol);
+
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+
+ val = value_cast (to_type, val);
+
+ /* Don't allow e.g. '&(int)var_with_no_debug_info'. */
+ if (VALUE_LVAL (val) == lval_memory)
+ {
+ if (value_lazy (val))
+ value_fetch_lazy (val);
+ VALUE_LVAL (val) = not_lval;
+ }
+ return val;
+ }
+
+ value *val = evaluate_subexp (to_type, exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ return eval_skip_value (exp);
+ return value_cast (to_type, val);
+}
+
/* Parse a type expression in the string [P..P+LENGTH). */
struct type *
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index a22f0ca..fc86225 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -2770,6 +2770,16 @@ init_type (struct objfile *objfile, enum type_code code, int length,
return type;
}
+/* Allocate a TYPE_CODE_ERROR type structure associated with OBJFILE,
+ to use with variables that have no debug info. NAME is the type
+ name. */
+
+static struct type *
+init_nodebug_var_type (struct objfile *objfile, const char *name)
+{
+ return init_type (objfile, TYPE_CODE_ERROR, 0, name);
+}
+
/* Allocate a TYPE_CODE_INT type structure associated with OBJFILE.
BIT is the type size in bits. If UNSIGNED_P is non-zero, set
the type's TYPE_UNSIGNED flag. NAME is the type name. */
@@ -5325,14 +5335,11 @@ objfile_type (struct objfile *objfile)
"<text from jump slot in .got.plt, no debug info>",
objfile_type->nodebug_text_symbol);
objfile_type->nodebug_data_symbol
- = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0,
- "<data variable, no debug info>");
+ = init_nodebug_var_type (objfile, "<data variable, no debug info>");
objfile_type->nodebug_unknown_symbol
- = init_integer_type (objfile, TARGET_CHAR_BIT, 0,
- "<variable (not text or data), no debug info>");
+ = init_nodebug_var_type (objfile, "<variable (not text or data), no debug info>");
objfile_type->nodebug_tls_symbol
- = init_integer_type (objfile, gdbarch_int_bit (gdbarch), 0,
- "<thread local variable, no debug info>");
+ = init_nodebug_var_type (objfile, "<thread local variable, no debug info>");
/* NOTE: on some targets, addresses and pointers are not necessarily
the same.
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 5457aa1..072423d 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,21 @@
2017-09-04 Pedro Alves <palves@redhat.com>
+ * gdb.asm/asm-source.exp: Add casts to int.
+ * gdb.base/nodebug.c (dataglobal8, dataglobal32_1, dataglobal32_2)
+ (dataglobal64_1, dataglobal64_2): New globals.
+ * gdb.base/nodebug.exp: Test different expressions involving the
+ new globals, with print, whatis and ptype. Add casts to int.
+ * gdb.base/solib-display.exp: Add casts to int.
+ * gdb.compile/compile-ifunc.exp: Expect warning. Add cast to int.
+ * gdb.cp/m-static.exp: Add cast to int.
+ * gdb.dwarf2/dw2-skip-prologue.exp: Add cast to int.
+ * gdb.threads/tls-nodebug.exp: Check that gdb errors out printing
+ tls variable with no debug info without a cast. Test with a cast
+ to int too.
+ * gdb.trace/entry-values.exp: Add casts.
+
+2017-09-04 Pedro Alves <palves@redhat.com>
+
* gdb.base/nodebug.exp: Test that ptype's error about functions
with unknown return type includes the function name too.
diff --git a/gdb/testsuite/gdb.asm/asm-source.exp b/gdb/testsuite/gdb.asm/asm-source.exp
index e07e554..138609a 100644
--- a/gdb/testsuite/gdb.asm/asm-source.exp
+++ b/gdb/testsuite/gdb.asm/asm-source.exp
@@ -465,14 +465,14 @@ proc test_dis { command var } {
}
# See if we can look at a global variable, three ways
-gdb_test "print globalvar" ".* = 11" "look at global variable"
+gdb_test "print (int) globalvar" ".* = 11" "look at global variable"
test_dis "x/i &globalvar" "globalvar"
-test_dis "disassem &globalvar, &globalvar+1" "globalvar"
+test_dis "disassem &globalvar, (int *) &globalvar+1" "globalvar"
# See if we can look at a static variable, three ways
-gdb_test "print staticvar" ".* = 5" "look at static variable"
+gdb_test "print (int) staticvar" ".* = 5" "look at static variable"
test_dis "x/i &staticvar" "staticvar"
-test_dis "disassem &staticvar, &staticvar+1" "staticvar"
+test_dis "disassem &staticvar, (int *) &staticvar+1" "staticvar"
# See if we can look at a static function
gdb_test "disassem foostatic" ".*<\\+0>:.*End of assembler dump." \
diff --git a/gdb/testsuite/gdb.base/nodebug.c b/gdb/testsuite/gdb.base/nodebug.c
index 99641e8..c7bc939 100644
--- a/gdb/testsuite/gdb.base/nodebug.c
+++ b/gdb/testsuite/gdb.base/nodebug.c
@@ -8,6 +8,13 @@ static int datalocal = 4; /* Should go in local data */
int bssglobal; /* Should go in global bss */
static int bsslocal; /* Should go in local bss */
+/* Non-int-sized global data variables. */
+uint8_t dataglobal8 = 0xff;
+uint32_t dataglobal32_1 = 0x7fffffff;
+uint32_t dataglobal32_2 = 0x000000ff;
+uint64_t dataglobal64_1 = 0x7fffffffffffffff;
+uint64_t dataglobal64_2 = 0x00000000000000ff;
+
int
inner (int x)
{
diff --git a/gdb/testsuite/gdb.base/nodebug.exp b/gdb/testsuite/gdb.base/nodebug.exp
index da704f1..2099456 100644
--- a/gdb/testsuite/gdb.base/nodebug.exp
+++ b/gdb/testsuite/gdb.base/nodebug.exp
@@ -152,11 +152,57 @@ if [runto inner] then {
# we may or may not have debug info for those (depending on
# whether we have debug info for the C runtime, for example).
gdb_test_no_output "macro define uint8 unsigned char"
-
- gdb_test "p dataglobal" "= 3"
- gdb_test "whatis dataglobal" \
- "<(data variable|variable), no debug info>|int"
- gdb_test "ptype dataglobal" "<(data variable|variable), no debug info>|int"
+ gdb_test_no_output "macro define uint32 unsigned int"
+ gdb_test_no_output "macro define uint64 unsigned long long"
+
+ set data_var_type "<data variable, no debug info>"
+ set unk_type_re "has unknown type.*to its declared type"
+ set ptr_math_re "Cannot perform pointer math on incomplete type \"$data_var_type\", try casting to a known type, or void \\*\\."
+ set not_mem_re "Attempt to take address of value not located in memory\\."
+
+ set dataglobal_unk_re "dataglobal.*$unk_type_re"
+
+ #exp #fmt #print #ptype/whatis
+ foreach line {
+ {"dataglobal" "" $dataglobal_unk_re " = $data_var_type"}
+ {"(int) dataglobal" "" "= 3" " = int"}
+ {"sizeof(dataglobal)" "" $dataglobal_unk_re $dataglobal_unk_re}
+ {"sizeof(dataglobal + 1)" "" $dataglobal_unk_re $dataglobal_unk_re}
+ {"sizeof((int) dataglobal)" "" " = $decimal" " = int"}
+ {"dataglobal + 1" "" $dataglobal_unk_re $dataglobal_unk_re}
+ {"&dataglobal" "" "\\($data_var_type \\*\\) $hex <dataglobal>" " = $data_var_type \\*"}
+ {"&dataglobal + 1" "" $ptr_math_re $ptr_math_re}
+ {"(int *) &dataglobal + 1" "" " = \\(int \\*\\) $hex <datalocal>" "int \\*"}
+ {"&(int) dataglobal + 1" "" $not_mem_re $not_mem_re}
+ {"&dataglobal, &dataglobal" "" "\\($data_var_type \\*\\) $hex <dataglobal>" " = $data_var_type \\*"}
+ {"*dataglobal" "" $dataglobal_unk_re $dataglobal_unk_re}
+
+ {"dataglobal8" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint8) dataglobal8" "/x" " = 0xff" "unsigned char"}
+
+ {"dataglobal32_1" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint32) dataglobal32_1" "/x" " = 0x7fffffff" "unsigned int"}
+ {"dataglobal32_2" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint32) dataglobal32_2" "/x" " = 0xff" "unsigned int"}
+
+ {"dataglobal64_1" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint64) dataglobal64_1" "/x" " = 0x7fffffffffffffff" "unsigned long long"}
+ {"dataglobal64_2" "/x" $dataglobal_unk_re " = $data_var_type"}
+ {"(uint64) dataglobal64_2" "/x" " = 0xff" "unsigned long long"}
+ } {
+ set exp [lindex $line 0]
+ # Expand variables.
+ set fmt [subst -nobackslashes [lindex $line 1]]
+ set print [subst -nobackslashes [lindex $line 2]]
+ set whatis [subst -nobackslashes [lindex $line 3]]
+ if {$fmt == ""} {
+ gdb_test "p $exp" $print
+ } else {
+ gdb_test "p $fmt $exp" $print
+ }
+ gdb_test "whatis $exp" $whatis
+ gdb_test "ptype $exp" $whatis
+ }
# The only symbol xcoff puts out for statics is for the TOC entry.
# Possible, but hairy, for gdb to deal. Right now it doesn't, it
@@ -164,35 +210,39 @@ if [runto inner] then {
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "p datalocal" "= 4"
+ gdb_test "p datalocal" "datalocal.*$unk_type_re"
+ gdb_test "p (int) datalocal" "= 4"
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "whatis datalocal" "<(data variable|variable), no debug info>"
+ gdb_test "whatis datalocal" "datalocal.*$data_var_type"
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "ptype datalocal" "<(data variable|variable), no debug info>"
- gdb_test "p bssglobal" "= 0"
- gdb_test "whatis bssglobal" "<(data variable|variable), no debug info>|int"
- gdb_test "ptype bssglobal" "<(data variable|variable), no debug info>|int"
+ gdb_test "ptype datalocal" "datalocal.*$data_var_type"
+
+ gdb_test "p bssglobal" "bssglobal.*$unk_type_re"
+ gdb_test "p (int) bssglobal" "= 0"
+ gdb_test "whatis bssglobal" $data_var_type
+ gdb_test "ptype bssglobal" $data_var_type
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "p bsslocal" "= 0"
+ gdb_test "p bsslocal" "bsslocal.*$unk_type_re"
+ gdb_test "p (int) bsslocal" "= 0"
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "whatis bsslocal" "<(data variable|variable), no debug info>"
+ gdb_test "whatis bsslocal" $data_var_type
setup_xfail "rs6000*-*-aix*"
setup_xfail "powerpc*-*-aix*"
- gdb_test "ptype bsslocal" "<(data variable|variable), no debug info>"
+ gdb_test "ptype bsslocal" $data_var_type
gdb_test "backtrace 10" "#0.*inner.*#1.*middle.*#2.*top.*#3.*main.*" \
"backtrace from inner in nodebug.exp"
diff --git a/gdb/testsuite/gdb.base/solib-display.exp b/gdb/testsuite/gdb.base/solib-display.exp
index 1e26853..6df9f26 100644
--- a/gdb/testsuite/gdb.base/solib-display.exp
+++ b/gdb/testsuite/gdb.base/solib-display.exp
@@ -94,9 +94,9 @@ foreach libsepdebug {NO IN SEP} { with_test_prefix "$libsepdebug" {
return 0
}
- gdb_test "display a_global" "1: a_global = 41"
- gdb_test "display b_global" "2: b_global = 42"
- gdb_test "display c_global" "3: c_global = 43"
+ gdb_test "display (int) a_global" "1: \\(int\\) a_global = 41"
+ gdb_test "display (int) b_global" "2: \\(int\\) b_global = 42"
+ gdb_test "display (int) c_global" "3: \\(int\\) c_global = 43"
if { [gdb_start_cmd] < 0 } {
fail "can't run to main (2)"
@@ -104,9 +104,9 @@ foreach libsepdebug {NO IN SEP} { with_test_prefix "$libsepdebug" {
}
gdb_test "" [multi_line \
- "1: a_global = 41" \
- "2: b_global = 42" \
- "3: c_global = 43" \
+ "1: \\(int\\) a_global = 41" \
+ "2: \\(int\\) b_global = 42" \
+ "3: \\(int\\) c_global = 43" \
] "after rerun"
# Now rebuild the library without b_global
@@ -132,9 +132,9 @@ foreach libsepdebug {NO IN SEP} { with_test_prefix "$libsepdebug" {
gdb_test "" [multi_line \
- "1: a_global = 41" \
+ "1: \\(int\\) a_global = 41" \
"warning: .*b_global.*" \
- "3: c_global = 43" \
+ "3: \\(int\\) c_global = 43" \
] "after rerun (2)"
# Now verify that displays which are not in the shared library
diff --git a/gdb/testsuite/gdb.compile/compile-ifunc.exp b/gdb/testsuite/gdb.compile/compile-ifunc.exp
index dc442ff..b591939 100644
--- a/gdb/testsuite/gdb.compile/compile-ifunc.exp
+++ b/gdb/testsuite/gdb.compile/compile-ifunc.exp
@@ -36,9 +36,10 @@ with_test_prefix "nodebug" {
return -1
}
- gdb_test_no_output "compile code resultvar = gnu_ifunc (10);"
+ gdb_test "compile code resultvar = gnu_ifunc (10);" \
+ "warning: variable has unknown type; assuming int"
- gdb_test "p resultvar" " = 11"
+ gdb_test "p (int) resultvar" " = 11"
}
diff --git a/gdb/testsuite/gdb.cp/m-static.exp b/gdb/testsuite/gdb.cp/m-static.exp
index 52eea1a..eeb88e9 100644
--- a/gdb/testsuite/gdb.cp/m-static.exp
+++ b/gdb/testsuite/gdb.cp/m-static.exp
@@ -54,8 +54,8 @@ gdb_continue_to_breakpoint "end of constructors"
# simple object, static const int, accessing via 'class::method::variable'
# Regression test for PR c++/15203 and PR c++/15210
-gdb_test "print 'gnu_obj_1::method()::sintvar'" "\\$\[0-9\]+ = 4" \
- "simple object, static const int, accessing via 'class::method::variable"
+gdb_test "print (int) 'gnu_obj_1::method()::sintvar'" "\\$\[0-9\]+ = 4" \
+ "simple object, static int, accessing via 'class::method::variable'"
# simple object, static const bool
gdb_test "print test1.test" "\\$\[0-9\]* = true" "simple object, static const bool"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
index 458809b..6338e6d 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-skip-prologue.exp
@@ -79,4 +79,4 @@ gdb_continue_to_breakpoint "func"
# Sanity check GDB has really found 2 locations
gdb_test {info break $bpnum} "\r\n2\\.1\[ \t\]\[^\n\]*\r\n2\\.2\[ \t\]\[^\n\]*" "2 locations found"
-gdb_test "p v" " = 0" "no statement got executed"
+gdb_test "p (int) v" " = 0" "no statement got executed"
diff --git a/gdb/testsuite/gdb.threads/tls-nodebug.exp b/gdb/testsuite/gdb.threads/tls-nodebug.exp
index 8dc9444..e718736 100644
--- a/gdb/testsuite/gdb.threads/tls-nodebug.exp
+++ b/gdb/testsuite/gdb.threads/tls-nodebug.exp
@@ -33,7 +33,10 @@ if ![runto_main] then {
}
# Formerly: Cannot access memory at address 0x0
-gdb_test "p thread_local" "= 42" "thread local storage"
+gdb_test "p thread_local" "'thread_local' has unknown type; cast it to its declared type" \
+ "thread local storage, unknown type"
+gdb_test "p (int) thread_local" "= 42" \
+ "thread local storage, cast"
# Done!
#
diff --git a/gdb/testsuite/gdb.trace/entry-values.exp b/gdb/testsuite/gdb.trace/entry-values.exp
index b2650c6..baf9371 100644
--- a/gdb/testsuite/gdb.trace/entry-values.exp
+++ b/gdb/testsuite/gdb.trace/entry-values.exp
@@ -194,8 +194,8 @@ gdb_test_sequence "bt" "bt (1)" {
# Update global variables 'global1' and 'global2' and test that the
# entry values are updated too.
-gdb_test_no_output "set var global1=10"
-gdb_test_no_output "set var global2=11"
+gdb_test_no_output "set var *(int *) &global1=10"
+gdb_test_no_output "set var *(int *) &global2=11"
gdb_test_sequence "bt" "bt (2)" {
"\[\r\n\]#0 .* foo \\(i=[-]?[0-9]+, i@entry=10, j=[-]?[0-9]+, j@entry=11\\)"
@@ -226,7 +226,7 @@ gdb_test "trace foo" "Tracepoint $decimal at .*"
# argument j.
gdb_trace_setactions "set action for tracepoint 1" "" \
- "collect i, j, global1, \(\*\(void \*\*\) \(\$$spreg\)\) @ 128" "^$"
+ "collect i, j, (int) global1, \(\*\(void \*\*\) \(\$$spreg\)\) @ 128" "^$"
gdb_test_no_output "tstart"
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 8e58bf9..0cc6821 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -394,6 +394,15 @@ type_print_unknown_return_type (struct ui_file *stream)
fprintf_filtered (stream, _("<unknown return type>"));
}
+/* See typeprint.h. */
+
+void
+error_unknown_type (const char *sym_print_name)
+{
+ error (_("'%s' has unknown type; cast it to its declared type"),
+ sym_print_name);
+}
+
/* Print type of EXP, or last thing in value history if EXP == NULL.
show is passed to type_print. */
diff --git a/gdb/typeprint.h b/gdb/typeprint.h
index d4e19e5..a458aa4 100644
--- a/gdb/typeprint.h
+++ b/gdb/typeprint.h
@@ -78,6 +78,11 @@ void c_type_print_args (struct type *, struct ui_file *, int, enum language,
void type_print_unknown_return_type (struct ui_file *stream);
+/* Throw an error indicating that the user tried to use a symbol that
+ has unknown type. SYM_PRINT_NAME is the name of the symbol, to be
+ included in the error message. */
+extern void error_unknown_type (const char *sym_print_name);
+
extern void val_print_not_allocated (struct ui_file *stream);
extern void val_print_not_associated (struct ui_file *stream);