This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: fix PR 9164


This patch fixes PR 9164.

The bug is that the result of sizeof has signed type, not unsigned.
The C and C++ standards require an unsigned type here.

This fix defers the choice of type to the language, using the existing
language-arch machinery.  I fixed the C language family, including
ObjC, but I left the other languages unchanged.  I think the language
maintainers will have to make a change here, if one is needed or
desired.  (FWIW I don't think Java needs a change, since I don't think
it is possible to invoke sizeof when Java is the selected language.)

Built and regtested on x86-64 (compile farm).
New test case included.

Please review.

thanks,
Tom

2009-01-03  Tom Tromey  <tromey@redhat.com>

	PR gdb/9164:
	* p-lang.c (pascal_language_arch_info): Initialize
	lai->size_type_default.
	* objc-exp.y (exp): Call language_size_type.
	* m2-lang.c (m2_language_arch_info): Initialize
	lai->size_type_default.
	* language.h (language_size_type): Declare.
	(struct language_arch_info) <size_type_symbol, size_type_default>:
	New fields.
	* language.c (unknown_language_arch_info): Initialize
	lai->size_type_default.
	(language_size_type): New function.
	* jv-lang.c (java_language_arch_info): Initialize
	lai->size_type_default.
	* f-lang.c (f_language_arch_info): Initialize
	lai->size_type_default.
	* eval.c (evaluate_subexp_for_sizeof): Call language_size_type.
	* c-lang.c (find_size_type): New function.
	(c_language_arch_info): Call it.
	(cplus_language_arch_info): Likewise.
	* c-exp.y (exp): Use language_size_type.
	* ada-lang.c (ada_language_arch_info): Initialize
	lai->size_type_default.

2009-01-03  Tom Tromey  <tromey@redhat.com>

	* gdb.base/sizeof.exp (check_sizeof): Verify that sizeof returns
	unsigned type.

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index bcbd709..8571eda 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11000,6 +11000,8 @@ ada_language_arch_info (struct gdbarch *gdbarch,
 
   lai->bool_type_symbol = "boolean";
   lai->bool_type_default = builtin->builtin_bool;
+
+  lai->size_type_default = builtin->builtin_int;
 }
 
 				/* Language vector */
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 0db8c0b..212d7b5 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -558,7 +558,8 @@ exp	:	VARIABLE
 
 exp	:	SIZEOF '(' type ')'	%prec UNARY
 			{ write_exp_elt_opcode (OP_LONG);
-			  write_exp_elt_type (parse_type->builtin_int);
+			  write_exp_elt_type (language_size_type (parse_language,
+								  parse_gdbarch));
 			  CHECK_TYPEDEF ($3);
 			  write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
 			  write_exp_elt_opcode (OP_LONG); }
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index dc7b059..f3020f6 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -223,6 +223,25 @@ const struct op_print c_op_print_tab[] =
   {NULL, 0, 0, 0}
 };
 
