diff mbox

Handle volatile array types in dwarf2read.c.

Message ID 1404164071-24432-1-git-send-email-mjw@redhat.com
State New
Headers show

Commit Message

Mark Wielaard June 30, 2014, 9:34 p.m. UTC
read_tag_const_type propagates the cv-qualifier to the array element type,
but read_tag_volatile_type didn't. Make sure that both cv-qualifiers that
apply to array types are handled the same.

gdb/ChangeLog

	* dwarf2read.c (add_array_cv_type): New function.
	(read_tag_const_type): Call add_array_cv_type for TYPE_CODE_ARRAY.
	(read_tag_volatile_type): Likewise.

gdb/testsuite/ChangeLog

	* gdb.base/constvars.c (violent, violet, vips, virgen, vulgar,
	vulture, vilify, villar): New volatile array constants.
	(vindictive, vegetation): New const volatile array constants.
	* gdb.base/volatile.exp: Test volatile and const volatile array
	types.
---
 gdb/ChangeLog                       |    6 ++++
 gdb/dwarf2read.c                    |   55 +++++++++++++++++++++++------------
 gdb/testsuite/ChangeLog             |    8 +++++
 gdb/testsuite/gdb.base/constvars.c  |   14 +++++++++
 gdb/testsuite/gdb.base/volatile.exp |   24 +++++++++++++++
 5 files changed, 88 insertions(+), 19 deletions(-)

Comments

Tom Tromey July 1, 2014, 4:04 p.m. UTC | #1
>>>>> "Mark" == Mark Wielaard <mjw@redhat.com> writes:

Mark> read_tag_const_type propagates the cv-qualifier to the array
Mark> element type, but read_tag_volatile_type didn't. Make sure that
Mark> both cv-qualifiers that apply to array types are handled the same.

Thanks Mark.

Mark> 	* gdb.base/constvars.c (violent, violet, vips, virgen, vulgar,
Mark> 	vulture, vilify, villar): New volatile array constants.
Mark> 	(vindictive, vegetation): New const volatile array constants.

Lovely names.

Mark> +   the cv-qualifiers.  This is mimics section 6.7.3 of the C99
Mark> +   specification.  */

"This is" -> "This".

Mark> +static struct type *
Mark> +add_array_cv_type (struct die_info *die, struct dwarf2_cu *cu,
Mark> +		   struct type *base_type, int cnst, int voltl)

gdb usually puts a blank line between the intro comment and the function
head.

Mark> +  while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
Mark> +    {
Mark> +      TYPE_TARGET_TYPE (inner_array) =
Mark> +	copy_type (TYPE_TARGET_TYPE (inner_array));
Mark> +      inner_array = TYPE_TARGET_TYPE (inner_array);
Mark> +    }

I think this may be overly eager in the case where the underlying type
already has the needed qualifications.

Mark> +  cnst |= TYPE_CONST (el_type);
Mark> +  voltl |= TYPE_VOLATILE (el_type);
Mark> +  TYPE_TARGET_TYPE (inner_array) = make_cv_type (cnst, voltl, el_type, NULL);

make_cv_type preserves the already existing qualifiers so you don't need
to track "cnst" and "voltl".  You can just pass in the ones you want to
add.

Mark> +  /* In case the volatile qualifier is applied to an array type, the
Mark> +     element type is so qualified, not the array type (section 6.7.3
Mark> +     of C99).  */
Mark> +  if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
Mark> +    return add_array_cv_type (die, cu, base_type, 0, 1);

I wonder about typedefs to array type.
Calling check_typedef here is probably not so great but I assume we can
just ignore incomplete types.

