Re: [RFC PATCH 0/3] Pretty-printing for errno

Pedro Alves <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha,gmane.comp.gdb.devel
Message-ID <[email protected]>
On 06/29/2017 04:48 PM, Phil Muldoon wrote:
> 
> (gdb) p (test_i) i
> $2 = ('typename: ', 'int')
> 
> Which is most puzzling.

Indeed.  No need for printers to see this, actually.

With this code:

 typedef int zzz;
 zzz z;

gdb:

 (gdb) whatis z
 type = zzz
 (gdb) whatis (zzz) z
 type = int

Eh.

I suspect this is the result of a bogus implementation of
only stripping one level of typedef if the argument to
whatis is a type name.  From the manual:

 If @var{arg} is a variable or an expression, @code{whatis} prints its
 literal type as it is used in the source code.  If the type was
 defined using a @code{typedef}, @code{whatis} will @emph{not} print
 the data type underlying the @code{typedef}.
 (...)
 If @var{arg} is a type name that was defined using @code{typedef},
 @code{whatis} @dfn{unrolls} only one level of that @code{typedef}.


That one-level stripping comes from here, in
gdb/eval.c:evaluate_subexp_standard, handling OP_TYPE:

...
     else if (noside == EVAL_AVOID_SIDE_EFFECTS)
	{
	  struct type *type = exp->elts[pc + 1].type;

	  /* If this is a typedef, then find its immediate target.  We
	     use check_typedef to resolve stubs, but we ignore its
	     result because we do not want to dig past all
	     typedefs.  */
	  check_typedef (type);
	  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
	    type = TYPE_TARGET_TYPE (type);
	  return allocate_value (type);
	}

However, this is reachable in both:

#1 - (gdb) whatis (zzz)0
#2 - (gdb) whatis zzz

While only case #2 should strip the typedef.  Removing that "find immediate
target" code above help with fixing #1.  We then run into the fact that
value_cast also drops typedefs.  Fixing that (see patch below) makes
whatis (zzz)0 work as expected:

 (gdb) whatis (zzz)0
 type = zzz

however, we'd need to still make "whatis" strip one level of
typedefs when the argument is a type, somehow, because we now
get this:

 (gdb) whatis zzz
 type = zzz
From 21f3a88611fad22f73aff2217c93d99971dd076f Mon Sep 17 00:00:00 2001
From: Pedro Alves <[email protected]>
Date: Thu, 29 Jun 2017 17:18:32 +0100
Subject: [PATCH] whatis

---
 gdb/eval.c   |  2 ++
 gdb/valops.c | 28 +++++++++++++++-------------
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/gdb/eval.c b/gdb/eval.c
index 2a39774..6aa2499 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2735,8 +2735,10 @@ evaluate_subexp_standard (struct type *expect_type,
 	     result because we do not want to dig past all
 	     typedefs.  */
 	  check_typedef (type);
+#if 0
 	  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
 	    type = TYPE_TARGET_TYPE (type);
+#endif
 	  return allocate_value (type);
 	}
       else
diff --git a/gdb/valops.c b/gdb/valops.c
index 8675e6c..058fe1e 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -378,6 +378,8 @@ value_cast (struct type *type, struct value *arg2)
     /* We deref the value and then do the cast.  */
     return value_cast (type, coerce_ref (arg2)); 
 
+  struct type *org_type = type;
+
   type = check_typedef (type);
   code1 = TYPE_CODE (type);
   arg2 = coerce_ref (arg2);
@@ -452,14 +454,14 @@ value_cast (struct type *type, struct value *arg2)
       && (code2 == TYPE_CODE_STRUCT || code2 == TYPE_CODE_UNION)
       && TYPE_NAME (type) != 0)
     {
-      struct value *v = value_cast_structs (type, arg2);
+      struct value *v = value_cast_structs (org_type, arg2);
 
       if (v)
 	return v;
     }
 
   if (code1 == TYPE_CODE_FLT && scalar)
-    return value_from_double (type, value_as_double (arg2));
+    return value_from_double (org_type, value_as_double (arg2));
   else if (code1 == TYPE_CODE_DECFLOAT && scalar)
     {
       enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type));
@@ -475,7 +477,7 @@ value_cast (struct type *type, struct value *arg2)
 	/* The only option left is an integral type.  */
 	decimal_from_integral (arg2, dec, dec_len, byte_order);
 
-      return value_from_decfloat (type, dec);
+      return value_from_decfloat (org_type, dec);
     }
   else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
 	    || code1 == TYPE_CODE_RANGE)
@@ -496,7 +498,7 @@ value_cast (struct type *type, struct value *arg2)
 		     gdbarch_byte_order (get_type_arch (type2)));
       else
         longest = value_as_long (arg2);
-      return value_from_longest (type, convert_to_boolean ?
+      return value_from_longest (org_type, convert_to_boolean ?
 				 (LONGEST) (longest ? 1 : 0) : longest);
     }
   else if (code1 == TYPE_CODE_PTR && (code2 == TYPE_CODE_INT  
@@ -522,14 +524,14 @@ value_cast (struct type *type, struct value *arg2)
 	      || longest <= -((LONGEST) 1 << addr_bit))
 	    warning (_("value truncated"));
 	}
-      return value_from_longest (type, longest);
+      return value_from_longest (org_type, longest);
     }
   else if (code1 == TYPE_CODE_METHODPTR && code2 == TYPE_CODE_INT
 	   && value_as_long (arg2) == 0)
     {
-      struct value *result = allocate_value (type);
+      struct value *result = allocate_value (org_type);
 
-      cplus_make_method_ptr (type, value_contents_writeable (result), 0, 0);
+      cplus_make_method_ptr (org_type, value_contents_writeable (result), 0, 0);
       return result;
     }
   else if (code1 == TYPE_CODE_MEMBERPTR && code2 == TYPE_CODE_INT
@@ -537,7 +539,7 @@ value_cast (struct type *type, struct value *arg2)
     {
       /* The Itanium C++ ABI represents NULL pointers to members as
 	 minus one, instead of biasing the normal case.  */
-      return value_from_longest (type, -1);
+      return value_from_longest (org_type, -1);
     }
   else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
 	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
@@ -548,21 +550,21 @@ value_cast (struct type *type, struct value *arg2)
     error (_("can only cast scalar to vector of same size"));
   else if (code1 == TYPE_CODE_VOID)
     {
-      return value_zero (type, not_lval);
+      return value_zero (org_type, not_lval);
     }
   else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
     {
       if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
-	return value_cast_pointers (type, arg2, 0);
+	return value_cast_pointers (org_type, arg2, 0);
 
       arg2 = value_copy (arg2);
-      deprecated_set_value_type (arg2, type);
-      set_value_enclosing_type (arg2, type);
+      deprecated_set_value_type (arg2, org_type);
+      set_value_enclosing_type (arg2, org_type);
       set_value_pointed_to_offset (arg2, 0);	/* pai: chk_val */
       return arg2;
     }
   else if (VALUE_LVAL (arg2) == lval_memory)
-    return value_at_lazy (type, value_address (arg2));
+    return value_at_lazy (org_type, value_address (arg2));
   else
     {
       error (_("Invalid cast."));
-- 
2.5.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.