+/* A helper function to compute the default size type for C-like
+   languages.  */
+static void
+find_size_type (const struct builtin_type *builtin,
+		struct language_arch_info *lai)
+{
+  lai->size_type_symbol = "size_t";
+
+  /* For the default, pick an unsigned integral type the same width as
+     a data pointer, if possible.  If none match, use unsigned int.  */
+  if (TYPE_LENGTH (builtin->builtin_unsigned_long)
+      == TYPE_LENGTH (builtin->builtin_data_ptr))
+    lai->size_type_default = builtin->builtin_unsigned_long;
+  else if (TYPE_LENGTH (builtin->builtin_unsigned_long_long))
+    lai->size_type_default = builtin->builtin_unsigned_long_long;
+  else
+    lai->size_type_default = builtin->builtin_unsigned_int;
+}
+
 enum c_primitive_types {
   c_primitive_type_int,
   c_primitive_type_long,
@@ -278,6 +297,8 @@ c_language_arch_info (struct gdbarch *gdbarch,
   lai->primitive_type_vector [c_primitive_type_declong] = builtin->builtin_declong;
 
   lai->bool_type_default = builtin->builtin_int;
+
+  find_size_type (builtin, lai);
 }
 
 const struct language_defn c_language_defn =
@@ -396,6 +417,8 @@ cplus_language_arch_info (struct gdbarch *gdbarch,
 
   lai->bool_type_symbol = "bool";
   lai->bool_type_default = builtin->builtin_bool;
+
+  find_size_type (builtin, lai);
 }
 
 const struct language_defn cplus_language_defn =
diff --git a/gdb/eval.c b/gdb/eval.c
index ccb6b74..026795b 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2652,8 +2652,8 @@ evaluate_subexp_with_coercion (struct expression *exp,
 static struct value *
 evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
 {
-  /* FIXME: This should be size_t.  */
-  struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
+  struct type *size_type = language_size_type (exp->language_defn,
+					       exp->gdbarch);
   enum exp_opcode op;
   int pc;
   struct type *type;
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 4d4d4d7..bf4dac5 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -302,6 +302,8 @@ f_language_arch_info (struct gdbarch *gdbarch,
 
   lai->bool_type_symbol = "logical";
   lai->bool_type_default = builtin->builtin_logical_s2;
+
+  lai->size_type_default = builtin_type (gdbarch)->builtin_int;
 }
 
 /* This is declared in c-lang.h but it is silly to import that file for what
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 0470eef..4f75f7b 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -1083,6 +1083,8 @@ java_language_arch_info (struct gdbarch *gdbarch,
 
   lai->bool_type_symbol = "boolean";
   lai->bool_type_default = java_boolean_type;
+
+  lai->size_type_default = builtin_type (gdbarch)->builtin_int;
 }
 
 const struct exp_descriptor exp_descriptor_java = 
diff --git a/gdb/language.c b/gdb/language.c
index 46e238d..c6eec0a 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -1127,6 +1127,7 @@ unknown_language_arch_info (struct gdbarch *gdbarch,
 {
   lai->string_char_type = builtin_type (gdbarch)->builtin_char;
   lai->bool_type_default = builtin_type (gdbarch)->builtin_int;
+  lai->size_type_default = builtin_type (gdbarch)->builtin_int;
   lai->primitive_type_vector = GDBARCH_OBSTACK_CALLOC (gdbarch, 1,
 						       struct type *);
 }
@@ -1303,6 +1304,33 @@ language_bool_type (const struct language_defn *la,
   return ld->arch_info[la->la_language].bool_type_default;
 }
 
+/* Return the size type for the given language and architecture.  The
+   size type is the type used to represent the size of an object, for
+   instance the result of the C `sizeof' operator.  */
+
+struct type *
+language_size_type (const struct language_defn *la,
+		    struct gdbarch *gdbarch)
+{
+  struct language_gdbarch *ld = gdbarch_data (gdbarch,
+					      language_gdbarch_data);
+
+  if (ld->arch_info[la->la_language].size_type_symbol)
+    {
+      struct symbol *sym;
+      sym = lookup_symbol (ld->arch_info[la->la_language].size_type_symbol,
+			   NULL, VAR_DOMAIN, NULL);
+      if (sym)
+	{
+	  struct type *type = SYMBOL_TYPE (sym);
+	  if (type && TYPE_CODE (type) == TYPE_CODE_INT)
+	    return type;
+	}
+    }
+
+  return ld->arch_info[la->la_language].size_type_default;
+}
+
 struct type *
 language_lookup_primitive_type_by_name (const struct language_defn *la,
 					struct gdbarch *gdbarch,
diff --git a/gdb/language.h b/gdb/language.h
index c92c57c..f09c029 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -134,6 +134,11 @@ struct language_arch_info
   const char *bool_type_symbol;
   /* Otherwise, this is the default boolean builtin type.  */
   struct type *bool_type_default;
+
+  /* Symbol name of type to use as size type, if defined.  */
+  const char *size_type_symbol;
+  /* Otherwise, this is the default builtin size type.  */
+  struct type *size_type_default;
 };
 
 /* Structure tying together assorted information about a language.  */
@@ -331,6 +336,9 @@ struct type *language_bool_type (const struct language_defn *l,
 struct type *language_string_char_type (const struct language_defn *l,
 					struct gdbarch *gdbarch);
 
+struct type *language_size_type (const struct language_defn *l,
+				 struct gdbarch *gdbarch);
+
 struct type *language_lookup_primitive_type_by_name (const struct language_defn *l,
 						     struct gdbarch *gdbarch,
 						     const char *name);
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index e09b64b..fa6fcaf 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -349,6 +349,8 @@ m2_language_arch_info (struct gdbarch *gdbarch,
 
   lai->bool_type_symbol = "BOOLEAN";
   lai->bool_type_default = builtin->builtin_bool;
+
+  lai->size_type_default = builtin->builtin_int;
 }
 
 const struct exp_descriptor exp_descriptor_modula2 = 
diff --git a/gdb/objc-exp.y b/gdb/objc-exp.y
index 1527a04..aa4f738 100644
--- a/gdb/objc-exp.y
+++ b/gdb/objc-exp.y
@@ -577,7 +577,8 @@ exp	:	SELECTOR
 
 exp	:	SIZEOF '(' type ')'	%prec UNARY
 			{ write_exp_elt_opcode (OP_LONG);
-			  write_exp_elt_type (parse_type->builtin_int);
+			  write_exp_elt_type (language_size_type (parse_language,
+								  parse_gdbarch));
 			  CHECK_TYPEDEF ($3);
 			  write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
 			  write_exp_elt_opcode (OP_LONG); }
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index cd4285d..bd82c48 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -397,6 +397,8 @@ pascal_language_arch_info (struct gdbarch *gdbarch,
 
   lai->bool_type_symbol = "boolean";
   lai->bool_type_default = builtin->builtin_bool;
+
+  lai->size_type_default = builtin->builtin_int;
 }
 
 const struct language_defn pascal_language_defn =
diff --git a/gdb/testsuite/gdb.base/sizeof.exp b/gdb/testsuite/gdb.base/sizeof.exp
index c6432bf..421d3ea 100644
--- a/gdb/testsuite/gdb.base/sizeof.exp
+++ b/gdb/testsuite/gdb.base/sizeof.exp
@@ -118,6 +118,10 @@ check_sizeof "float" ${sizeof_float}
 check_sizeof "double" ${sizeof_double}
 check_sizeof "long double" ${sizeof_long_double}
 
+# Check that sizeof has unsigned type.
+gdb_test "print -sizeof(int)" \
+  "\\$\[0-9\]* = (\[0-9\]*)"
+
 proc check_valueof { exp val } {
     global gdb_prompt
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]