+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 ...
 
 #include "linespec.h"
 #include "location.h"
 #include "objfiles.h"
-
+#include "typeprint.h"
 #include "valprint.h"
 #include "c-lang.h"
 
 }
 \f
 
+/* 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 */
        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;
 
        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;
 
        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;
 
 
 
     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),
 
             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
 
 #include "valprint.h"
 #include "gdb_obstack.h"
 #include "objfiles.h"
+#include "typeprint.h"
 #include <ctype.h>
 
 /* This is defined in valops.c */
 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);
       (*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;
     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);
       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);
        (*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
   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 *
 
   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.  */
                         "<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.
 
+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
 
 }
 
 # 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." \
 
 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)
 {
 
     # 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
     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"
 
       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)"
     }
 
     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
 
 
     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
 
        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"
 
 }
 
 
 
 # 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"
 
 # 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"
 
 }
 
 # 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!
 #
 
 # 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\\)"
 # 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"
 
 
   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.  */
 
 
 
 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);