Tom
diff mbox

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8d304ac..ccfae0c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@ 
+2014-06-30  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf2read.c (add_array_cv_type): New function.
+	(read_tag_const_type): Call add_array_cv_type for TYPE_CODE_ARRAY.
+	(read_tag_volatile_type): Likewise.
+
 2014-06-30  Tom Tromey  <tromey@redhat.com>
 
 	* symtab.c (operator_chars): Make parameters and return type
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index fc4f7cb..f36c67a 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14097,6 +14097,35 @@  read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
+/* Add the given cv-qualifiers to the element type of the array.  GCC
+   outputs DWARF type qualifiers that apply to an array, not the
+   element type.  But GDB relies on the array element type to carry
+   the cv-qualifiers.  This is mimics section 6.7.3 of the C99
+   specification.  */
+static struct type *
+add_array_cv_type (struct die_info *die, struct dwarf2_cu *cu,
+		   struct type *base_type, int cnst, int voltl)
+{
+  struct type *el_type, *inner_array;
+
+  base_type = copy_type (base_type);
+  inner_array = base_type;
+
+  while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
+    {
+      TYPE_TARGET_TYPE (inner_array) =
+	copy_type (TYPE_TARGET_TYPE (inner_array));
+      inner_array = TYPE_TARGET_TYPE (inner_array);
+    }
+
+  el_type = TYPE_TARGET_TYPE (inner_array);
+  cnst |= TYPE_CONST (el_type);
+  voltl |= TYPE_VOLATILE (el_type);
+  TYPE_TARGET_TYPE (inner_array) = make_cv_type (cnst, voltl, el_type, NULL);
+
+  return set_die_type (die, base_type, cu);
+}
+
 static struct type *
 read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
 {
@@ -14112,25 +14141,7 @@  read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
   /* In case the const qualifier is applied to an array type, the element type
      is so qualified, not the array type (section 6.7.3 of C99).  */
   if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
-    {
-      struct type *el_type, *inner_array;
-
-      base_type = copy_type (base_type);
-      inner_array = base_type;
-
-      while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
-	{
-	  TYPE_TARGET_TYPE (inner_array) =
-	    copy_type (TYPE_TARGET_TYPE (inner_array));
-	  inner_array = TYPE_TARGET_TYPE (inner_array);
-	}
-
-      el_type = TYPE_TARGET_TYPE (inner_array);
-      TYPE_TARGET_TYPE (inner_array) =
-	make_cv_type (1, TYPE_VOLATILE (el_type), el_type, NULL);
-
-      return set_die_type (die, base_type, cu);
-    }
+    return add_array_cv_type (die, cu, base_type, 1, 0);
 
   cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
   return set_die_type (die, cv_type, cu);
@@ -14148,6 +14159,12 @@  read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
   if (cv_type)
     return cv_type;
 
+  /* In case the volatile qualifier is applied to an array type, the
+     element type is so qualified, not the array type (section 6.7.3
+     of C99).  */
+  if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+    return add_array_cv_type (die, cu, base_type, 0, 1);
+
   cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
   return set_die_type (die, cv_type, cu);
 }
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 751848f..90be171 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,11 @@ 
+2014-06-30  Mark Wielaard  <mjw@redhat.com>
+
+	* gdb.base/constvars.c (violent, violet, vips, virgen, vulgar,
+	vulture, vilify, villar): New volatile array constants.
+	(vindictive, vegetation): New const volatile array constants.
+	* gdb.base/volatile.exp: Test volatile and const volatile array
+	types.
+
 2014-06-30  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
 	* gdb.base/watchpoint-reuse-slot.exp: Handle the case that the
diff --git a/gdb/testsuite/gdb.base/constvars.c b/gdb/testsuite/gdb.base/constvars.c
index 4228822..60cca2a 100644
--- a/gdb/testsuite/gdb.base/constvars.c
+++ b/gdb/testsuite/gdb.base/constvars.c
@@ -127,6 +127,16 @@  main (void)
   volatile float          * volatile vitality = &vacuity;
   volatile double         * volatile voracity = &vertigo;
 
+  /* volatile arrays */
+  volatile char violent[2] = {vox, vox};
+  volatile unsigned char violet[2] = {victuals, victuals};
+  volatile short vips[2] = {vixen, vixen};
+  volatile unsigned short virgen[2] = {vitriol, vitriol};
+  volatile long vulgar[2] = {vellum, vellum};
+  volatile unsigned long vulture[2] = {valve, valve};
+  volatile float vilify[2] = {vacuity, vacuity};
+  volatile double villar[2] = {vertigo, vertigo};
+
   /* const volatile vars */
 
   const volatile char           victor = 'Y';
@@ -177,6 +187,10 @@  main (void)
   const volatile char              * const volatile vagary = &victor;
   const volatile unsigned char     * const volatile vendor = &vicar;
   
+  /* const volatile arrays */
+  const volatile char vindictive[2] = {victor, victor};
+  const volatile unsigned char vegetation[2] = {vicar, vicar};
+
   /* various structs with const members */
 
   struct crass { char * const ptr; } crass = { lamprey };
diff --git a/gdb/testsuite/gdb.base/volatile.exp b/gdb/testsuite/gdb.base/volatile.exp
index 7cd7254..0e106fc 100644
--- a/gdb/testsuite/gdb.base/volatile.exp
+++ b/gdb/testsuite/gdb.base/volatile.exp
@@ -229,6 +229,30 @@  gdb_test "ptype vagary" "type = const volatile char \\* const volatile.*"
 local_compiler_xfail_check
 gdb_test "ptype vendor" "type = const volatile unsigned char \\* const volatile.*"
 
+# volatile arrays
+local_compiler_xfail_check
+gdb_test "ptype violent" "type = volatile char \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype violet" "type = volatile unsigned char \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype vips" "type = volatile short( int)? \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype virgen" "type = volatile (unsigned short|short unsigned)( int)? \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype vulgar" "type = volatile long( int)? \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype vulture" "type = volatile (unsigned long|long unsigned)( int)? \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype vilify" "type = volatile float \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype villar" "type = volatile double \\\[2\\\]"
+
+# const volatile arrays
+local_compiler_xfail_check
+gdb_test "ptype vindictive" "type = const volatile char \\\[2\\\]"
+local_compiler_xfail_check
+gdb_test "ptype vegetation" "type = const volatile unsigned char \\\[2\\\]"
+
 # test function parameters
 local_compiler_xfail_check
 local_compiler_xfail_check_2