public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v6 00/15] Please have a final look
@ 2014-04-10 12:42 Sanimir Agovic
  2014-04-10 12:42 ` [PATCH v6 01/15] refactoring: rename create_range_type to create_static_range_type Sanimir Agovic
                   ` (15 more replies)
  0 siblings, 16 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:42 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

Hello,

this patch series (v6) add C99 variable length support to gdb.

Current status
==============

TYPE_CODE_PTR types are not considered as being dynamic, otherwise all issues
are addressed mentioned by Joel:

    #03 | type: add c99 variable length array support

Minor adjustments like usage of bitfields and dealing with LOC_CONST values:

    #09 | vla: resolve dynamic bounds if value contents is a constant byte-seq
    #08 | vla: support for DW_AT_count
    #10 | vla: evaluate operand of sizeof if its type is a vla

Pre-approved with minor adjustments:

    #01 | refactoring: rename create_range_type to create_static_range_type
    #02 | vla: introduce new bound type abstraction adapt uses
    #04 | vla: enable sizeof operator to work with variable length arrays
    #05 | vla: enable sizeof operator for indirection
    #06 | vla: update type from newly created value
    #07 | vla: print "variable length" for unresolved dynamic bounds
    #11 | test: cover subranges with present DW_AT_count attribute
    #12 | test: multi-dimensional c99 vla
    #13 | test: evaluate pointers to C99 vla correctly
    #14 | test: basic c99 vla tests for C primitives
    #15 | test: add mi vla test


Some technical background
=========================

Dwarf allows certain attributes e.g upper/lower bound to be computed
dynamically. To support this feature with the current gdb type-system types
are "normalized". This means types with dynamic properties are converted
to types with static properties.

To convert a type with dynamic properties into one with static properties
access to inferior memory is needed. Therefore we hooked into the following
value constructors value_at/value_at_lazy/value_from_contents_and_address
as they require an inferior address in addition to a type to instantiate
a value. If the passed type has dynamic properties we resolve the bounds
and thus the type is modified, not in place but rather by a new copy.

Given the following code snippet:

  struct value *val = value_at (my_vla_type, at_address);

Before this was always true:
  TYPE_LENGTH (value_type (val)) == TYPE_LENGTH (my_vla_type)

This is not the case after applying this patch series. Type normalization
is done in the mentioned value constructors and might change the value type.

Some documentation, examples as well as a github branch with support for c99
and Fortran variable length arrays is availabel at http://intel-gdb.github.io/

 -Sanimir & Keven

Sanimir Agovic (15):
  refactoring: rename create_range_type to create_static_range_type
  vla: introduce new bound type abstraction adapt uses
  type: add c99 variable length array support
  vla: enable sizeof operator to work with variable length arrays
  vla: enable sizeof operator for indirection
  vla: update type from newly created value
  vla: print "variable length" for unresolved dynamic bounds
  vla: support for DW_AT_count
  vla: resolve dynamic bounds if value contents is a constant
    byte-sequence
  vla: evaluate operand of sizeof if its type is a vla
  test: cover subranges with present DW_AT_count attribute
  test: multi-dimensional c99 vla.
  test: evaluate pointers to C99 vla correctly.
  test: basic c99 vla tests for C primitives
  test: add mi vla test

 gdb/ada-lang.c                            |  44 ++++--
 gdb/c-typeprint.c                         |   6 +-
 gdb/coffread.c                            |   6 +-
 gdb/cp-valprint.c                         |   2 +
 gdb/d-valprint.c                          |   1 +
 gdb/dwarf2loc.c                           | 119 ++++++++++++++
 gdb/dwarf2loc.h                           |  28 ++++
 gdb/dwarf2read.c                          | 159 +++++++++++++------
 gdb/eval.c                                |  54 ++++++-
 gdb/f-exp.y                               |   9 +-
 gdb/findvar.c                             |   8 +-
 gdb/gdbtypes.c                            | 254 ++++++++++++++++++++++--------
 gdb/gdbtypes.h                            |  76 +++++++--
 gdb/jv-valprint.c                         |   1 +
 gdb/m2-valprint.c                         |   2 +-
 gdb/mdebugread.c                          |   4 +-
 gdb/parse.c                               |   3 +-
 gdb/stabsread.c                           |  11 +-
 gdb/testsuite/gdb.base/vla-datatypes.c    |  86 ++++++++++
 gdb/testsuite/gdb.base/vla-datatypes.exp  | 139 ++++++++++++++++
 gdb/testsuite/gdb.base/vla-multi.c        |  48 ++++++
 gdb/testsuite/gdb.base/vla-multi.exp      |  41 +++++
 gdb/testsuite/gdb.base/vla-ptr.c          |  58 +++++++
 gdb/testsuite/gdb.base/vla-ptr.exp        |  41 +++++
 gdb/testsuite/gdb.base/vla-sideeffect.c   |  42 +++++
 gdb/testsuite/gdb.base/vla-sideeffect.exp |  89 +++++++++++
 gdb/testsuite/gdb.dwarf2/count.exp        | 125 +++++++++++++++
 gdb/testsuite/gdb.mi/mi-vla-c99.exp       |  82 ++++++++++
 gdb/testsuite/gdb.mi/vla.c                |  37 +++++
 gdb/valops.c                              |  35 ++--
 gdb/valprint.c                            |   2 +-
 gdb/value.c                               |  20 ++-
 32 files changed, 1447 insertions(+), 185 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/vla-datatypes.c
 create mode 100644 gdb/testsuite/gdb.base/vla-datatypes.exp
 create mode 100644 gdb/testsuite/gdb.base/vla-multi.c
 create mode 100644 gdb/testsuite/gdb.base/vla-multi.exp
 create mode 100644 gdb/testsuite/gdb.base/vla-ptr.c
 create mode 100644 gdb/testsuite/gdb.base/vla-ptr.exp
 create mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.c
 create mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.exp
 create mode 100644 gdb/testsuite/gdb.dwarf2/count.exp
 create mode 100644 gdb/testsuite/gdb.mi/mi-vla-c99.exp
 create mode 100644 gdb/testsuite/gdb.mi/vla.c

-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 01/15] refactoring: rename create_range_type to create_static_range_type
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
@ 2014-04-10 12:42 ` Sanimir Agovic
  2014-04-10 12:43 ` [PATCH v6 02/15] vla: introduce new bound type abstraction adapt uses Sanimir Agovic
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:42 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

2013-12-19  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell <keven.boell@intel.com>

	* gdbtypes.c (create_static_range_type): Renamed from create_range_type.
	* gdbtypes.h (create_static_range_type): Renamed from create_range_type.
	* ada-lang.c: All uses of create_range_type updated.
	* coffread.c: All uses of create_range_type updated.
	* dwarf2read.c: All uses of create_range_type updated.
	* f-exp.y: All uses of create_range_type updated.
	* m2-valprint.c: All uses of create_range_type updated.
	* mdebugread.c: All uses of create_range_type updated.
	* stabsread.c: All uses of create_range_type updated.
	* valops.c: All uses of create_range_type updated.
	* valprint.c: All uses of create_range_type updated.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/ada-lang.c    | 31 ++++++++++++++++---------------
 gdb/coffread.c    |  6 +++---
 gdb/dwarf2read.c  |  6 +++---
 gdb/f-exp.y       |  9 ++++++---
 gdb/gdbtypes.c    |  6 +++---
 gdb/gdbtypes.h    |  4 ++--
 gdb/m2-valprint.c |  2 +-
 gdb/mdebugread.c  |  4 ++--
 gdb/stabsread.c   | 11 ++++++-----
 gdb/valops.c      | 16 ++++++++--------
 gdb/valprint.c    |  2 +-
 11 files changed, 51 insertions(+), 46 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 786ca7a..d08e116 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -1875,9 +1875,9 @@ ada_type_of_array (struct value *arr, int bounds)
           struct value *high = desc_one_bound (descriptor, arity, 1);
 
           arity -= 1;
-          create_range_type (range_type, value_type (low),
-                             longest_to_int (value_as_long (low)),
-                             longest_to_int (value_as_long (high)));
+          create_static_range_type (range_type, value_type (low),
+				    longest_to_int (value_as_long (low)),
+				    longest_to_int (value_as_long (high)));
           elt_type = create_array_type (array_type, elt_type, range_type);
 
 	  if (ada_is_unconstrained_packed_array_type (value_type (arr)))
@@ -2648,9 +2648,10 @@ ada_value_slice_from_ptr (struct value *array_ptr, struct type *type,
   CORE_ADDR base = value_as_address (array_ptr)
     + ((low - ada_discrete_type_low_bound (TYPE_INDEX_TYPE (type0)))
        * TYPE_LENGTH (TYPE_TARGET_TYPE (type0)));
-  struct type *index_type =
-    create_range_type (NULL, TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (type0)),
-                       low, high);
+  struct type *index_type
+    = create_static_range_type (NULL,
+				TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (type0)),
+				low, high);
   struct type *slice_type =
     create_array_type (NULL, TYPE_TARGET_TYPE (type0), index_type);
 
@@ -2662,8 +2663,8 @@ static struct value *
 ada_value_slice (struct value *array, int low, int high)
 {
   struct type *type = ada_check_typedef (value_type (array));
-  struct type *index_type =
-    create_range_type (NULL, TYPE_INDEX_TYPE (type), low, high);
+  struct type *index_type
+    = create_static_range_type (NULL, TYPE_INDEX_TYPE (type), low, high);
   struct type *slice_type =
     create_array_type (NULL, TYPE_TARGET_TYPE (type), index_type);
 
@@ -2871,9 +2872,9 @@ static struct value *
 empty_array (struct type *arr_type, int low)
 {
   struct type *arr_type0 = ada_check_typedef (arr_type);
-  struct type *index_type =
-    create_range_type (NULL, TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (arr_type0)),
-                       low, low - 1);
+  struct type *index_type
+    = create_static_range_type
+        (NULL, TYPE_TARGET_TYPE (TYPE_INDEX_TYPE (arr_type0)),  low, low - 1);
   struct type *elt_type = ada_array_element_type (arr_type0, 1);
 
   return allocate_value (create_array_type (NULL, elt_type, index_type));
@@ -10853,9 +10854,8 @@ to_fixed_range_type (struct type *raw_type, struct value *dval)
       if (L < INT_MIN || U > INT_MAX)
 	return raw_type;
       else
-	return create_range_type (alloc_type_copy (raw_type), raw_type,
-				  ada_discrete_type_low_bound (raw_type),
-				  ada_discrete_type_high_bound (raw_type));
+	return create_static_range_type (alloc_type_copy (raw_type), raw_type,
+					 L, U);
     }
   else
     {
@@ -10918,7 +10918,8 @@ to_fixed_range_type (struct type *raw_type, struct value *dval)
             }
         }
 
-      type = create_range_type (alloc_type_copy (raw_type), base_type, L, U);
+      type = create_static_range_type (alloc_type_copy (raw_type),
+				       base_type, L, U);
       TYPE_NAME (type) = name;
       return type;
     }
diff --git a/gdb/coffread.c b/gdb/coffread.c
index b49e30c..6a19e8b 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -1841,9 +1841,9 @@ decode_type (struct coff_symbol *cs, unsigned int c_type,
 
 	  base_type = decode_type (cs, new_c_type, aux, objfile);
 	  index_type = objfile_type (objfile)->builtin_int;
-	  range_type =
-	    create_range_type ((struct type *) NULL, 
-			       index_type, 0, n - 1);
+	  range_type
+	    = create_static_range_type ((struct type *) NULL,
+					index_type, 0, n - 1);
 	  type =
 	    create_array_type ((struct type *) NULL, 
 			       base_type, range_type);
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 1c7dfc5..4ba25ff 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -13231,7 +13231,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
   if (die->child == NULL)
     {
       index_type = objfile_type (objfile)->builtin_int;
-      range_type = create_range_type (NULL, index_type, 0, -1);
+      range_type = create_static_range_type (NULL, index_type, 0, -1);
       type = create_array_type (NULL, element_type, range_type);
       return set_die_type (die, type, cu);
     }
@@ -13935,7 +13935,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   index_type = objfile_type (objfile)->builtin_int;
-  range_type = create_range_type (NULL, index_type, 1, length);
+  range_type = create_static_range_type (NULL, index_type, 1, length);
   char_type = language_string_char_type (cu->language_defn, gdbarch);
   type = create_string_type (NULL, char_type, range_type);
 
@@ -14400,7 +14400,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
     high |= negative_mask;
 
-  range_type = create_range_type (NULL, orig_base_type, low, high);
+  range_type = create_static_range_type (NULL, orig_base_type, low, high);
 
   /* Mark arrays with dynamic length at least as an array of unspecified
      length.  GDB could check the boundary but before it gets implemented at
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 567cd00..af8de68 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -558,10 +558,13 @@ ptype	:	typebase
 			array_size = pop_type_int ();
 			if (array_size != -1)
 			  {
+			    struct type *index_type;
+
+			    index_type = parse_f_type->builtin_integer;
 			    range_type =
-			      create_range_type ((struct type *) NULL,
-						 parse_f_type->builtin_integer,
-						 0, array_size - 1);
+			      create_static_range_type((struct type *) NULL,
+						       index_type,
+						       0, array_size - 1);
 			    follow_type =
 			      create_array_type ((struct type *) NULL,
 						 follow_type, range_type);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 2470304..807e18e 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -809,8 +809,8 @@ allocate_stub_method (struct type *type)
    sure it is TYPE_CODE_UNDEF before we bash it into a range type?  */
 
 struct type *
-create_range_type (struct type *result_type, struct type *index_type,
-		   LONGEST low_bound, LONGEST high_bound)
+create_static_range_type (struct type *result_type, struct type *index_type,
+			  LONGEST low_bound, LONGEST high_bound)
 {
   if (result_type == NULL)
     result_type = alloc_type_copy (index_type);
@@ -998,7 +998,7 @@ lookup_array_range_type (struct type *element_type,
   struct gdbarch *gdbarch = get_type_arch (element_type);
   struct type *index_type = builtin_type (gdbarch)->builtin_int;
   struct type *range_type
-    = create_range_type (NULL, index_type, low_bound, high_bound);
+    = create_static_range_type (NULL, index_type, low_bound, high_bound);
 
   return create_array_type (NULL, element_type, range_type);
 }
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index c7bef5f..0396078 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1526,8 +1526,8 @@ extern struct type *lookup_function_type_with_arguments (struct type *,
 							 int,
 							 struct type **);
 
-extern struct type *create_range_type (struct type *, struct type *, LONGEST,
-				       LONGEST);
+extern struct type *create_static_range_type (struct type *, struct type *,
+					      LONGEST, LONGEST);
 
 extern struct type *create_array_type (struct type *, struct type *,
 				       struct type *);
diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c
index f8a8f75..12c38a5 100644
--- a/gdb/m2-valprint.c
+++ b/gdb/m2-valprint.c
@@ -475,7 +475,7 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset,
 			address, stream, recurse, original_value, options);
 	  break;
 	}
-      /* FIXME: create_range_type does not set the unsigned bit in a
+      /* FIXME: create_static_range_type does not set the unsigned bit in a
          range type (I think it probably should copy it from the target
          type), so we won't print values which are too large to
          fit in a signed integer correctly.  */
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index bbeea12..b0ba3ee 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -1869,8 +1869,8 @@ upgrade_type (int fd, struct type **tpp, int tq, union aux_ext *ax, int bigend,
       ax++;
       rf = AUX_GET_WIDTH (bigend, ax);	/* bit size of array element */
 
-      range = create_range_type ((struct type *) NULL, indx,
-				 lower, upper);
+      range = create_static_range_type ((struct type *) NULL, indx,
+					lower, upper);
 
       t = create_array_type ((struct type *) NULL, *tpp, range);
 
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 0046772..b8e36d4 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -863,9 +863,9 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	    /* NULL terminate the string.  */
 	    string_local[ind] = 0;
 	    range_type
-	      = create_range_type (NULL,
-				   objfile_type (objfile)->builtin_int,
-				   0, ind);
+	      = create_static_range_type (NULL,
+					  objfile_type (objfile)->builtin_int,
+					  0, ind);
 	    SYMBOL_TYPE (sym) = create_array_type (NULL,
 				  objfile_type (objfile)->builtin_char,
 				  range_type);
@@ -3615,7 +3615,7 @@ read_array_type (char **pp, struct type *type,
     }
 
   range_type =
-    create_range_type ((struct type *) NULL, index_type, lower, upper);
+    create_static_range_type ((struct type *) NULL, index_type, lower, upper);
   type = create_array_type (type, element_type, range_type);
 
   return type;
@@ -4245,7 +4245,8 @@ handle_true_range:
       index_type = objfile_type (objfile)->builtin_int;
     }
 
-  result_type = create_range_type ((struct type *) NULL, index_type, n2, n3);
+  result_type
+    = create_static_range_type ((struct type *) NULL, index_type, n2, n3);
   return (result_type);
 }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index d43c758..5c7bb89 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -415,10 +415,10 @@ value_cast (struct type *type, struct value *arg2)
 		       "divide object size in cast"));
 	  /* FIXME-type-allocation: need a way to free this type when
 	     we are done with it.  */
-	  range_type = create_range_type ((struct type *) NULL,
-					  TYPE_TARGET_TYPE (range_type),
-					  low_bound,
-					  new_length + low_bound - 1);
+	  range_type = create_static_range_type ((struct type *) NULL,
+						 TYPE_TARGET_TYPE (range_type),
+						 low_bound,
+						 new_length + low_bound - 1);
 	  deprecated_set_value_type (arg2, 
 				     create_array_type ((struct type *) NULL,
 							element_type, 
@@ -3569,10 +3569,10 @@ value_slice (struct value *array, int lowbound, int length)
 
   /* FIXME-type-allocation: need a way to free this type when we are
      done with it.  */
-  slice_range_type = create_range_type ((struct type *) NULL,
-					TYPE_TARGET_TYPE (range_type),
-					lowbound, 
-					lowbound + length - 1);
+  slice_range_type = create_static_range_type ((struct type *) NULL,
+					       TYPE_TARGET_TYPE (range_type),
+					       lowbound,
+					       lowbound + length - 1);
 
     {
       struct type *element_type = TYPE_TARGET_TYPE (array_type);
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 7ebcdfd..b178109 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -597,7 +597,7 @@ generic_val_print (struct type *type, const gdb_byte *valaddr,
       break;
 
     case TYPE_CODE_RANGE:
-      /* FIXME: create_range_type does not set the unsigned bit in a
+      /* FIXME: create_static_range_type does not set the unsigned bit in a
          range type (I think it probably should copy it from the
          target type), so we won't print values which are too large to
          fit in a signed integer correctly.  */
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 02/15] vla: introduce new bound type abstraction adapt uses
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
  2014-04-10 12:42 ` [PATCH v6 01/15] refactoring: rename create_range_type to create_static_range_type Sanimir Agovic
@ 2014-04-10 12:43 ` Sanimir Agovic
  2014-04-10 12:44 ` [PATCH v6 04/15] vla: enable sizeof operator to work with variable length arrays Sanimir Agovic
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:43 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

The rational behind this patch is to get started to implement the feature
described in dwarf4 standard (2.19) Static and Dynamic Values of Attributes.
It adds new BOUND_PROP to store either a constant, exprloc, or reference to
describe an upper-/lower bound of a subrange. Other than that no new features
are introduced.

2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

	* dwarf2read.c (read_subrange_type): Use struct bound_prop for
	declaring high/low bounds and change uses accordingly. Call
	create_range_type instead of create_static_range_type.
	* gdbtypes.c (create_range_type): New function.
	(create_range_type): Convert bounds into struct bound_prop and pass
	them to create_range_type.
	* gdbtypes.h (struct bound_prop): New struct.
	(create_range_type): New function prototype.
	(struct range_bounds): Use struct bound_prop instead of LONGEST for
	high/low bounds. Remove low_undefined/high_undefined and adapt all uses.
	(TYPE_LOW_BOUND,TYPE_HIGH_BOUND): Adapt macros to refer to the static
	part of the bound.
	* parse.c (follow_types): Set high bound kind to BOUND_UNDEFINED.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/dwarf2read.c | 43 ++++++++++++++++++++++++------------------
 gdb/gdbtypes.c   | 50 +++++++++++++++++++++++++++++++++++--------------
 gdb/gdbtypes.h   | 57 ++++++++++++++++++++++++++++++++++++++++++--------------
 gdb/parse.c      |  3 ++-
 4 files changed, 106 insertions(+), 47 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 4ba25ff..101065b 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14260,7 +14260,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   struct type *base_type, *orig_base_type;
   struct type *range_type;
   struct attribute *attr;
-  LONGEST low, high;
+  struct dynamic_prop low, high;
   int low_default_is_valid;
   const char *name;
   LONGEST negative_mask;
@@ -14277,33 +14277,37 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (range_type)
     return range_type;
 
+  low.kind = PROP_CONST;
+  high.kind = PROP_CONST;
+  high.data.const_val = 0;
+
   /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
      omitting DW_AT_lower_bound.  */
   switch (cu->language)
     {
     case language_c:
     case language_cplus:
-      low = 0;
+      low.data.const_val = 0;
       low_default_is_valid = 1;
       break;
     case language_fortran:
-      low = 1;
+      low.data.const_val = 1;
       low_default_is_valid = 1;
       break;
     case language_d:
     case language_java:
     case language_objc:
-      low = 0;
+      low.data.const_val = 0;
       low_default_is_valid = (cu->header.version >= 4);
       break;
     case language_ada:
     case language_m2:
     case language_pascal:
-      low = 1;
+      low.data.const_val = 1;
       low_default_is_valid = (cu->header.version >= 4);
       break;
     default:
-      low = 0;
+      low.data.const_val = 0;
       low_default_is_valid = 0;
       break;
     }
@@ -14313,7 +14317,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
      but we don't know how to handle it.  */
   attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
   if (attr)
-    low = dwarf2_get_attr_constant_value (attr, low);
+    low.data.const_val
+      = dwarf2_get_attr_constant_value (attr, low.data.const_val);
   else if (!low_default_is_valid)
     complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
 				      "- DIE at 0x%x [in module %s]"),
@@ -14335,10 +14340,10 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
              either; we just represent them as zero-length
              arrays.  Choose an appropriate upper bound given
              the lower bound we've computed above.  */
-          high = low - 1;
+          high.data.const_val = low.data.const_val - 1;
         }
       else
-        high = dwarf2_get_attr_constant_value (attr, 1);
+        high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
     }
   else
     {
@@ -14346,12 +14351,12 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
       if (attr)
 	{
 	  int count = dwarf2_get_attr_constant_value (attr, 1);
-	  high = low + count - 1;
+	  high.data.const_val = low.data.const_val + count - 1;
 	}
       else
 	{
 	  /* Unspecified array length.  */
-	  high = low - 1;
+	  high.data.const_val = low.data.const_val - 1;
 	}
     }
 
@@ -14395,22 +14400,24 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   negative_mask =
     (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);
-  if (!TYPE_UNSIGNED (base_type) && (low & negative_mask))
-    low |= negative_mask;
-  if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
-    high |= negative_mask;
+  if (low.kind == PROP_CONST
+      && !TYPE_UNSIGNED (base_type) && (low.data.const_val & negative_mask))
+    low.data.const_val |= negative_mask;
+  if (high.kind == PROP_CONST
+      && !TYPE_UNSIGNED (base_type) && (high.data.const_val & negative_mask))
+    high.data.const_val |= negative_mask;
 
-  range_type = create_static_range_type (NULL, orig_base_type, low, high);
+  range_type = create_range_type (NULL, orig_base_type, &low, &high);
 
   /* Mark arrays with dynamic length at least as an array of unspecified
      length.  GDB could check the boundary but before it gets implemented at
      least allow accessing the array elements.  */
   if (attr && attr_form_is_block (attr))
-    TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
+    TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
 
   /* Ada expects an empty array on no boundary attributes.  */
   if (attr == NULL && cu->language != language_ada)
-    TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
+    TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
 
   name = dwarf2_name (die, cu);
   if (name)
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 807e18e..7f0269c 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -798,19 +798,13 @@ allocate_stub_method (struct type *type)
   return mtype;
 }
 
-/* Create a range type using either a blank type supplied in
-   RESULT_TYPE, or creating a new type, inheriting the objfile from
-   INDEX_TYPE.
-
-   Indices will be of type INDEX_TYPE, and will range from LOW_BOUND
-   to HIGH_BOUND, inclusive.
-
-   FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make
-   sure it is TYPE_CODE_UNDEF before we bash it into a range type?  */
+/* Create a range type with a dynamic range from LOW_BOUND to
+   HIGH_BOUND, inclusive.  See create_range_type for further details. */
 
 struct type *
-create_static_range_type (struct type *result_type, struct type *index_type,
-			  LONGEST low_bound, LONGEST high_bound)
+create_range_type (struct type *result_type, struct type *index_type,
+		   const struct dynamic_prop *low_bound,
+		   const struct dynamic_prop *high_bound)
 {
   if (result_type == NULL)
     result_type = alloc_type_copy (index_type);
@@ -820,17 +814,45 @@ create_static_range_type (struct type *result_type, struct type *index_type,
     TYPE_TARGET_STUB (result_type) = 1;
   else
     TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
+
   TYPE_RANGE_DATA (result_type) = (struct range_bounds *)
     TYPE_ZALLOC (result_type, sizeof (struct range_bounds));
-  TYPE_LOW_BOUND (result_type) = low_bound;
-  TYPE_HIGH_BOUND (result_type) = high_bound;
+  TYPE_RANGE_DATA (result_type)->low = *low_bound;
+  TYPE_RANGE_DATA (result_type)->high = *high_bound;
 
-  if (low_bound >= 0)
+  if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0)
     TYPE_UNSIGNED (result_type) = 1;
 
   return result_type;
 }
 
+/* Create a range type using either a blank type supplied in
+   RESULT_TYPE, or creating a new type, inheriting the objfile from
+   INDEX_TYPE.
+
+   Indices will be of type INDEX_TYPE, and will range from LOW_BOUND
+   to HIGH_BOUND, inclusive.
+
+   FIXME: Maybe we should check the TYPE_CODE of RESULT_TYPE to make
+   sure it is TYPE_CODE_UNDEF before we bash it into a range type?  */
+
+struct type *
+create_static_range_type (struct type *result_type, struct type *index_type,
+			  LONGEST low_bound, LONGEST high_bound)
+{
+  struct dynamic_prop low, high;
+
+  low.kind = PROP_CONST;
+  low.data.const_val = low_bound;
+
+  high.kind = PROP_CONST;
+  high.data.const_val = high_bound;
+
+  result_type = create_range_type (result_type, index_type, &low, &high);
+
+  return result_type;
+}
+
 /* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
    TYPE.  Return 1 if type is a range type, 0 if it is discrete (and
    bounds will fit in LONGEST), or -1 otherwise.  */
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 0396078..f6e68c5 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -365,6 +365,33 @@ enum type_instance_flag_value
 #define TYPE_ADDRESS_CLASS_ALL(t) (TYPE_INSTANCE_FLAGS(t) \
 				   & TYPE_INSTANCE_FLAG_ADDRESS_CLASS_ALL)
 
+/* Used to store a dynamic property.  */
+
+struct dynamic_prop
+{
+  /* Determine which field of the union dynamic_prop.data is used.  */
+  enum
+  {
+    PROP_UNDEFINED, /* Not defined.  */
+    PROP_CONST,     /* Constant.  */
+    PROP_LOCEXPR,   /* Location expression.  */
+    PROP_LOCLIST    /* Location list.  */
+  } kind;
+
+  /* Storage for dynamic or static value.  */
+  union data
+  {
+    /* Storage for constant property.  */
+
+    LONGEST const_val;
+
+    /* Storage for dynamic property.  */
+
+    void *baton;
+  } data;
+};
+
+
 /* Determine which field of the union main_type.fields[x].loc is used.  */
 
 enum field_loc_kind
@@ -589,19 +616,11 @@ struct main_type
     {
       /* Low bound of range.  */
 
-      LONGEST low;
+      struct dynamic_prop low;
 
       /* High bound of range.  */
 
-      LONGEST high;
-
-      /* Flags indicating whether the values of low and high are
-         valid.  When true, the respective range value is
-         undefined.  Currently used only for FORTRAN arrays.  */
-           
-      char low_undefined;
-      char high_undefined;
-
+      struct dynamic_prop high;
     } *bounds;
 
   } flds_bnds;
@@ -1066,12 +1085,18 @@ extern void allocate_gnat_aux_type (struct type *);
 
 #define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
 #define TYPE_RANGE_DATA(thistype) TYPE_MAIN_TYPE(thistype)->flds_bnds.bounds
-#define TYPE_LOW_BOUND(range_type) TYPE_RANGE_DATA(range_type)->low
-#define TYPE_HIGH_BOUND(range_type) TYPE_RANGE_DATA(range_type)->high
+#define TYPE_LOW_BOUND(range_type) \
+  TYPE_RANGE_DATA(range_type)->low.data.const_val
+#define TYPE_HIGH_BOUND(range_type) \
+  TYPE_RANGE_DATA(range_type)->high.data.const_val
 #define TYPE_LOW_BOUND_UNDEFINED(range_type) \
-   TYPE_RANGE_DATA(range_type)->low_undefined
+  (TYPE_RANGE_DATA(range_type)->low.kind == PROP_UNDEFINED)
 #define TYPE_HIGH_BOUND_UNDEFINED(range_type) \
-   TYPE_RANGE_DATA(range_type)->high_undefined
+  (TYPE_RANGE_DATA(range_type)->high.kind == PROP_UNDEFINED)
+#define TYPE_HIGH_BOUND_KIND(range_type) \
+  TYPE_RANGE_DATA(range_type)->high.kind
+#define TYPE_LOW_BOUND_KIND(range_type) \
+  TYPE_RANGE_DATA(range_type)->low.kind
 
 /* Moto-specific stuff for FORTRAN arrays.  */
 
@@ -1529,6 +1554,10 @@ extern struct type *lookup_function_type_with_arguments (struct type *,
 extern struct type *create_static_range_type (struct type *, struct type *,
 					      LONGEST, LONGEST);
 
+extern struct type *create_range_type (struct type *, struct type *,
+				       const struct dynamic_prop *,
+				       const struct dynamic_prop *);
+
 extern struct type *create_array_type (struct type *, struct type *,
 				       struct type *);
 extern struct type *lookup_array_range_type (struct type *, LONGEST, LONGEST);
diff --git a/gdb/parse.c b/gdb/parse.c
index 4b9ca5d..b1671f3 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1710,7 +1710,8 @@ follow_types (struct type *follow_type)
 	  lookup_array_range_type (follow_type,
 				   0, array_size >= 0 ? array_size - 1 : 0);
 	if (array_size < 0)
-	  TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (follow_type) = 1;
+	  TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (follow_type))
+	    = PROP_UNDEFINED;
 	break;
       case tp_function:
 	/* FIXME-type-allocation: need a way to free this type when we are
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 03/15] type: add c99 variable length array support
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (2 preceding siblings ...)
  2014-04-10 12:44 ` [PATCH v6 04/15] vla: enable sizeof operator to work with variable length arrays Sanimir Agovic
@ 2014-04-10 12:44 ` Sanimir Agovic
  2014-04-10 14:21   ` Joel Brobecker
  2014-04-10 12:45 ` [PATCH v6 05/15] vla: enable sizeof operator for indirection Sanimir Agovic
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:44 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

The dwarf standard allow certain attributes to be expressed as dwarf
expressions rather than constants. For instance upper-/lowerbound attributes.
In case of a c99 variable length array the upperbound is a dynamic attribute.

With this change c99 vla behave the same as with static arrays.

1| void foo (size_t n) {
2|   int ary[n];
3|   memset(ary, 0, sizeof(ary));
4| }

(gdb) print ary
$1 = {0 <repeats 42 times>}

2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
	(dwarf2_evaluate_property): New function.
	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
	* dwarf2read.c (attr_to_dynamic_prop): New function.
	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
	attribute.
	* gdbtypes.c: Include dwarf2loc.h.
	(is_dynamic_type): New function.
	(resolve_dynamic_type): New function.
	(resolve_dynamic_bounds): New function.
	(get_type_length): New function.
	(check_typedef): Use get_type_length to compute type length.
	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
	(TYPE_LOW_BOUND_KIND): New macro.
	(is_dynamic_type): New function prototype.
	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
	to resolve dynamic properties of the type. Update comment.
	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/dwarf2loc.c  | 119 +++++++++++++++++++++++++++++++++
 gdb/dwarf2loc.h  |  28 ++++++++
 gdb/dwarf2read.c | 106 +++++++++++++++++++++--------
 gdb/gdbtypes.c   | 199 +++++++++++++++++++++++++++++++++++++++++--------------
 gdb/gdbtypes.h   |  10 +++
 gdb/valops.c     |  15 ++++-
 gdb/value.c      |  19 ++++--
 7 files changed, 409 insertions(+), 87 deletions(-)

diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 2b1f323..d903322 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2431,6 +2431,125 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
   return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
 }
 
+/* Evaluates a dwarf expression and stores the result in VAL, expecting
+   that the dwarf expression only produces a single CORE_ADDR.  ADDR is a
+   context (location of a variable) and might be needed to evaluate the
+   location expression.
+   Returns 1 on success, 0 otherwise.   */
+
+static int
+dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
+			   CORE_ADDR addr, CORE_ADDR *valp)
+{
+  struct dwarf_expr_context *ctx;
+  struct dwarf_expr_baton baton;
+  struct objfile *objfile;
+  struct cleanup *cleanup;
+
+  if (dlbaton == NULL || dlbaton->size == 0)
+    return 0;
+
+  ctx = new_dwarf_expr_context ();
+  cleanup = make_cleanup_free_dwarf_expr_context (ctx);
+
+  baton.frame = get_selected_frame (NULL);
+  baton.per_cu = dlbaton->per_cu;
+
+  objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
+
+  ctx->gdbarch = get_objfile_arch (objfile);
+  ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
+  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
+  ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
+  ctx->funcs = &dwarf_expr_ctx_funcs;
+  ctx->baton = &baton;
+
+  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
+
+  switch (ctx->location)
+    {
+    case DWARF_VALUE_REGISTER:
+    case DWARF_VALUE_MEMORY:
+    case DWARF_VALUE_STACK:
+      *valp = dwarf_expr_fetch_address (ctx, 0);
+      if (ctx->location == DWARF_VALUE_REGISTER)
+	*valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
+      do_cleanups (cleanup);
+      return 1;
+    case DWARF_VALUE_LITERAL:
+      *valp = extract_signed_integer (ctx->data, ctx->len,
+				      gdbarch_byte_order (ctx->gdbarch));
+      do_cleanups (cleanup);
+      return 1;
+      /* Unsupported dwarf values.  */
+    case DWARF_VALUE_OPTIMIZED_OUT:
+    case DWARF_VALUE_IMPLICIT_POINTER:
+      break;
+    }
+
+  do_cleanups (cleanup);
+  return 0;
+}
+
+/* See dwarf2loc.h.  */
+
+int
+dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address,
+			  CORE_ADDR *value)
+{
+  if (prop == NULL)
+    return 0;
+
+  switch (prop->kind)
+    {
+    case PROP_LOCEXPR:
+      {
+	const struct dwarf2_property_baton *baton = prop->data.baton;
+
+	if (dwarf2_locexpr_baton_eval (&baton->locexpr, address, value))
+	  {
+	    if (baton->referenced_type)
+	      {
+		struct value *val = value_at (baton->referenced_type, *value);
+
+		*value = value_as_address (val);
+	      }
+	    return 1;
+	  }
+      }
+      break;
+
+    case PROP_LOCLIST:
+      {
+	struct dwarf2_property_baton *baton = prop->data.baton;
+	struct frame_info *frame = get_selected_frame (NULL);
+	CORE_ADDR pc = get_frame_address_in_block (frame);
+	const gdb_byte *data;
+	struct value *val;
+	size_t size;
+
+	data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
+	if (data != NULL)
+	  {
+	    val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data,
+					    size, baton->loclist.per_cu);
+	    if (!value_optimized_out (val))
+	      {
+		*value = value_as_address (val);
+		return 1;
+	      }
+	  }
+      }
+      break;
+
+    case PROP_CONST:
+      *value = prop->data.const_val;
+      return 1;
+    }
+
+  return 0;
+}
+
 \f
 /* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 9bc8ca5..94d9c5f 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -90,6 +90,14 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
 					size_t size,
 					struct dwarf2_per_cu_data *per_cu);
 
+/* Converts a dynamic property into a static one.  ADDR is the address of
+   the object currently being evaluated and might be nedded.
+   Returns 1 if PROP could be converted and the static value is passed back
+   into VALUE, otherwise returns 0.  */
+
+int dwarf2_evaluate_property (const struct dynamic_prop *prop,
+			      CORE_ADDR addr, CORE_ADDR *value);
+
 CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
 				  unsigned int addr_index);
 
@@ -135,6 +143,26 @@ struct dwarf2_loclist_baton
   unsigned char from_dwo;
 };
 
+/* A dynamic property is either expressed as a single location expression
+   or a location list.  If the property is an indirection, pointing to
+   another die, keep track of the targeted type in REFERENCED_TYPE.  */
+
+struct dwarf2_property_baton
+{
+  /* If the property is an indirection, we need to evaluate the location
+     LOCEXPR or LOCLIST in the context of the type REFERENCED_TYPE.
+     If NULL, the location is the actual value of the property.  */
+  struct type *referenced_type;
+  union
+  {
+    /* Location expression.  */
+    struct dwarf2_locexpr_baton locexpr;
+
+    /* Location list to be evaluated in the context of TYPE.  */
+    struct dwarf2_loclist_baton loclist;
+  };
+};
+
 extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
 extern const struct symbol_computed_ops dwarf2_loclist_funcs;
 
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 101065b..436d0db 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14252,6 +14252,84 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
+/* Parse dwarf attribute if it's a block, reference or constant and put the
+   resulting value of the attribute into struct bound_prop.
+   Returns 1 if ATTR could be resolved into PROP, 0 otherwise.  */
+
+static int
+attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
+		      struct dwarf2_cu *cu, struct dynamic_prop *prop)
+{
+  struct dwarf2_property_baton *baton;
+  struct obstack *obstack = &cu->objfile->objfile_obstack;
+
+  if (attr == NULL || prop == NULL)
+    return 0;
+
+  if (attr_form_is_block (attr))
+    {
+      baton = obstack_alloc (obstack, sizeof (*baton));
+      baton->referenced_type = NULL;
+      baton->locexpr.per_cu = cu->per_cu;
+      baton->locexpr.size = DW_BLOCK (attr)->size;
+      baton->locexpr.data = DW_BLOCK (attr)->data;
+      prop->data.baton = baton;
+      prop->kind = PROP_LOCEXPR;
+      gdb_assert (prop->data.baton != NULL);
+    }
+  else if (attr_form_is_ref (attr))
+    {
+      struct dwarf2_cu *target_cu = cu;
+      struct die_info *target_die;
+      struct attribute *target_attr;
+
+      target_die = follow_die_ref (die, attr, &target_cu);
+      target_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
+      if (target_attr == NULL)
+	return 0;
+
+      if (attr_form_is_section_offset (target_attr))
+	{
+	  baton = obstack_alloc (obstack, sizeof (*baton));
+	  baton->referenced_type = die_type (target_die, target_cu);
+	  fill_in_loclist_baton (cu, &baton->loclist, target_attr);
+	  prop->data.baton = baton;
+	  prop->kind = PROP_LOCLIST;
+	  gdb_assert (prop->data.baton != NULL);
+	}
+      else if (attr_form_is_block (target_attr))
+	{
+	  baton = obstack_alloc (obstack, sizeof (*baton));
+	  baton->referenced_type = die_type (target_die, target_cu);
+	  baton->locexpr.per_cu = cu->per_cu;
+	  baton->locexpr.size = DW_BLOCK (target_attr)->size;
+	  baton->locexpr.data = DW_BLOCK (target_attr)->data;
+	  prop->data.baton = baton;
+	  prop->kind = PROP_LOCEXPR;
+	  gdb_assert (prop->data.baton != NULL);
+	}
+      else
+	{
+	  dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
+						 "dynamic property");
+	  return 0;
+	}
+    }
+  else if (attr_form_is_constant (attr))
+    {
+      prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
+      prop->kind = PROP_CONST;
+    }
+  else
+    {
+      dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
+					     dwarf2_name (die, cu));
+      return 0;
+    }
+
+  return 1;
+}
+
 /* Read the given DW_AT_subrange DIE.  */
 
 static struct type *
@@ -14325,27 +14403,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 	       die->offset.sect_off, objfile_name (cu->objfile));
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
-  if (attr)
-    {
-      if (attr_form_is_block (attr) || attr_form_is_ref (attr))
-        {
-          /* GCC encodes arrays with unspecified or dynamic length
-             with a DW_FORM_block1 attribute or a reference attribute.
-             FIXME: GDB does not yet know how to handle dynamic
-             arrays properly, treat them as arrays with unspecified
-             length for now.
-
-             FIXME: jimb/2003-09-22: GDB does not really know
-             how to handle arrays of unspecified length
-             either; we just represent them as zero-length
-             arrays.  Choose an appropriate upper bound given
-             the lower bound we've computed above.  */
-          high.data.const_val = low.data.const_val - 1;
-        }
-      else
-        high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
-    }
-  else
+  if (!attr_to_dynamic_prop (attr, die, cu, &high))
     {
       attr = dwarf2_attr (die, DW_AT_count, cu);
       if (attr)
@@ -14409,12 +14467,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   range_type = create_range_type (NULL, orig_base_type, &low, &high);
 
-  /* Mark arrays with dynamic length at least as an array of unspecified
-     length.  GDB could check the boundary but before it gets implemented at
-     least allow accessing the array elements.  */
-  if (attr && attr_form_is_block (attr))
-    TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
-
   /* Ada expects an empty array on no boundary attributes.  */
   if (attr == NULL && cu->language != language_ada)
     TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 7f0269c..ce582f8 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -853,6 +853,17 @@ create_static_range_type (struct type *result_type, struct type *index_type,
   return result_type;
 }
 
+/* Predicate tests whether BOUNDS are static.  Returns 1 if all bounds values
+   are static, otherwise returns 0.  */
+
+static int
+has_static_range (const struct range_bounds *bounds)
+{
+  return (bounds->low.kind == PROP_CONST
+	  && bounds->high.kind == PROP_CONST);
+}
+
+
 /* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
    TYPE.  Return 1 if type is a range type, 0 if it is discrete (and
    bounds will fit in LONGEST), or -1 otherwise.  */
@@ -982,24 +993,31 @@ create_array_type (struct type *result_type,
 		   struct type *element_type,
 		   struct type *range_type)
 {
-  LONGEST low_bound, high_bound;
-
   if (result_type == NULL)
     result_type = alloc_type_copy (range_type);
 
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
-  if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
-    low_bound = high_bound = 0;
-  CHECK_TYPEDEF (element_type);
-  /* Be careful when setting the array length.  Ada arrays can be
-     empty arrays with the high_bound being smaller than the low_bound.
-     In such cases, the array length should be zero.  */
-  if (high_bound < low_bound)
-    TYPE_LENGTH (result_type) = 0;
+
+  if (has_static_range (TYPE_RANGE_DATA (range_type)))
+    {
+      LONGEST low_bound, high_bound;
+
+      if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+	low_bound = high_bound = 0;
+      CHECK_TYPEDEF (element_type);
+      /* Be careful when setting the array length.  Ada arrays can be
+	 empty arrays with the high_bound being smaller than the low_bound.
+	 In such cases, the array length should be zero.  */
+      if (high_bound < low_bound)
+	TYPE_LENGTH (result_type) = 0;
+      else
+	TYPE_LENGTH (result_type) =
+	  TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+    }
   else
-    TYPE_LENGTH (result_type) =
-      TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+    TYPE_LENGTH (result_type) = 0;
+
   TYPE_NFIELDS (result_type) = 1;
   TYPE_FIELDS (result_type) =
     (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
@@ -1530,6 +1548,124 @@ stub_noname_complaint (void)
   complaint (&symfile_complaints, _("stub type has NULL name"));
 }
 
+/* See gdbtypes.h.  */
+
+int
+is_dynamic_type (struct type *type)
+{
+  type = check_typedef (type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_REF)
+    type = check_typedef (TYPE_TARGET_TYPE (type));
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      {
+	const struct type *range_type;
+
+	gdb_assert (TYPE_NFIELDS (type) == 1);
+	range_type = TYPE_INDEX_TYPE (type);
+	if (!has_static_range (TYPE_RANGE_DATA (range_type)))
+	  return 1;
+	else
+	  return is_dynamic_type (TYPE_TARGET_TYPE (type));
+	break;
+      }
+    default:
+      return 0;
+      break;
+    }
+}
+
+/* Resolves dynamic bound values of an array type TYPE to static ones.
+   ADDRESS might be needed to resolve the subrange bounds, it is the location
+   of the associated array.  */
+
+static struct type *
+resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
+{
+  CORE_ADDR value;
+  struct type *elt_type;
+  struct type *range_type;
+  struct type *ary_dim;
+  const struct dynamic_prop *prop;
+  const struct dwarf2_locexpr_baton *baton;
+  struct dynamic_prop low_bound, high_bound;
+
+  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    {
+      struct type *copy = copy_type (type);
+
+      TYPE_TARGET_TYPE (copy)
+	= resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
+
+      return copy;
+    }
+
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+
+  elt_type = type;
+  range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
+
+  prop = &TYPE_RANGE_DATA (range_type)->low;
+  if (dwarf2_evaluate_property (prop, addr, &value))
+    {
+      low_bound.kind = PROP_CONST;
+      low_bound.data.const_val = value;
+    }
+  else
+    {
+      low_bound.kind = PROP_UNDEFINED;
+      low_bound.data.const_val = 0;
+    }
+
+  prop = &TYPE_RANGE_DATA (range_type)->high;
+  if (dwarf2_evaluate_property (prop, addr, &value))
+    {
+      high_bound.kind = PROP_CONST;
+      high_bound.data.const_val = value;
+    }
+  else
+    {
+      high_bound.kind = PROP_UNDEFINED;
+      high_bound.data.const_val = 0;
+    }
+
+  ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
+
+  if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
+    elt_type = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
+  else
+    elt_type = TYPE_TARGET_TYPE (type);
+
+  range_type
+    = create_range_type (NULL,
+			 TYPE_TARGET_TYPE (range_type),
+			 &low_bound, &high_bound);
+  elt_type = create_array_type (copy_type (type),
+				elt_type,
+				range_type);
+
+  return elt_type;
+}
+
+/* See gdbtypes.h  */
+
+struct type *
+resolve_dynamic_type (struct type *type, CORE_ADDR addr)
+{
+  struct type *real_type = check_typedef (type);
+  struct type *resolved_type;
+
+  if (!is_dynamic_type (real_type))
+    return type;
+
+  resolved_type = resolve_dynamic_bounds (type, addr);
+
+  return resolved_type;
+}
+
 /* Find the real type of TYPE.  This function returns the real type,
    after removing all layers of typedefs, and completing opaque or stub
    types.  Completion changes the TYPE argument, but stripping of
@@ -1705,45 +1841,6 @@ check_typedef (struct type *type)
 	{
 	  /* Nothing we can do.  */
 	}
-      else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
-	       && TYPE_NFIELDS (type) == 1
-	       && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
-		   == TYPE_CODE_RANGE))
-	{
-	  /* Now recompute the length of the array type, based on its
-	     number of elements and the target type's length.
-	     Watch out for Ada null Ada arrays where the high bound
-	     is smaller than the low bound.  */
-	  const LONGEST low_bound = TYPE_LOW_BOUND (range_type);
-	  const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
-	  ULONGEST len;
-
-	  if (high_bound < low_bound)
-	    len = 0;
-	  else
-	    {
-	      /* For now, we conservatively take the array length to be 0
-		 if its length exceeds UINT_MAX.  The code below assumes
-		 that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
-		 which is technically not guaranteed by C, but is usually true
-		 (because it would be true if x were unsigned with its
-		 high-order bit on).  It uses the fact that
-		 high_bound-low_bound is always representable in
-		 ULONGEST and that if high_bound-low_bound+1 overflows,
-		 it overflows to 0.  We must change these tests if we 
-		 decide to increase the representation of TYPE_LENGTH
-		 from unsigned int to ULONGEST.  */
-	      ULONGEST ulow = low_bound, uhigh = high_bound;
-	      ULONGEST tlen = TYPE_LENGTH (target_type);
-
-	      len = tlen * (uhigh - ulow + 1);
-	      if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh 
-		  || len > UINT_MAX)
-		len = 0;
-	    }
-	  TYPE_LENGTH (type) = len;
-	  TYPE_TARGET_STUB (type) = 0;
-	}
       else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
 	{
 	  TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index f6e68c5..36e4a5f 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1,3 +1,4 @@
+
 /* Internal type definitions for GDB.
 
    Copyright (C) 1992-2013 Free Software Foundation, Inc.
@@ -1574,6 +1575,15 @@ extern struct type *lookup_unsigned_typename (const struct language_defn *,
 extern struct type *lookup_signed_typename (const struct language_defn *,
 					    struct gdbarch *, const char *);
 
+/* Resolve all dynamic values of a type e.g. array bounds to static values.
+   ADDR specifies the location of the variable the type is bound to.
+   If TYPE has no dynamic properties return TYPE; otherwise a new type with
+   static properties is returned.  */
+extern struct type *resolve_dynamic_type (struct type *type, CORE_ADDR addr);
+
+/* Predicate if the type has dynamic values, which are not resolved yet.  */
+extern int is_dynamic_type (struct type *type);
+
 extern struct type *check_typedef (struct type *);
 
 #define CHECK_TYPEDEF(TYPE)			\
diff --git a/gdb/valops.c b/gdb/valops.c
index 5c7bb89..eefa8c6 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -902,7 +902,10 @@ value_one (struct type *type)
   return val;
 }
 
-/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.  */
+/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.
+   The type of the created value may differ from the passed type TYPE.
+   Make sure to retrieve the returned values's new type after this call
+   e.g. in case the type is a variable length array.  */
 
 static struct value *
 get_value_at (struct type *type, CORE_ADDR addr, int lazy)
@@ -927,7 +930,10 @@ get_value_at (struct type *type, CORE_ADDR addr, int lazy)
    value_at_lazy instead.  value_at_lazy simply records the address of
    the data and sets the lazy-evaluation-required flag.  The lazy flag
    is tested in the value_contents macro, which is used if and when
-   the contents are actually required.
+   the contents are actually required.  The type of the created value
+   may differ from the passed type TYPE.  Make sure to retrieve the
+   returned values's new type after this call e.g. in case the type
+   is a variable length array.
 
    Note: value_at does *NOT* handle embedded offsets; perform such
    adjustments before or after calling it.  */
@@ -938,7 +944,10 @@ value_at (struct type *type, CORE_ADDR addr)
   return get_value_at (type, addr, 0);
 }
 
-/* Return a lazy value with type TYPE located at ADDR (cf. value_at).  */
+/* Return a lazy value with type TYPE located at ADDR (cf. value_at).
+   The type of the created value may differ from the passed type TYPE.
+   Make sure to retrieve the returned values's new type after this call
+   e.g. in case the type is a variable length array.  */
 
 struct value *
 value_at_lazy (struct type *type, CORE_ADDR addr)
diff --git a/gdb/value.c b/gdb/value.c
index a64e7e1..993157f 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3178,32 +3178,39 @@ value_from_ulongest (struct type *type, ULONGEST num)
 
 
 /* Create a value representing a pointer of type TYPE to the address
-   ADDR.  */
+   ADDR.  The type of the created value may differ from the passed
+   type TYPE. Make sure to retrieve the returned values's new type
+   after this call e.g. in case of an variable length array.  */
+
 struct value *
 value_from_pointer (struct type *type, CORE_ADDR addr)
 {
-  struct value *val = allocate_value (type);
+  struct type *resolved_type = resolve_dynamic_type (type, addr);
+  struct value *val = allocate_value (resolved_type);
 
-  store_typed_address (value_contents_raw (val), check_typedef (type), addr);
+  store_typed_address (value_contents_raw (val),
+		       check_typedef (resolved_type), addr);
   return val;
 }
 
 
 /* Create a value of type TYPE whose contents come from VALADDR, if it
    is non-null, and whose memory address (in the inferior) is
-   ADDRESS.  */
+   ADDRESS.  The type of the created value may differ from the passed
+   type TYPE.  Make sure to retrieve values new type after this call.  */
 
 struct value *
 value_from_contents_and_address (struct type *type,
 				 const gdb_byte *valaddr,
 				 CORE_ADDR address)
 {
+  struct type *resolved_type = resolve_dynamic_type (type, address);
   struct value *v;
 
   if (valaddr == NULL)
-    v = allocate_value_lazy (type);
+    v = allocate_value_lazy (resolved_type);
   else
-    v = value_from_contents (type, valaddr);
+    v = value_from_contents (resolved_type, valaddr);
   set_value_address (v, address);
   VALUE_LVAL (v) = lval_memory;
   return v;
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 04/15] vla: enable sizeof operator to work with variable length arrays
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
  2014-04-10 12:42 ` [PATCH v6 01/15] refactoring: rename create_range_type to create_static_range_type Sanimir Agovic
  2014-04-10 12:43 ` [PATCH v6 02/15] vla: introduce new bound type abstraction adapt uses Sanimir Agovic
@ 2014-04-10 12:44 ` Sanimir Agovic
  2014-04-10 12:44 ` [PATCH v6 03/15] type: add c99 variable length array support Sanimir Agovic
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:44 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

In C99 the sizeof operator computes the size of a variable length array
at runtime (6.5.3.4 The sizeof operator). This patch reflects the semantic
change in the debugger.

We now are able to get the size of a vla:

1| void foo (size_t n) {
2|   int vla[n];
3| }

(gdb) p sizeof(vla)

yields N * sizeof(int).

2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
	passed to sizeof is dynamic evaluate the argument to compute the length.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/eval.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/gdb/eval.c b/gdb/eval.c
index 9d81a92..a81e789 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -3041,8 +3041,14 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
       return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 
     case OP_VAR_VALUE:
-      (*pos) += 4;
       type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol));
+      if (is_dynamic_type (type))
+	{
+	  val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
+	  type = value_type (val);
+	}
+      else
+	(*pos) += 4;
       return
 	value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 05/15] vla: enable sizeof operator for indirection
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (3 preceding siblings ...)
  2014-04-10 12:44 ` [PATCH v6 03/15] type: add c99 variable length array support Sanimir Agovic
@ 2014-04-10 12:45 ` Sanimir Agovic
  2014-04-10 12:46 ` [PATCH v6 06/15] vla: update type from newly created value Sanimir Agovic
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:45 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

This patch enables the sizeof operator for indirections:

1| void foo (size_t n) {
2|   int vla[n];
3|   int *vla_ptr = &vla;
4| }

(gdb) p sizeof(*vla_ptr)

yields sizeof (size_t) * n.

2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
	value and retrieve the dynamic type size.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/eval.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gdb/eval.c b/gdb/eval.c
index a81e789..b3e45ca 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -3027,6 +3027,8 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
       type = check_typedef (TYPE_TARGET_TYPE (type));
+      if (is_dynamic_type (type))
+	type = value_type (value_ind (val));
       return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 
     case UNOP_MEMVAL:
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 06/15] vla: update type from newly created value
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (4 preceding siblings ...)
  2014-04-10 12:45 ` [PATCH v6 05/15] vla: enable sizeof operator for indirection Sanimir Agovic
@ 2014-04-10 12:46 ` Sanimir Agovic
  2014-04-10 12:47 ` [PATCH v6 07/15] vla: print "variable length" for unresolved dynamic bounds Sanimir Agovic
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:46 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

Constructing a value based on a type and address might change the type
of the newly constructed value. Thus re-fetch type via value_type to ensure
we have the correct type at hand.

2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value.
	(ada_template_to_fixed_record_type_1): Likewise.
	(ada_to_fixed_type_1): Likewise.
	* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
	(cp_print_value): Likewise.
	* d-valprint.c (dynamic_array_type): Likewise.
	* eval.c (evaluate_subexp_with_coercion): Likewise.
	* findvar.c (address_of_variable): Likewise.
	* jv-valprint.c (java_value_print): Likewise.
	* valops.c (value_ind): Likewise.
	* value.c (coerce_ref): Likewise.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/ada-lang.c    | 13 +++++++++++--
 gdb/cp-valprint.c |  2 ++
 gdb/d-valprint.c  |  1 +
 gdb/eval.c        |  1 +
 gdb/jv-valprint.c |  1 +
 gdb/valops.c      |  4 ++++
 gdb/value.c       |  1 +
 7 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d08e116..caf52f2 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2300,6 +2300,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
   else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
     {
       v = value_at (type, value_address (obj));
+      type = value_type (v);
       bytes = (unsigned char *) alloca (len);
       read_memory (value_address (v) + offset, bytes, len);
     }
@@ -7658,6 +7659,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
 		 size first before creating the value.  */
 	      check_size (rtype);
 	      dval = value_from_contents_and_address (rtype, valaddr, address);
+	      rtype = value_type (dval);
 	    }
           else
             dval = dval0;
@@ -7760,7 +7762,10 @@ ada_template_to_fixed_record_type_1 (struct type *type,
       off = TYPE_FIELD_BITPOS (rtype, variant_field);
 
       if (dval0 == NULL)
-        dval = value_from_contents_and_address (rtype, valaddr, address);
+	{
+	  dval = value_from_contents_and_address (rtype, valaddr, address);
+	  rtype = value_type (dval);
+	}
       else
         dval = dval0;
 
@@ -7901,7 +7906,10 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
     return type;
 
   if (dval0 == NULL)
-    dval = value_from_contents_and_address (type, valaddr, address);
+    {
+      dval = value_from_contents_and_address (type, valaddr, address);
+      type = value_type (dval);
+    }
   else
     dval = dval0;
 
@@ -8199,6 +8207,7 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
 	      value_from_contents_and_address (fixed_record_type,
 					       valaddr,
 					       address);
+            fixed_record_type = value_type (obj);
             if (real_type != NULL)
               return to_fixed_record_type
 		(real_type, NULL,
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index bcf54ff..b868d37 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -443,6 +443,7 @@ cp_print_value_fields_rtti (struct type *type,
       /* Ugh, we have to convert back to a value here.  */
       value = value_from_contents_and_address (type, valaddr + offset,
 					       address + offset);
+      type = value_type (value);
       /* We don't actually care about most of the result here -- just
 	 the type.  We already have the correct offset, due to how
 	 val_print was initially called.  */
@@ -545,6 +546,7 @@ cp_print_value (struct type *type, struct type *real_type,
 		  base_val = value_from_contents_and_address (baseclass,
 							      buf,
 							      address + boffset);
+		  baseclass = value_type (base_val);
 		  thisoffset = 0;
 		  boffset = 0;
 		  thistype = baseclass;
diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c
index 6e9c28d..cca629a 100644
--- a/gdb/d-valprint.c
+++ b/gdb/d-valprint.c
@@ -59,6 +59,7 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr,
 
       true_type = lookup_array_range_type (true_type, 0, length - 1);
       ival = value_at (true_type, addr);
+      true_type = value_type (ival);
 
       d_val_print (true_type,
 		   value_contents_for_printing (ival),
diff --git a/gdb/eval.c b/gdb/eval.c
index b3e45ca..85cf071 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -2985,6 +2985,7 @@ evaluate_subexp_with_coercion (struct expression *exp,
 	{
 	  (*pos) += 4;
 	  val = address_of_variable (var, exp->elts[pc + 1].block);
+	  type = value_type (val);
 	  return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			     val);
 	}
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
index f465ca0..808e01b 100644
--- a/gdb/jv-valprint.c
+++ b/gdb/jv-valprint.c
@@ -65,6 +65,7 @@ java_value_print (struct value *val, struct ui_file *stream,
 	  type = lookup_pointer_type (type);
 
 	  val = value_at (type, address);
+	  type = value_type (val);
 	}
     }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index eefa8c6..4b81a7a 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -268,6 +268,7 @@ value_cast_structs (struct type *type, struct value *v2)
 	{
 	  v = value_full_object (v2, real_type, full, top, using_enc);
 	  v = value_at_lazy (real_type, value_address (v));
+	  real_type = value_type (v);
 
 	  /* We might be trying to cast to the outermost enclosing
 	     type, in which case search_struct_field won't work.  */
@@ -803,6 +804,7 @@ value_dynamic_cast (struct type *type, struct value *arg)
     return value_at_lazy (type, addr);
 
   tem = value_at (type, addr);
+  type = value_type (tem);
 
   /* The first dynamic check specified in 5.2.7.  */
   if (is_public_ancestor (arg_type, TYPE_TARGET_TYPE (resolved_type)))
@@ -1372,6 +1374,7 @@ address_of_variable (struct symbol *var, const struct block *b)
      Lazy evaluation pays off here.  */
 
   val = value_of_variable (var, b);
+  type = value_type (val);
 
   if ((VALUE_LVAL (val) == lval_memory && value_lazy (val))
       || TYPE_CODE (type) == TYPE_CODE_FUNC)
@@ -1620,6 +1623,7 @@ value_ind (struct value *arg1)
 			      (value_as_address (arg1)
 			       - value_pointed_to_offset (arg1)));
 
+      enc_type = value_type (arg2);
       return readjust_indirect_value_type (arg2, enc_type, base_type, arg1);
     }
 
diff --git a/gdb/value.c b/gdb/value.c
index 993157f..3139a8b 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3364,6 +3364,7 @@ coerce_ref (struct value *arg)
   retval = value_at_lazy (enc_type,
                           unpack_pointer (value_type (arg),
                                           value_contents (arg)));
+  enc_type = value_type (retval);
   return readjust_indirect_value_type (retval, enc_type,
                                        value_type_arg_tmp, arg);
 }
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 07/15] vla: print "variable length" for unresolved dynamic bounds
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (5 preceding siblings ...)
  2014-04-10 12:46 ` [PATCH v6 06/15] vla: update type from newly created value Sanimir Agovic
@ 2014-04-10 12:47 ` Sanimir Agovic
  2014-04-10 12:48 ` [PATCH v6 09/15] vla: resolve dynamic bounds if value contents is a constant byte-sequence Sanimir Agovic
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:47 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

1| void foo (size_t n) {
2|   int vla[n];
3| }

Given the following expression

  (gdb) ptype &vla

Gdb evaluates the expression with EVAL_AVOID_SIDE_EFFECTS and thus
does not resolve the bounds information and misinterprets the high
bound as a constant. The current output is:

  type = int (*)[1289346]

this patch deals with this case and prints:

  type = int (*)[variable length]

instead.

2013-08-30  Keven Boell  <keven.boell@intel.com>
            Sanimir Agovic  <sanimir.agovic@intel.com>

	* c-typeprint.c (c_type_print_varspec_suffix): Added
	check for not yet resolved high bound. If unresolved, print
	"variable length" string to the console instead of random
	length.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/c-typeprint.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 2757337..739d770 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -689,7 +689,11 @@ c_type_print_varspec_suffix (struct type *type,
 
 	fprintf_filtered (stream, (is_vector ?
 				   " __attribute__ ((vector_size(" : "["));
-	if (get_array_bounds (type, &low_bound, &high_bound))
+	/* Bounds are not yet resolved, print a bounds placeholder instead.  */
+	if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
+	    || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
+	  fprintf_filtered (stream, "variable length");
+	else if (get_array_bounds (type, &low_bound, &high_bound))
 	  fprintf_filtered (stream, "%s", 
 			    plongest (high_bound - low_bound + 1));
 	fprintf_filtered (stream, (is_vector ? ")))" : "]"));
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 08/15] vla: support for DW_AT_count
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (7 preceding siblings ...)
  2014-04-10 12:48 ` [PATCH v6 09/15] vla: resolve dynamic bounds if value contents is a constant byte-sequence Sanimir Agovic
@ 2014-04-10 12:48 ` Sanimir Agovic
  2014-04-10 12:49 ` [PATCH v6 11/15] test: cover subranges with present DW_AT_count attribute Sanimir Agovic
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:48 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

This patch adds support for DW_AT_count as requested in the code review:

  https://sourceware.org/ml/gdb-patches/2013-11/msg00200.html

2013-11-19  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell <keven.boell@intel.com>

	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
	property and store it as the high bound and flag the range accordingly.
	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
	RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
	* gdbtypes.h (enum range_flags): New enum.
	(struct range_bounds): Add flags member.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/dwarf2read.c | 18 ++++++++++--------
 gdb/gdbtypes.c   |  4 ++++
 gdb/gdbtypes.h   |  6 +++++-
 3 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 436d0db..155bdb1 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14340,6 +14340,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   struct attribute *attr;
   struct dynamic_prop low, high;
   int low_default_is_valid;
+  int high_bound_is_count = 0;
   const char *name;
   LONGEST negative_mask;
 
@@ -14406,15 +14407,13 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (!attr_to_dynamic_prop (attr, die, cu, &high))
     {
       attr = dwarf2_attr (die, DW_AT_count, cu);
-      if (attr)
-	{
-	  int count = dwarf2_get_attr_constant_value (attr, 1);
-	  high.data.const_val = low.data.const_val + count - 1;
-	}
-      else
+      if (attr_to_dynamic_prop (attr, die, cu, &high))
 	{
-	  /* Unspecified array length.  */
-	  high.data.const_val = low.data.const_val - 1;
+	  /* If bounds are constant do the final calculation here.  */
+	  if (low.kind == PROP_CONST && high.kind == PROP_CONST)
+	    high.data.const_val = low.data.const_val + high.data.const_val - 1;
+	  else
+	    high_bound_is_count = 1;
 	}
     }
 
@@ -14467,6 +14466,9 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   range_type = create_range_type (NULL, orig_base_type, &low, &high);
 
+  if (high_bound_is_count)
+    TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1;
+
   /* Ada expects an empty array on no boundary attributes.  */
   if (attr == NULL && cu->language != language_ada)
     TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index ce582f8..61a5b3d 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1625,6 +1625,10 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
     {
       high_bound.kind = PROP_CONST;
       high_bound.data.const_val = value;
+
+      if (TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count)
+	high_bound.data.const_val
+	  = low_bound.data.const_val + high_bound.data.const_val - 1;
     }
   else
     {
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 36e4a5f..d0757e5 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -392,7 +392,6 @@ struct dynamic_prop
   } data;
 };
 
-
 /* Determine which field of the union main_type.fields[x].loc is used.  */
 
 enum field_loc_kind
@@ -622,6 +621,11 @@ struct main_type
       /* High bound of range.  */
 
       struct dynamic_prop high;
+
+      /* True if HIGH range bound contains the number of elements in the
+	 subrange. This affects how the final hight bound is computed.  */
+
+      int flag_upper_bound_is_count : 1;
     } *bounds;
 
   } flds_bnds;
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 09/15] vla: resolve dynamic bounds if value contents is a constant byte-sequence
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (6 preceding siblings ...)
  2014-04-10 12:47 ` [PATCH v6 07/15] vla: print "variable length" for unresolved dynamic bounds Sanimir Agovic
@ 2014-04-10 12:48 ` Sanimir Agovic
  2014-04-10 14:22   ` Joel Brobecker
  2014-04-10 12:48 ` [PATCH v6 08/15] vla: support for DW_AT_count Sanimir Agovic
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:48 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

A variable location might be a constant value and therefore no inferior memory
access is needed to read the content. In this case try to resolve the type
bounds.

2013-11-26  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
	points to a constant blob.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/findvar.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/gdb/findvar.c b/gdb/findvar.c
index ec6afd6..d54637c 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -441,7 +441,10 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
   switch (SYMBOL_CLASS (var))
     {
     case LOC_CONST:
-      /* Put the constant back in target format.  */
+      if (is_dynamic_type (type))
+	/* Value is a constant byte-sequence and needs no memory access.  */
+	type = resolve_dynamic_type (type, /* Unused address.  */ 0);
+      /* Put the constant back in target format. */
       v = allocate_value (type);
       store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
 			    gdbarch_byte_order (get_type_arch (type)),
@@ -468,6 +471,9 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
       return v;
 
     case LOC_CONST_BYTES:
+      if (is_dynamic_type (type))
+	/* Value is a constant byte-sequence and needs no memory access.  */
+	type = resolve_dynamic_type (type, /* Unused address.  */ 0);
       v = allocate_value (type);
       memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
 	      TYPE_LENGTH (type));
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 10/15] vla: evaluate operand of sizeof if its type is a vla
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (9 preceding siblings ...)
  2014-04-10 12:49 ` [PATCH v6 11/15] test: cover subranges with present DW_AT_count attribute Sanimir Agovic
@ 2014-04-10 12:49 ` Sanimir Agovic
  2014-04-10 14:31   ` Joel Brobecker
  2014-04-10 12:50 ` [PATCH v6 12/15] test: multi-dimensional c99 vla Sanimir Agovic
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:49 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

The c99 standard in "6.5.3.4 The sizeof operator" states:

 If the type of the operand is a variable length array type, the operand
 is evaluated;[...]

This patch mirrors the following c99 semantic in gdb:

 1| int vla[n][m];
 2| int i = 1;
 3| sizeof(vla[i++][0]); // No sideffect
 4| assert (i == 1);
 5| sizeof(vla[i++]);    // With sideffect
 6| assert (i == 2);

Note: ptype/whatsis still do not allow any sideeffects.

This patch was motivated by:

  https://sourceware.org/ml/gdb-patches/2014-01/msg00732.html

2014-02-05  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell <keven.boell@intel.com>

	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
	(evaluate_subexp_standard): Pass noside argument.
	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
	if noside equals EVAL_NORMAL. If the subscript yields a vla type
	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.

testsuite/gdb.base/

	* vla-sideeffect.c: New file.
	* vla-sideeffect.exp: New file.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/eval.c                                | 43 +++++++++++++--
 gdb/gdbtypes.c                            |  1 +
 gdb/gdbtypes.h                            |  5 ++
 gdb/testsuite/gdb.base/vla-sideeffect.c   | 42 +++++++++++++++
 gdb/testsuite/gdb.base/vla-sideeffect.exp | 89 +++++++++++++++++++++++++++++++
 5 files changed, 176 insertions(+), 4 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.c
 create mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.exp

diff --git a/gdb/eval.c b/gdb/eval.c
index 85cf071..2824854 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -51,7 +51,8 @@ extern int overload_resolution;
 
 /* Prototypes for local functions.  */
 
-static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
+static struct value *evaluate_subexp_for_sizeof (struct expression *, int *,
+						 enum noside);
 
 static struct value *evaluate_subexp_for_address (struct expression *,
 						  int *, enum noside);
@@ -2563,7 +2564,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	  evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
 	  goto nosideret;
 	}
-      return evaluate_subexp_for_sizeof (exp, pos);
+      return evaluate_subexp_for_sizeof (exp, pos, noside);
 
     case UNOP_CAST:
       (*pos) += 2;
@@ -2998,10 +2999,13 @@ evaluate_subexp_with_coercion (struct expression *exp,
 
 /* Evaluate a subexpression of EXP, at index *POS,
    and return a value for the size of that subexpression.
-   Advance *POS over the subexpression.  */
+   Advance *POS over the subexpression. If NOSIDE is EVAL_NORMAL
+   we allow side-effects on the operand if its type is a variable
+   length array.   */
 
 static struct value *
-evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
+evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
+			    enum noside noside)
 {
   /* FIXME: This should be size_t.  */
   struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
@@ -3055,6 +3059,37 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
       return
 	value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 
+      /* 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
+	 side-effects. */
+    case BINOP_SUBSCRIPT:
+      if (noside == EVAL_NORMAL)
+	{
+	  int pc = (*pos) + 1;
+
+	  val = evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
+	  type = check_typedef (value_type (val));
+	  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+	    {
+	      type = check_typedef (TYPE_TARGET_TYPE (type));
+	      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+		{
+		  type = TYPE_INDEX_TYPE (type);
+		  /* Only re-evaluate the right hand side if the resulting type
+		     is a variable length type.  */
+		  if (TYPE_RANGE_DATA (type)->flag_bound_evaluated)
+		    {
+		      val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
+		      return value_from_longest
+			(size_type, (LONGEST)TYPE_LENGTH (value_type (val)));
+		    }
+		}
+	    }
+	}
+
+      /* Fall through.  */
+
     default:
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       return value_from_longest (size_type,
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 61a5b3d..e4c6c4c 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1647,6 +1647,7 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
     = create_range_type (NULL,
 			 TYPE_TARGET_TYPE (range_type),
 			 &low_bound, &high_bound);
+  TYPE_RANGE_DATA (range_type)->flag_bound_evaluated = 1;
   elt_type = create_array_type (copy_type (type),
 				elt_type,
 				range_type);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index d0757e5..265bdc2 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -626,6 +626,11 @@ struct main_type
 	 subrange. This affects how the final hight bound is computed.  */
 
       int flag_upper_bound_is_count : 1;
+
+      /* True if LOW or/and HIGH are resolved into a static bound from
+	 a dynamic one.  */
+
+      int flag_bound_evaluated : 1;
     } *bounds;
 
   } flds_bnds;
diff --git a/gdb/testsuite/gdb.base/vla-sideeffect.c b/gdb/testsuite/gdb.base/vla-sideeffect.c
new file mode 100644
index 0000000..6e42a64
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-sideeffect.c
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#define SIZE 10
+
+int
+main (void)
+{
+  int n = SIZE;
+  int i = 0;
+  int j = 0;
+  int vla2[SIZE][n];
+  int vla1[n];
+
+  for (i = 0; i < n; i++)
+    vla1[i] = (i * 2) + n;
+
+  for (i = 0; i < SIZE; i++)
+    for (j = 0; j < n; j++)
+      vla2[i][j] = (i + j) + n;
+
+
+  i = 0;
+  j = 0;
+
+  return 0;           /* vla-filled */
+}
diff --git a/gdb/testsuite/gdb.base/vla-sideeffect.exp b/gdb/testsuite/gdb.base/vla-sideeffect.exp
new file mode 100644
index 0000000..f6717f0
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-sideeffect.exp
@@ -0,0 +1,89 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Tests side-effects of sizeof evaluation.
+# Based on gcc/testsuite/gcc.dg/vla-4.c; vla-15.c
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "vla-filled"]
+gdb_continue_to_breakpoint "vla-filled"
+
+# Check side effects for sizeof argument.
+set sizeof_int [get_sizeof "int" 4]
+set sizeof_vla [ expr "10" * "$sizeof_int" ]
+
+gdb_test "print sizeof (vla1\[i++\])" "= ${sizeof_int}" \
+         "print sizeof (vla1\[i++\])"
+gdb_test "print i" " = 0" \
+         "print i - sizeof no side effects"
+
+gdb_test "print sizeof (++vla1\[0\])" " = ${sizeof_int}" \
+         "print sizeof (++vla1\[0\])"
+gdb_test "print vla1\[0\]" " = 10" \
+         "print vla1\[0\] - sizeof no side effects"
+
+gdb_test "ptype ++vla1\[0\]" "type = int" "ptype ++vla1\[0\]"
+gdb_test "print vla1\[0\]" " = 10" \
+         "print vla1\[0\] - ptype no side effects"
+
+gdb_test "whatis ++vla1\[0\]" "type = int" "whatis ++vla1\[0\]"
+gdb_test "print vla1\[0\]" " = 10" \
+         "print vla1\[0\] - whatis no side effects"
+
+
+gdb_test "print sizeof (vla2\[i++\])" " = ${sizeof_vla}" \
+         "print sizeof (vla2\[i++\])"
+gdb_test "print i" " = 1" \
+         "print i - sizeof with side effects (1)"
+
+gdb_test "print sizeof (vla2\[i++ + sizeof(j++)\])" " = ${sizeof_vla}" \
+         "print sizeof (vla2\[i++ + sizeof(j++)\])"
+gdb_test "print i" " = 2" \
+         "print i - sizeof with side effects (2)"
+gdb_test "print j" " = 0" \
+         "print j - sizeof with no side effects"
+
+gdb_test "ptype vla2\[i++\]" "type = int \\\[10\\\]" \
+         "ptype vla2\[i++\]"
+gdb_test "print i" " = 2" \
+         "print i - ptype with side effects (1)"
+
+gdb_test "ptype vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
+         "ptype vla2\[i++ + sizeof(j++)\]"
+gdb_test "print i" " = 2" \
+         "print i - ptype with side effects (2)"
+gdb_test "print j" " = 0" \
+         "print j - ptype with no side effects"
+
+gdb_test "whatis vla2\[i++\]" "type = int \\\[10\\\]" \
+         "whatis vla2\[i++\]"
+gdb_test "print i" " = 2" \
+         "print i - whatis with side effects (1)"
+
+gdb_test "whatis vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
+         "whatis vla2\[i++ + sizeof(j++)\]"
+gdb_test "print i" " = 2" \
+         "print i - whatis with side effects (2)"
+gdb_test "print j" " = 0" \
+         "print j - whatis with no side effects"
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 11/15] test: cover subranges with present DW_AT_count attribute
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (8 preceding siblings ...)
  2014-04-10 12:48 ` [PATCH v6 08/15] vla: support for DW_AT_count Sanimir Agovic
@ 2014-04-10 12:49 ` Sanimir Agovic
  2014-04-10 12:49 ` [PATCH v6 10/15] vla: evaluate operand of sizeof if its type is a vla Sanimir Agovic
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:49 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

The dwarf attribute DW_AT_count specifies the elements of a subrange.
This test covers subranges with present count but absent upper bound
attribute, both with static and dynamic attribute values.

2013-11-26  Sanimir Agovic  <sanimir.agovic@intel.com>
            Keven Boell  <keven.boell@intel.com>

testsuite:
	* gdb.dwarf2/count.exp: New file.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/testsuite/gdb.dwarf2/count.exp | 125 +++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)
 create mode 100644 gdb/testsuite/gdb.dwarf2/count.exp

diff --git a/gdb/testsuite/gdb.dwarf2/count.exp b/gdb/testsuite/gdb.dwarf2/count.exp
new file mode 100644
index 0000000..d52fa62
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/count.exp
@@ -0,0 +1,125 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Tests to cover DW_AT_count attribute in subranges.
+
+load_lib dwarf.exp
+
+# Only run on targets which support dwarf and gas.
+if { ![dwarf2_support] } {
+    return 0
+}
+
+standard_testfile main.c count.S
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    cu {} {
+	compile_unit {{language @DW_LANG_C99}} {
+	    declare_labels char_label array_label array_label2 static_array_label
+
+	    char_label: base_type {
+		{name char}
+		{encoding @DW_ATE_signed}
+		{byte_size 1 DW_FORM_sdata}
+	    }
+
+	    array_label: array_type {
+		{type :$char_label}
+	    } {
+		subrange_type {
+		    {count {DW_OP_lit5} SPECIAL_expr}
+		    {type :$char_label}
+		}
+	    }
+
+	    array_label2: array_type {
+		{type :$char_label}
+	    } {
+		subrange_type {
+		    {count {DW_OP_lit1} SPECIAL_expr}
+		    {type :$char_label}
+		}
+	    }
+
+	    static_array_label: array_type {
+		{type :$char_label}
+	    } {
+		subrange_type {
+		    {count 5 DW_FORM_sdata}
+		    {type :$char_label}
+		}
+	    }
+
+	    DW_TAG_variable {
+		{name array2}
+		{type :$array_label2}
+		{const_value 65 DW_FORM_udata}
+	    }
+
+	    DW_TAG_variable {
+		{name array}
+		{type :$array_label}
+		{const_value hello DW_FORM_block1}
+	    }
+
+	    DW_TAG_variable {
+		{name static_array}
+		{type :$static_array_label}
+		{const_value world DW_FORM_block1}
+	    }
+	}
+    }
+}
+
+if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
+	  object {nodebug}] != "" } {
+    return -1
+}
+
+if { [gdb_compile $asm_file ${binfile}2.o object {nodebug}] != "" } {
+    return -1
+}
+
+if { [gdb_compile [list ${binfile}1.o ${binfile}2.o] \
+	  "${binfile}" executable {}] != "" } {
+    return -1
+}
+
+global GDBFLAGS
+set saved_gdbflags $GDBFLAGS
+set GDBFLAGS [concat $GDBFLAGS " -readnow"]
+clean_restart ${testfile}
+set GDBFLAGS $saved_gdbflags
+
+if ![runto_main] {
+    perror "couldn't run to main"
+    return -1
+}
+
+gdb_test "ptype array" "type = char \\\[5\\\]" "ptype array"
+gdb_test "whatis array" "type = char \\\[5\\\]" "whatis array"
+gdb_test "print array" " = \"hello\"" "print array"
+gdb_test "print sizeof array" " = 5" "print sizeof array"
+
+gdb_test "ptype array2" "type = char \\\[1\\\]" "ptype array"
+gdb_test "whatis array2" "type = char \\\[1\\\]" "whatis array"
+gdb_test "print array2" " = \"A\"" "print array"
+gdb_test "print sizeof array2" " = 1" "print sizeof array"
+
+gdb_test "ptype static_array" "type = char \\\[5\\\]" "ptype static_array"
+gdb_test "whatis static_array" "type = char \\\[5\\\]" "whatis static_array"
+gdb_test "print static_array" " = \"world\"" "print static_array"
+gdb_test "print sizeof static_array" " = 5" "print sizeof static_array"
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 12/15] test: multi-dimensional c99 vla.
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (10 preceding siblings ...)
  2014-04-10 12:49 ` [PATCH v6 10/15] vla: evaluate operand of sizeof if its type is a vla Sanimir Agovic
@ 2014-04-10 12:50 ` Sanimir Agovic
  2014-04-10 12:51 ` [PATCH v6 13/15] test: evaluate pointers to C99 vla correctly Sanimir Agovic
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:50 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

2013-10-18  Keven Boell  <keven.boell@intel.com>
            Sanimir Agovic  <sanimir.agovic@intel.com>

gdb/testsuite:
	* gdb.base/vla-multi.c: New file.
	* gdb.base/vla-multi.exp: New file.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/testsuite/gdb.base/vla-multi.c   | 48 ++++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/vla-multi.exp | 41 ++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/vla-multi.c
 create mode 100644 gdb/testsuite/gdb.base/vla-multi.exp

diff --git a/gdb/testsuite/gdb.base/vla-multi.c b/gdb/testsuite/gdb.base/vla-multi.c
new file mode 100644
index 0000000..e5bf9e2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-multi.c
@@ -0,0 +1,48 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+void
+f1 (int n, int m, int vla_ptr[n][m])
+{
+  return;                                 /* f1_breakpoint */
+}
+
+void
+vla_mult (int n, int m)
+{
+  int vla[n][m];
+  int i, j;
+
+  for (i = 0; i < n; i++)
+    {
+      for (j = 0; j < m; j++)
+        {
+          vla[i][j] = i + j;
+        }
+    }
+
+  f1(n, m, vla);                          /* vla_filled */
+
+  return;
+}
+
+int
+main(void)
+{
+  vla_mult(2, 2);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/vla-multi.exp b/gdb/testsuite/gdb.base/vla-multi.exp
new file mode 100644
index 0000000..afc2b61
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-multi.exp
@@ -0,0 +1,41 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+set sizeof_int [get_sizeof "int" 4]
+
+gdb_breakpoint [gdb_get_line_number "vla_filled"]
+gdb_continue_to_breakpoint "vla_filled"
+gdb_test "print vla" " = \\\{\\\{0, 1\\\}, \\\{1, 2\\\}\\\}" \
+         "print vla"
+gdb_test "print vla\[0\]\[1\]" " = 1" "print vla\[0\]\[1\]"
+
+gdb_breakpoint [gdb_get_line_number "f1_breakpoint"]
+gdb_continue_to_breakpoint "f1_breakpoint"
+
+# Calculate the overall size of the vla.
+set sizeof_vla [ expr "2" * "$sizeof_int" ]
+gdb_test "ptype &vla_ptr" \
+    "type = int \\\(\\\*\\\*\\\)\\\[variable length\\\]" \
+    "ptype &vla_ptr"
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 13/15] test: evaluate pointers to C99 vla correctly.
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (11 preceding siblings ...)
  2014-04-10 12:50 ` [PATCH v6 12/15] test: multi-dimensional c99 vla Sanimir Agovic
@ 2014-04-10 12:51 ` Sanimir Agovic
  2014-04-10 12:52 ` [PATCH v6 14/15] test: basic c99 vla tests for C primitives Sanimir Agovic
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:51 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

2013-10-18  Keven Boell  <keven.boell@intel.com>
            Sanimir Agovic  <sanimir.agovic@intel.com>

gdb/testsuite:
	* gdb.base/vla-ptr.c: New file.
	* gdb.base/vla-ptr.exp: New file.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/testsuite/gdb.base/vla-ptr.c   | 58 ++++++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/vla-ptr.exp | 41 +++++++++++++++++++++++++++
 2 files changed, 99 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/vla-ptr.c
 create mode 100644 gdb/testsuite/gdb.base/vla-ptr.exp

diff --git a/gdb/testsuite/gdb.base/vla-ptr.c b/gdb/testsuite/gdb.base/vla-ptr.c
new file mode 100644
index 0000000..54d04a6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-ptr.c
@@ -0,0 +1,58 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 5
+
+void
+foo (int n, int vla_ptr[n])
+{
+  return;         /* foo_bp */
+}
+
+void
+bar (int *vla_ptr)
+{
+  return;         /* bar_bp */
+}
+
+void
+vla_func (int n)
+{
+  int vla[n];
+  typedef int typedef_vla[n];
+  typedef_vla td_vla;
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      vla[i] = 2+i;
+      td_vla[i] = 4+i;
+    }
+
+  foo(n, vla);
+  bar(vla);
+
+  return;         /* vla_func_bp */
+}
+
+int
+main (void)
+{
+  vla_func(SIZE);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/vla-ptr.exp b/gdb/testsuite/gdb.base/vla-ptr.exp
new file mode 100644
index 0000000..56c9d5b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-ptr.exp
@@ -0,0 +1,41 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+set sizeof_int [get_sizeof "int" 4]
+
+# Check that VLA passed to function (pointer) points to the first element.
+gdb_breakpoint [gdb_get_line_number "foo_bp"]
+gdb_continue_to_breakpoint "foo_bp"
+gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (foo)"
+gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (foo)"
+
+gdb_breakpoint [gdb_get_line_number "bar_bp"]
+gdb_continue_to_breakpoint "bar_bp"
+gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (bar)"
+gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (bar)"
+
+gdb_breakpoint [gdb_get_line_number "vla_func_bp"]
+gdb_continue_to_breakpoint "vla_func_bp"
+gdb_test "print td_vla" " = \\\{4, 5, 6, 7, 8\\\}" "print td_vla"
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 14/15] test: basic c99 vla tests for C primitives
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (12 preceding siblings ...)
  2014-04-10 12:51 ` [PATCH v6 13/15] test: evaluate pointers to C99 vla correctly Sanimir Agovic
@ 2014-04-10 12:52 ` Sanimir Agovic
  2014-04-10 12:53 ` [PATCH v6 15/15] test: add mi vla test Sanimir Agovic
  2014-04-10 14:39 ` [PATCH v6 00/15] Please have a final look Joel Brobecker
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:52 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

2013-10-18  Keven Boell  <keven.boell@intel.com>
            Sanimir Agovic  <sanimir.agovic@intel.com>

gdb/testsuite:
	* gdb.base/vla-datatypes.c: New file.
	* gdb.base/vla-datatypes.exp: New file.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/testsuite/gdb.base/vla-datatypes.c   |  86 +++++++++++++++++++
 gdb/testsuite/gdb.base/vla-datatypes.exp | 139 +++++++++++++++++++++++++++++++
 2 files changed, 225 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/vla-datatypes.c
 create mode 100644 gdb/testsuite/gdb.base/vla-datatypes.exp

diff --git a/gdb/testsuite/gdb.base/vla-datatypes.c b/gdb/testsuite/gdb.base/vla-datatypes.c
new file mode 100644
index 0000000..51e342e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-datatypes.c
@@ -0,0 +1,86 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#define SIZE 5
+
+struct foo
+{
+  int a;
+};
+
+typedef struct bar
+{
+  int x;
+  struct foo y;
+} BAR;
+
+void
+vla_factory (int n)
+{
+  int             int_vla[n];
+  unsigned int    unsigned_int_vla[n];
+  double          double_vla[n];
+  float           float_vla[n];
+  long            long_vla[n];
+  unsigned long   unsigned_long_vla[n];
+  char            char_vla[n];
+  short           short_vla[n];
+  unsigned short  unsigned_short_vla[n];
+  unsigned char   unsigned_char_vla[n];
+  struct foo      foo_vla[n];
+  BAR             bar_vla[n];
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      int_vla[i] = i*2;
+      unsigned_int_vla[i] = i*2;
+      double_vla[i] = i/2.0;
+      float_vla[i] = i/2.0f;
+      long_vla[i] = i*2;
+      unsigned_long_vla[i] = i*2;
+      char_vla[i] = 'A';
+      short_vla[i] = i*2;
+      unsigned_short_vla[i] = i*2;
+      unsigned_char_vla[i] = 'A';
+      foo_vla[i].a = i*2;
+      bar_vla[i].x = i*2;
+      bar_vla[i].y.a = i*2;
+    }
+
+  size_t int_size        = sizeof(int_vla);     /* vlas_filled */
+  size_t uint_size       = sizeof(unsigned_int_vla);
+  size_t double_size     = sizeof(double_vla);
+  size_t float_size      = sizeof(float_vla);
+  size_t long_size       = sizeof(long_vla);
+  size_t char_size       = sizeof(char_vla);
+  size_t short_size      = sizeof(short_vla);
+  size_t ushort_size     = sizeof(unsigned_short_vla);
+  size_t uchar_size      = sizeof(unsigned_char_vla);
+  size_t foo_size        = sizeof(foo_vla);
+  size_t bar_size        = sizeof(bar_vla);
+
+  return;                                 /* break_end_of_vla_factory */
+}
+
+int
+main (void)
+{
+  vla_factory(SIZE);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/vla-datatypes.exp b/gdb/testsuite/gdb.base/vla-datatypes.exp
new file mode 100644
index 0000000..8247658
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-datatypes.exp
@@ -0,0 +1,139 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "vlas_filled"]
+gdb_continue_to_breakpoint "vlas_filled"
+
+# Check the values of VLA's.
+gdb_test "print int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print int_vla"
+gdb_test "print unsigned_int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print unsigned_int_vla"
+gdb_test "print double_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
+         "print double_vla"
+gdb_test "print float_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
+         "print float_vla"
+gdb_test "print long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print long_vla"
+gdb_test "print unsigned_long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print unsigned_long_vla"
+gdb_test "print char_vla" " = \"AAAAA\"" \
+         "print char_vla"
+gdb_test "print short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print short_vla"
+gdb_test "print unsigned_short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print unsigned_short_vla"
+gdb_test "print unsigned_char_vla" " = \"AAAAA\"" \
+         "print unsigned_char_vla"
+gdb_test "print foo_vla" \
+         "\\\{\\\{a = 0\\\}, \\\{a = 2\\\}, \\\{a = 4\\\}, \\\{a = 6\\\}, \\\{a = 8\\\}\\\}" \
+         "print foo_vla"
+gdb_test "print bar_vla" \
+         "\\\{\\\{x = 0, y = \\\{a = 0\\\}\\\}, \\\{x = 2, y = \\\{a = 2\\\}\\\}, \\\{x = 4, y = \\\{a = 4\\\}\\\}, \\\{x = 6, y = \\\{a = 6\\\}\\\}, \\\{x = 8, y = \\\{a = 8\\\}\\\}\\\}" \
+         "print bar_vla"
+
+# Check whatis of VLA's.
+gdb_test "whatis int_vla" "type = int \\\[5\\\]" "whatis int_vla"
+gdb_test "whatis unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
+         "whatis unsigned_int_vla"
+gdb_test "whatis double_vla" "type = double \\\[5\\\]" "whatis double_vla"
+gdb_test "whatis float_vla" "type = float \\\[5\\\]" "whatis float_vla"
+gdb_test "whatis long_vla" "type = long( int)? \\\[5\\\]" "whatis long_vla"
+gdb_test "whatis unsigned_long_vla" \
+         "type = (long unsigned int|unsigned long) \\\[5\\\]" \
+         "whatis unsigned_long_vla"
+gdb_test "whatis char_vla" "type = char \\\[5\\\]" "whatis char_vla"
+gdb_test "whatis short_vla" "type = short( int)? \\\[5\\\]" \
+         "whatis short_vla"
+gdb_test "whatis unsigned_short_vla" \
+         "type = (short unsigned int|unsigned short) \\\[5\\\]" \
+         "whatis unsigned_short_vla"
+gdb_test "whatis unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
+         "whatis unsigned_char_vla"
+gdb_test "whatis foo_vla" "type = struct foo \\\[5\\\]" "whatis foo_vla"
+gdb_test "whatis bar_vla" "type = BAR \\\[5\\\]" "whatis bar_vla"
+
+# Check ptype of VLA's.
+gdb_test "ptype int_vla" "type = int \\\[5\\\]" "ptype int_vla"
+gdb_test "ptype unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
+         "ptype unsigned_int_vla"
+gdb_test "ptype double_vla" "type = double \\\[5\\\]" "ptype double_vla"
+gdb_test "ptype float_vla" "type = float \\\[5\\\]" "ptype float_vla"
+gdb_test "ptype long_vla" "type = long( int)? \\\[5\\\]" "ptype long_vla"
+gdb_test "ptype unsigned_long_vla" "type = unsigned long \\\[5\\\]" \
+         "ptype unsigned_long_vla"
+gdb_test "ptype char_vla" "type = char \\\[5\\\]" "ptype char_vla"
+gdb_test "ptype short_vla" "type = short( int)? \\\[5\\\]" \
+         "ptype short_vla"
+gdb_test "ptype unsigned_short_vla" "type = unsigned short \\\[5\\\]" \
+         "ptype unsigned_short_vla"
+gdb_test "ptype unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
+         "ptype unsigned_char_vla"
+gdb_test "ptype foo_vla" "type = struct foo {\r\n\\s+int a;\r\n} \\\[5\\\]" \
+         "ptype foo_vla"
+gdb_test "ptype bar_vla" \
+         "type = struct bar {\r\n\\s+int x;\r\n\\s+struct foo y;\r\n} \\\[5\\\]" \
+         "ptype bar_vla"
+
+# Check the size of the VLA's.
+gdb_breakpoint [gdb_get_line_number "break_end_of_vla_factory"]
+gdb_continue_to_breakpoint "break_end_of_vla_factory"
+gdb_test "print int_size == sizeof(int_vla)" " = 1" "size of int_vla"
+gdb_test "print uint_size == sizeof(unsigned_int_vla)" " = 1" \
+         "size of unsigned_int_vla"
+gdb_test "print double_size == sizeof(double_vla)" " = 1" \
+         "size of double_vla"
+gdb_test "print float_size == sizeof(float_vla)" " = 1" \
+         "size of float_vla"
+gdb_test "print long_size == sizeof(long_vla)" " = 1" \
+         "size of long_vla"
+gdb_test "print char_size == sizeof(char_vla)" " = 1" \
+         "size of char_vla"
+gdb_test "print short_size == sizeof(short_vla)" " = 1" \
+         "size of short_vla"
+gdb_test "print ushort_size == sizeof(unsigned_short_vla)" " = 1" \
+         "size of unsigned_short_vla"
+gdb_test "print uchar_size == sizeof(unsigned_char_vla)" " = 1" \
+         "size of unsigned_char_vla"
+gdb_test "print foo_size == sizeof(foo_vla)" " = 1" "size of foo_vla"
+gdb_test "print bar_size == sizeof(bar_vla)" " = 1" "size of bar_vla"
+
+# Check side effects for sizeof argument.
+set sizeof_int [get_sizeof "int" 4]
+gdb_test_no_output  "set variable int_vla\[0\] = 42" \
+                    "set variable int_vla\[0\] = 42"
+
+gdb_test "print sizeof (++int_vla\[0\])" " = ${sizeof_int}" \
+         "print sizeof (++int_vla\[0\])"
+gdb_test "print int_vla\[0\]" " = 42" \
+         "print int_vla\[0\] - sizeof no side effects"
+
+gdb_test "ptype ++int_vla\[0\]" "type = int" "ptype ++int_vla\[0\]"
+gdb_test "print int_vla\[0\]" " = 42" \
+         "print int_vla\[0\] - ptype no side effects"
+
+gdb_test "whatis ++int_vla\[0\]" "type = int" "whatis ++int_vla\[0\]"
+gdb_test "print int_vla\[0\]" " = 42" \
+         "print int_vla\[0\] - whatis no side effects"
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v6 15/15] test: add mi vla test
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (13 preceding siblings ...)
  2014-04-10 12:52 ` [PATCH v6 14/15] test: basic c99 vla tests for C primitives Sanimir Agovic
@ 2014-04-10 12:53 ` Sanimir Agovic
  2014-04-10 14:39 ` [PATCH v6 00/15] Please have a final look Joel Brobecker
  15 siblings, 0 replies; 46+ messages in thread
From: Sanimir Agovic @ 2014-04-10 12:53 UTC (permalink / raw)
  To: brobecker; +Cc: gdb-patches, tromey

2013-10-18  Keven Boell  <keven.boell@intel.com>
            Sanimir Agovic  <sanimir.agovic@intel.com>

testsuite/gdb.mi/

	* mi-vla-c99.exp: New file.
	* vla.c: New file.


Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
---
 gdb/testsuite/gdb.mi/mi-vla-c99.exp | 82 +++++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.mi/vla.c          | 37 +++++++++++++++++
 2 files changed, 119 insertions(+)
 create mode 100644 gdb/testsuite/gdb.mi/mi-vla-c99.exp
 create mode 100644 gdb/testsuite/gdb.mi/vla.c

diff --git a/gdb/testsuite/gdb.mi/mi-vla-c99.exp b/gdb/testsuite/gdb.mi/mi-vla-c99.exp
new file mode 100644
index 0000000..618e8ab
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-vla-c99.exp
@@ -0,0 +1,82 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# Contributed by Intel Corp. <keven.boell@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Verify that, using the MI, we can evaluate a simple C Variable Length
+# Array (VLA).
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+standard_testfile vla.c
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" \
+                  "${binfile}" executable {debug}] != "" } {
+     untested mi-vla-basics.exp
+     return -1
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+set bp_lineno [gdb_get_line_number "vla-filled"]
+
+mi_create_breakpoint "-t vla.c:$bp_lineno" 1 "del" "func" \
+             ".*vla.c" $bp_lineno $hex \
+             "insert breakpoint at line $bp_lineno after vla is filled"
+mi_run_cmd
+mi_expect_stop "breakpoint-hit" "func" "\{name=\"n\",value=\"5\"\}" \
+               ".*vla.c" "$bp_lineno" { "" "disp=\"del\"" } \
+               "run to breakpoint at line $bp_lineno"
+
+mi_gdb_test "500-data-evaluate-expression vla" \
+    "500\\^done,value=\"\\{0, 1, 2, 3, 4\\}\"" "evaluate complete vla"
+
+mi_gdb_test "501-data-evaluate-expression vla\[0\]" \
+    "501\\^done,value=\"0\"" "evaluate vla\[0\]"
+
+mi_gdb_test "502-data-evaluate-expression vla\[2\]" \
+    "502\\^done,value=\"2\"" "evaluate vla\[2\]"
+
+mi_gdb_test "503-data-evaluate-expression vla\[4\]" \
+    "503\\^done,value=\"4\"" "evaluate vla\[4\]"
+
+mi_create_varobj_checked vla vla "int \\\[5\\\]" \
+                                 "create local variable vla"
+
+mi_gdb_test "504-var-info-type vla" \
+    "504\\^done,type=\"int \\\[5\\\]\"" \
+    "info type variable vla"
+
+mi_gdb_test "505-var-show-format vla" \
+    "505\\^done,format=\"natural\"" \
+    "show format variable vla"
+
+mi_gdb_test "506-var-evaluate-expression vla" \
+    "506\\^done,value=\"\\\[5\\\]\"" \
+    "eval variable vla"
+
+mi_list_array_varobj_children "vla" "5" "int" \
+    "get children of vla"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/vla.c b/gdb/testsuite/gdb.mi/vla.c
new file mode 100644
index 0000000..a26244b
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/vla.c
@@ -0,0 +1,37 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Contributed by Intel Corp. <keven.boell@intel.com>
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+func (int n)
+{
+  int vla[n], i;
+
+  for (i = 0; i < n; i++)
+    vla[i] = i;
+
+  return n;                 /* vla-filled */
+}
+
+int
+main (void)
+{
+  func (5);
+
+  return 0;
+}
-- 
1.8.4.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 03/15] type: add c99 variable length array support
  2014-04-10 12:44 ` [PATCH v6 03/15] type: add c99 variable length array support Sanimir Agovic
@ 2014-04-10 14:21   ` Joel Brobecker
  0 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-10 14:21 UTC (permalink / raw)
  To: Sanimir Agovic; +Cc: gdb-patches, tromey

On Thu, Apr 10, 2014 at 02:40:05PM +0200, Sanimir Agovic wrote:
> The dwarf standard allow certain attributes to be expressed as dwarf
> expressions rather than constants. For instance upper-/lowerbound attributes.
> In case of a c99 variable length array the upperbound is a dynamic attribute.
> 
> With this change c99 vla behave the same as with static arrays.
> 
> 1| void foo (size_t n) {
> 2|   int ary[n];
> 3|   memset(ary, 0, sizeof(ary));
> 4| }
> 
> (gdb) print ary
> $1 = {0 <repeats 42 times>}
> 
> 2013-10-18  Sanimir Agovic  <sanimir.agovic@intel.com>
>             Keven Boell  <keven.boell@intel.com>
> 
> 	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
> 	(dwarf2_evaluate_property): New function.
> 	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
> 	* dwarf2read.c (attr_to_dynamic_prop): New function.
> 	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
> 	attribute.
> 	* gdbtypes.c: Include dwarf2loc.h.
> 	(is_dynamic_type): New function.
> 	(resolve_dynamic_type): New function.
> 	(resolve_dynamic_bounds): New function.
> 	(get_type_length): New function.
> 	(check_typedef): Use get_type_length to compute type length.
> 	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
> 	(TYPE_LOW_BOUND_KIND): New macro.
> 	(is_dynamic_type): New function prototype.
> 	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
> 	to resolve dynamic properties of the type. Update comment.
> 	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.

LGTM. Pre-approved with the following minor corrections outlined below.
It's nice to see that there were even more simplifications that could
be made after abandonning types deep copies!

> 
> 
> Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
> ---
>  gdb/dwarf2loc.c  | 119 +++++++++++++++++++++++++++++++++
>  gdb/dwarf2loc.h  |  28 ++++++++
>  gdb/dwarf2read.c | 106 +++++++++++++++++++++--------
>  gdb/gdbtypes.c   | 199 +++++++++++++++++++++++++++++++++++++++++--------------
>  gdb/gdbtypes.h   |  10 +++
>  gdb/valops.c     |  15 ++++-
>  gdb/value.c      |  19 ++++--
>  7 files changed, 409 insertions(+), 87 deletions(-)
> 
> diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
> index 2b1f323..d903322 100644
> --- a/gdb/dwarf2loc.c
> +++ b/gdb/dwarf2loc.c
> @@ -2431,6 +2431,125 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
>    return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
>  }
>  
> +/* Evaluates a dwarf expression and stores the result in VAL, expecting
> +   that the dwarf expression only produces a single CORE_ADDR.  ADDR is a
> +   context (location of a variable) and might be needed to evaluate the
> +   location expression.
> +   Returns 1 on success, 0 otherwise.   */
> +
> +static int
> +dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
> +			   CORE_ADDR addr, CORE_ADDR *valp)
> +{
> +  struct dwarf_expr_context *ctx;
> +  struct dwarf_expr_baton baton;
> +  struct objfile *objfile;
> +  struct cleanup *cleanup;
> +
> +  if (dlbaton == NULL || dlbaton->size == 0)
> +    return 0;
> +
> +  ctx = new_dwarf_expr_context ();
> +  cleanup = make_cleanup_free_dwarf_expr_context (ctx);
> +
> +  baton.frame = get_selected_frame (NULL);
> +  baton.per_cu = dlbaton->per_cu;
> +
> +  objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
> +
> +  ctx->gdbarch = get_objfile_arch (objfile);
> +  ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
> +  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
> +  ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
> +  ctx->funcs = &dwarf_expr_ctx_funcs;
> +  ctx->baton = &baton;
> +
> +  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
> +
> +  switch (ctx->location)
> +    {
> +    case DWARF_VALUE_REGISTER:
> +    case DWARF_VALUE_MEMORY:
> +    case DWARF_VALUE_STACK:
> +      *valp = dwarf_expr_fetch_address (ctx, 0);
> +      if (ctx->location == DWARF_VALUE_REGISTER)
> +	*valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
> +      do_cleanups (cleanup);
> +      return 1;
> +    case DWARF_VALUE_LITERAL:
> +      *valp = extract_signed_integer (ctx->data, ctx->len,
> +				      gdbarch_byte_order (ctx->gdbarch));
> +      do_cleanups (cleanup);
> +      return 1;
> +      /* Unsupported dwarf values.  */
> +    case DWARF_VALUE_OPTIMIZED_OUT:
> +    case DWARF_VALUE_IMPLICIT_POINTER:
> +      break;
> +    }
> +
> +  do_cleanups (cleanup);
> +  return 0;
> +}
> +
> +/* See dwarf2loc.h.  */
> +
> +int
> +dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address,
> +			  CORE_ADDR *value)
> +{
> +  if (prop == NULL)
> +    return 0;
> +
> +  switch (prop->kind)
> +    {
> +    case PROP_LOCEXPR:
> +      {
> +	const struct dwarf2_property_baton *baton = prop->data.baton;
> +
> +	if (dwarf2_locexpr_baton_eval (&baton->locexpr, address, value))
> +	  {
> +	    if (baton->referenced_type)
> +	      {
> +		struct value *val = value_at (baton->referenced_type, *value);
> +
> +		*value = value_as_address (val);
> +	      }
> +	    return 1;
> +	  }
> +      }
> +      break;
> +
> +    case PROP_LOCLIST:
> +      {
> +	struct dwarf2_property_baton *baton = prop->data.baton;
> +	struct frame_info *frame = get_selected_frame (NULL);
> +	CORE_ADDR pc = get_frame_address_in_block (frame);
> +	const gdb_byte *data;
> +	struct value *val;
> +	size_t size;
> +
> +	data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
> +	if (data != NULL)
> +	  {
> +	    val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data,
> +					    size, baton->loclist.per_cu);
> +	    if (!value_optimized_out (val))
> +	      {
> +		*value = value_as_address (val);
> +		return 1;
> +	      }
> +	  }
> +      }
> +      break;
> +
> +    case PROP_CONST:
> +      *value = prop->data.const_val;
> +      return 1;
> +    }
> +
> +  return 0;
> +}
> +
>  \f
>  /* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
>  
> diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
> index 9bc8ca5..94d9c5f 100644
> --- a/gdb/dwarf2loc.h
> +++ b/gdb/dwarf2loc.h
> @@ -90,6 +90,14 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
>  					size_t size,
>  					struct dwarf2_per_cu_data *per_cu);
>  
> +/* Converts a dynamic property into a static one.  ADDR is the address of
> +   the object currently being evaluated and might be nedded.
> +   Returns 1 if PROP could be converted and the static value is passed back
> +   into VALUE, otherwise returns 0.  */
> +
> +int dwarf2_evaluate_property (const struct dynamic_prop *prop,
> +			      CORE_ADDR addr, CORE_ADDR *value);
> +
>  CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
>  				  unsigned int addr_index);
>  
> @@ -135,6 +143,26 @@ struct dwarf2_loclist_baton
>    unsigned char from_dwo;
>  };
>  
> +/* A dynamic property is either expressed as a single location expression
> +   or a location list.  If the property is an indirection, pointing to
> +   another die, keep track of the targeted type in REFERENCED_TYPE.  */
> +
> +struct dwarf2_property_baton
> +{
> +  /* If the property is an indirection, we need to evaluate the location
> +     LOCEXPR or LOCLIST in the context of the type REFERENCED_TYPE.
> +     If NULL, the location is the actual value of the property.  */
> +  struct type *referenced_type;
> +  union
> +  {
> +    /* Location expression.  */
> +    struct dwarf2_locexpr_baton locexpr;
> +
> +    /* Location list to be evaluated in the context of TYPE.  */
> +    struct dwarf2_loclist_baton loclist;

I missed that one in my first review, but I think you meant
REFERENCED_TYPE, rather than TYPE?

> +  };
> +};
> +
>  extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
>  extern const struct symbol_computed_ops dwarf2_loclist_funcs;
>  
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index 101065b..436d0db 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -14252,6 +14252,84 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
>    return set_die_type (die, type, cu);
>  }
>  
> +/* Parse dwarf attribute if it's a block, reference or constant and put the
> +   resulting value of the attribute into struct bound_prop.
> +   Returns 1 if ATTR could be resolved into PROP, 0 otherwise.  */
> +
> +static int
> +attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
> +		      struct dwarf2_cu *cu, struct dynamic_prop *prop)
> +{
> +  struct dwarf2_property_baton *baton;
> +  struct obstack *obstack = &cu->objfile->objfile_obstack;
> +
> +  if (attr == NULL || prop == NULL)
> +    return 0;
> +
> +  if (attr_form_is_block (attr))
> +    {
> +      baton = obstack_alloc (obstack, sizeof (*baton));
> +      baton->referenced_type = NULL;
> +      baton->locexpr.per_cu = cu->per_cu;
> +      baton->locexpr.size = DW_BLOCK (attr)->size;
> +      baton->locexpr.data = DW_BLOCK (attr)->data;
> +      prop->data.baton = baton;
> +      prop->kind = PROP_LOCEXPR;
> +      gdb_assert (prop->data.baton != NULL);
> +    }
> +  else if (attr_form_is_ref (attr))
> +    {
> +      struct dwarf2_cu *target_cu = cu;
> +      struct die_info *target_die;
> +      struct attribute *target_attr;
> +
> +      target_die = follow_die_ref (die, attr, &target_cu);
> +      target_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
> +      if (target_attr == NULL)
> +	return 0;
> +
> +      if (attr_form_is_section_offset (target_attr))
> +	{
> +	  baton = obstack_alloc (obstack, sizeof (*baton));
> +	  baton->referenced_type = die_type (target_die, target_cu);
> +	  fill_in_loclist_baton (cu, &baton->loclist, target_attr);
> +	  prop->data.baton = baton;
> +	  prop->kind = PROP_LOCLIST;
> +	  gdb_assert (prop->data.baton != NULL);
> +	}
> +      else if (attr_form_is_block (target_attr))
> +	{
> +	  baton = obstack_alloc (obstack, sizeof (*baton));
> +	  baton->referenced_type = die_type (target_die, target_cu);
> +	  baton->locexpr.per_cu = cu->per_cu;
> +	  baton->locexpr.size = DW_BLOCK (target_attr)->size;
> +	  baton->locexpr.data = DW_BLOCK (target_attr)->data;
> +	  prop->data.baton = baton;
> +	  prop->kind = PROP_LOCEXPR;
> +	  gdb_assert (prop->data.baton != NULL);
> +	}
> +      else
> +	{
> +	  dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
> +						 "dynamic property");
> +	  return 0;
> +	}
> +    }
> +  else if (attr_form_is_constant (attr))
> +    {
> +      prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
> +      prop->kind = PROP_CONST;
> +    }
> +  else
> +    {
> +      dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
> +					     dwarf2_name (die, cu));
> +      return 0;
> +    }
> +
> +  return 1;
> +}
> +
>  /* Read the given DW_AT_subrange DIE.  */
>  
>  static struct type *
> @@ -14325,27 +14403,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
>  	       die->offset.sect_off, objfile_name (cu->objfile));
>  
>    attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
> -  if (attr)
> -    {
> -      if (attr_form_is_block (attr) || attr_form_is_ref (attr))
> -        {
> -          /* GCC encodes arrays with unspecified or dynamic length
> -             with a DW_FORM_block1 attribute or a reference attribute.
> -             FIXME: GDB does not yet know how to handle dynamic
> -             arrays properly, treat them as arrays with unspecified
> -             length for now.
> -
> -             FIXME: jimb/2003-09-22: GDB does not really know
> -             how to handle arrays of unspecified length
> -             either; we just represent them as zero-length
> -             arrays.  Choose an appropriate upper bound given
> -             the lower bound we've computed above.  */
> -          high.data.const_val = low.data.const_val - 1;
> -        }
> -      else
> -        high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
> -    }
> -  else
> +  if (!attr_to_dynamic_prop (attr, die, cu, &high))
>      {
>        attr = dwarf2_attr (die, DW_AT_count, cu);
>        if (attr)
> @@ -14409,12 +14467,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
>  
>    range_type = create_range_type (NULL, orig_base_type, &low, &high);
>  
> -  /* Mark arrays with dynamic length at least as an array of unspecified
> -     length.  GDB could check the boundary but before it gets implemented at
> -     least allow accessing the array elements.  */
> -  if (attr && attr_form_is_block (attr))
> -    TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
> -
>    /* Ada expects an empty array on no boundary attributes.  */
>    if (attr == NULL && cu->language != language_ada)
>      TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index 7f0269c..ce582f8 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -853,6 +853,17 @@ create_static_range_type (struct type *result_type, struct type *index_type,
>    return result_type;
>  }
>  
> +/* Predicate tests whether BOUNDS are static.  Returns 1 if all bounds values
> +   are static, otherwise returns 0.  */
> +
> +static int
> +has_static_range (const struct range_bounds *bounds)
> +{
> +  return (bounds->low.kind == PROP_CONST
> +	  && bounds->high.kind == PROP_CONST);
> +}
> +
> +
>  /* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
>     TYPE.  Return 1 if type is a range type, 0 if it is discrete (and
>     bounds will fit in LONGEST), or -1 otherwise.  */
> @@ -982,24 +993,31 @@ create_array_type (struct type *result_type,
>  		   struct type *element_type,
>  		   struct type *range_type)
>  {
> -  LONGEST low_bound, high_bound;
> -
>    if (result_type == NULL)
>      result_type = alloc_type_copy (range_type);
>  
>    TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
>    TYPE_TARGET_TYPE (result_type) = element_type;
> -  if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
> -    low_bound = high_bound = 0;
> -  CHECK_TYPEDEF (element_type);
> -  /* Be careful when setting the array length.  Ada arrays can be
> -     empty arrays with the high_bound being smaller than the low_bound.
> -     In such cases, the array length should be zero.  */
> -  if (high_bound < low_bound)
> -    TYPE_LENGTH (result_type) = 0;
> +
> +  if (has_static_range (TYPE_RANGE_DATA (range_type)))
> +    {
> +      LONGEST low_bound, high_bound;
> +
> +      if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
> +	low_bound = high_bound = 0;
> +      CHECK_TYPEDEF (element_type);
> +      /* Be careful when setting the array length.  Ada arrays can be
> +	 empty arrays with the high_bound being smaller than the low_bound.
> +	 In such cases, the array length should be zero.  */
> +      if (high_bound < low_bound)
> +	TYPE_LENGTH (result_type) = 0;
> +      else
> +	TYPE_LENGTH (result_type) =
> +	  TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
> +    }
>    else
> -    TYPE_LENGTH (result_type) =
> -      TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
> +    TYPE_LENGTH (result_type) = 0;

Thanks for making that change. I think it'd be worth while explaining
why we set the length to zero. How about the following:

  else
    {
      /* This type is dynamic and its length needs to be computed
         on demand.  In the meantime, avoid leaving the TYPE_LENGTH
         undefined by setting it to zero.  Although we are not expected
         to trust TYPE_LENGTH in this case, setting the size to zero
         allows us to avoid allocating objects of random sizes in case
         we accidently do.  */
      TYPE_LENGTH (result_type) = 0;
    }

> +
>    TYPE_NFIELDS (result_type) = 1;
>    TYPE_FIELDS (result_type) =
>      (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
> @@ -1530,6 +1548,124 @@ stub_noname_complaint (void)
>    complaint (&symfile_complaints, _("stub type has NULL name"));
>  }
>  
> +/* See gdbtypes.h.  */
> +
> +int
> +is_dynamic_type (struct type *type)
> +{
> +  type = check_typedef (type);
> +
> +  if (TYPE_CODE (type) == TYPE_CODE_REF)
> +    type = check_typedef (TYPE_TARGET_TYPE (type));
> +
> +  switch (TYPE_CODE (type))
> +    {
> +    case TYPE_CODE_ARRAY:
> +      {
> +	const struct type *range_type;
> +
> +	gdb_assert (TYPE_NFIELDS (type) == 1);
> +	range_type = TYPE_INDEX_TYPE (type);
> +	if (!has_static_range (TYPE_RANGE_DATA (range_type)))
> +	  return 1;
> +	else
> +	  return is_dynamic_type (TYPE_TARGET_TYPE (type));
> +	break;
> +      }
> +    default:
> +      return 0;
> +      break;
> +    }
> +}
> +
> +/* Resolves dynamic bound values of an array type TYPE to static ones.
> +   ADDRESS might be needed to resolve the subrange bounds, it is the location
> +   of the associated array.  */
> +
> +static struct type *
> +resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
> +{
> +  CORE_ADDR value;
> +  struct type *elt_type;
> +  struct type *range_type;
> +  struct type *ary_dim;
> +  const struct dynamic_prop *prop;
> +  const struct dwarf2_locexpr_baton *baton;
> +  struct dynamic_prop low_bound, high_bound;
> +
> +  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
> +    {
> +      struct type *copy = copy_type (type);
> +
> +      TYPE_TARGET_TYPE (copy)
> +	= resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
> +
> +      return copy;
> +    }
> +
> +  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
> +
> +  elt_type = type;
> +  range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
> +
> +  prop = &TYPE_RANGE_DATA (range_type)->low;
> +  if (dwarf2_evaluate_property (prop, addr, &value))
> +    {
> +      low_bound.kind = PROP_CONST;
> +      low_bound.data.const_val = value;
> +    }
> +  else
> +    {
> +      low_bound.kind = PROP_UNDEFINED;
> +      low_bound.data.const_val = 0;
> +    }
> +
> +  prop = &TYPE_RANGE_DATA (range_type)->high;
> +  if (dwarf2_evaluate_property (prop, addr, &value))
> +    {
> +      high_bound.kind = PROP_CONST;
> +      high_bound.data.const_val = value;
> +    }
> +  else
> +    {
> +      high_bound.kind = PROP_UNDEFINED;
> +      high_bound.data.const_val = 0;
> +    }
> +
> +  ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
> +
> +  if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
> +    elt_type = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
> +  else
> +    elt_type = TYPE_TARGET_TYPE (type);
> +
> +  range_type
> +    = create_range_type (NULL,
> +			 TYPE_TARGET_TYPE (range_type),
> +			 &low_bound, &high_bound);

There was a small nit-pick request here, and since you're going to be
touching this code again (see below), would you mind...

Joel> Small formatting nit-pick (while we're touching this code):
Joel>
Joel>   range_type = create_range_type (NULL,
Joel>                                   TYPE_TARGET_TYPE (range_type),
Joel>                                   &low_bound, &high_bound);

> +  elt_type = create_array_type (copy_type (type),
> +				elt_type,
> +				range_type);
> +
> +  return elt_type;

Can you avoid assigning the array types being created to elt_type
(possibly confusing), and just do...

    return create_array_type (copy_type (type), elt_type, range_type);

... instead?


> +}
> +
> +/* See gdbtypes.h  */
> +
> +struct type *
> +resolve_dynamic_type (struct type *type, CORE_ADDR addr)
> +{
> +  struct type *real_type = check_typedef (type);
> +  struct type *resolved_type;
> +
> +  if (!is_dynamic_type (real_type))
> +    return type;
> +
> +  resolved_type = resolve_dynamic_bounds (type, addr);
> +
> +  return resolved_type;
> +}
> +
>  /* Find the real type of TYPE.  This function returns the real type,
>     after removing all layers of typedefs, and completing opaque or stub
>     types.  Completion changes the TYPE argument, but stripping of
> @@ -1705,45 +1841,6 @@ check_typedef (struct type *type)
>  	{
>  	  /* Nothing we can do.  */
>  	}
> -      else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
> -	       && TYPE_NFIELDS (type) == 1
> -	       && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
> -		   == TYPE_CODE_RANGE))
> -	{
> -	  /* Now recompute the length of the array type, based on its
> -	     number of elements and the target type's length.
> -	     Watch out for Ada null Ada arrays where the high bound
> -	     is smaller than the low bound.  */
> -	  const LONGEST low_bound = TYPE_LOW_BOUND (range_type);
> -	  const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
> -	  ULONGEST len;
> -
> -	  if (high_bound < low_bound)
> -	    len = 0;
> -	  else
> -	    {
> -	      /* For now, we conservatively take the array length to be 0
> -		 if its length exceeds UINT_MAX.  The code below assumes
> -		 that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
> -		 which is technically not guaranteed by C, but is usually true
> -		 (because it would be true if x were unsigned with its
> -		 high-order bit on).  It uses the fact that
> -		 high_bound-low_bound is always representable in
> -		 ULONGEST and that if high_bound-low_bound+1 overflows,
> -		 it overflows to 0.  We must change these tests if we 
> -		 decide to increase the representation of TYPE_LENGTH
> -		 from unsigned int to ULONGEST.  */
> -	      ULONGEST ulow = low_bound, uhigh = high_bound;
> -	      ULONGEST tlen = TYPE_LENGTH (target_type);
> -
> -	      len = tlen * (uhigh - ulow + 1);
> -	      if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh 
> -		  || len > UINT_MAX)
> -		len = 0;
> -	    }
> -	  TYPE_LENGTH (type) = len;
> -	  TYPE_TARGET_STUB (type) = 0;
> -	}
>        else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
>  	{
>  	  TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index f6e68c5..36e4a5f 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -1,3 +1,4 @@
> +
>  /* Internal type definitions for GDB.
>  
>     Copyright (C) 1992-2013 Free Software Foundation, Inc.
> @@ -1574,6 +1575,15 @@ extern struct type *lookup_unsigned_typename (const struct language_defn *,
>  extern struct type *lookup_signed_typename (const struct language_defn *,
>  					    struct gdbarch *, const char *);
>  
> +/* Resolve all dynamic values of a type e.g. array bounds to static values.
> +   ADDR specifies the location of the variable the type is bound to.
> +   If TYPE has no dynamic properties return TYPE; otherwise a new type with
> +   static properties is returned.  */
> +extern struct type *resolve_dynamic_type (struct type *type, CORE_ADDR addr);
> +
> +/* Predicate if the type has dynamic values, which are not resolved yet.  */
> +extern int is_dynamic_type (struct type *type);
> +
>  extern struct type *check_typedef (struct type *);
>  
>  #define CHECK_TYPEDEF(TYPE)			\
> diff --git a/gdb/valops.c b/gdb/valops.c
> index 5c7bb89..eefa8c6 100644
> --- a/gdb/valops.c
> +++ b/gdb/valops.c
> @@ -902,7 +902,10 @@ value_one (struct type *type)
>    return val;
>  }
>  
> -/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.  */
> +/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.
> +   The type of the created value may differ from the passed type TYPE.
> +   Make sure to retrieve the returned values's new type after this call
> +   e.g. in case the type is a variable length array.  */
>  
>  static struct value *
>  get_value_at (struct type *type, CORE_ADDR addr, int lazy)
> @@ -927,7 +930,10 @@ get_value_at (struct type *type, CORE_ADDR addr, int lazy)
>     value_at_lazy instead.  value_at_lazy simply records the address of
>     the data and sets the lazy-evaluation-required flag.  The lazy flag
>     is tested in the value_contents macro, which is used if and when
> -   the contents are actually required.
> +   the contents are actually required.  The type of the created value
> +   may differ from the passed type TYPE.  Make sure to retrieve the
> +   returned values's new type after this call e.g. in case the type
> +   is a variable length array.
>  
>     Note: value_at does *NOT* handle embedded offsets; perform such
>     adjustments before or after calling it.  */
> @@ -938,7 +944,10 @@ value_at (struct type *type, CORE_ADDR addr)
>    return get_value_at (type, addr, 0);
>  }
>  
> -/* Return a lazy value with type TYPE located at ADDR (cf. value_at).  */
> +/* Return a lazy value with type TYPE located at ADDR (cf. value_at).
> +   The type of the created value may differ from the passed type TYPE.
> +   Make sure to retrieve the returned values's new type after this call
> +   e.g. in case the type is a variable length array.  */
>  
>  struct value *
>  value_at_lazy (struct type *type, CORE_ADDR addr)
> diff --git a/gdb/value.c b/gdb/value.c
> index a64e7e1..993157f 100644
> --- a/gdb/value.c
> +++ b/gdb/value.c
> @@ -3178,32 +3178,39 @@ value_from_ulongest (struct type *type, ULONGEST num)
>  
>  
>  /* Create a value representing a pointer of type TYPE to the address
> -   ADDR.  */
> +   ADDR.  The type of the created value may differ from the passed
> +   type TYPE. Make sure to retrieve the returned values's new type
> +   after this call e.g. in case of an variable length array.  */
> +
>  struct value *
>  value_from_pointer (struct type *type, CORE_ADDR addr)
>  {
> -  struct value *val = allocate_value (type);
> +  struct type *resolved_type = resolve_dynamic_type (type, addr);
> +  struct value *val = allocate_value (resolved_type);
>  
> -  store_typed_address (value_contents_raw (val), check_typedef (type), addr);
> +  store_typed_address (value_contents_raw (val),
> +		       check_typedef (resolved_type), addr);
>    return val;
>  }
>  
>  
>  /* Create a value of type TYPE whose contents come from VALADDR, if it
>     is non-null, and whose memory address (in the inferior) is
> -   ADDRESS.  */
> +   ADDRESS.  The type of the created value may differ from the passed
> +   type TYPE.  Make sure to retrieve values new type after this call.  */
>  
>  struct value *
>  value_from_contents_and_address (struct type *type,
>  				 const gdb_byte *valaddr,
>  				 CORE_ADDR address)
>  {
> +  struct type *resolved_type = resolve_dynamic_type (type, address);
>    struct value *v;
>  
>    if (valaddr == NULL)
> -    v = allocate_value_lazy (type);
> +    v = allocate_value_lazy (resolved_type);
>    else
> -    v = value_from_contents (type, valaddr);
> +    v = value_from_contents (resolved_type, valaddr);
>    set_value_address (v, address);
>    VALUE_LVAL (v) = lval_memory;
>    return v;
> -- 
> 1.8.4.2

-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 09/15] vla: resolve dynamic bounds if value contents is a constant byte-sequence
  2014-04-10 12:48 ` [PATCH v6 09/15] vla: resolve dynamic bounds if value contents is a constant byte-sequence Sanimir Agovic
@ 2014-04-10 14:22   ` Joel Brobecker
  0 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-10 14:22 UTC (permalink / raw)
  To: Sanimir Agovic; +Cc: gdb-patches, tromey

> A variable location might be a constant value and therefore no inferior memory
> access is needed to read the content. In this case try to resolve the type
> bounds.
> 
> 2013-11-26  Sanimir Agovic  <sanimir.agovic@intel.com>
>             Keven Boell  <keven.boell@intel.com>
> 
> 	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
> 	points to a constant blob.

Approved, but you forgot one little request of mine... See below:

> Signed-off-by: Sanimir Agovic <sanimir.agovic@intel.com>
> ---
>  gdb/findvar.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/gdb/findvar.c b/gdb/findvar.c
> index ec6afd6..d54637c 100644
> --- a/gdb/findvar.c
> +++ b/gdb/findvar.c
> @@ -441,7 +441,10 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
>    switch (SYMBOL_CLASS (var))
>      {
>      case LOC_CONST:
> -      /* Put the constant back in target format.  */
> +      if (is_dynamic_type (type))
> +	/* Value is a constant byte-sequence and needs no memory access.  */
> +	type = resolve_dynamic_type (type, /* Unused address.  */ 0);
> +      /* Put the constant back in target format. */

Joel: Although not required by C, we prefer in the GDB project to still
Joel: use curly braces around the if block. The reason is that the comment
Joel: visually looks like a statement, so it looks like the if block as
Joel: more than one statement, hence the use of curly braces...

Same below.

>        v = allocate_value (type);
>        store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
>  			    gdbarch_byte_order (get_type_arch (type)),
> @@ -468,6 +471,9 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
>        return v;
>  
>      case LOC_CONST_BYTES:
> +      if (is_dynamic_type (type))
> +	/* Value is a constant byte-sequence and needs no memory access.  */
> +	type = resolve_dynamic_type (type, /* Unused address.  */ 0);
>        v = allocate_value (type);
>        memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
>  	      TYPE_LENGTH (type));
> -- 
> 1.8.4.2

-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 10/15] vla: evaluate operand of sizeof if its type is a vla
  2014-04-10 12:49 ` [PATCH v6 10/15] vla: evaluate operand of sizeof if its type is a vla Sanimir Agovic
@ 2014-04-10 14:31   ` Joel Brobecker
  0 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-10 14:31 UTC (permalink / raw)
  To: Sanimir Agovic; +Cc: gdb-patches, tromey

> 2014-02-05  Sanimir Agovic  <sanimir.agovic@intel.com>
>             Keven Boell <keven.boell@intel.com>
> 
> 	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
> 	(evaluate_subexp_standard): Pass noside argument.
> 	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
> 	if noside equals EVAL_NORMAL. If the subscript yields a vla type
> 	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
> 	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
> 	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.
> 
> testsuite/gdb.base/
> 
> 	* vla-sideeffect.c: New file.
> 	* vla-sideeffect.exp: New file.

Approved with some minor trivial modifications.

>  /* Evaluate a subexpression of EXP, at index *POS,
>     and return a value for the size of that subexpression.
> -   Advance *POS over the subexpression.  */
> +   Advance *POS over the subexpression. If NOSIDE is EVAL_NORMAL
                                       ^^^^^^^
Minor style nit: Two spaces after a period ("If NOSIDE")

> +		  if (TYPE_RANGE_DATA (type)->flag_bound_evaluated)
> +		    {
> +		      val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
> +		      return value_from_longest
> +			(size_type, (LONGEST)TYPE_LENGTH (value_type (val)));

I missed this one in the my first review, but there should be a space
after "(LONGEST)".

> +set sizeof_vla [ expr "10" * "$sizeof_int" ]
> +
> +gdb_test "print sizeof (vla1\[i++\])" "= ${sizeof_int}" \

Just to be consistent, let's add a space before the "=" sign.

> +         "print sizeof (vla1\[i++\])"

Thanks,
-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
                   ` (14 preceding siblings ...)
  2014-04-10 12:53 ` [PATCH v6 15/15] test: add mi vla test Sanimir Agovic
@ 2014-04-10 14:39 ` Joel Brobecker
  2014-04-10 14:46   ` Joel Brobecker
  2014-04-11 12:50   ` Agovic, Sanimir
  15 siblings, 2 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-10 14:39 UTC (permalink / raw)
  To: Sanimir Agovic; +Cc: gdb-patches, tromey

Sanimir,

> Sanimir Agovic (15):
>   refactoring: rename create_range_type to create_static_range_type
>   vla: introduce new bound type abstraction adapt uses
>   type: add c99 variable length array support
>   vla: enable sizeof operator to work with variable length arrays
>   vla: enable sizeof operator for indirection
>   vla: update type from newly created value
>   vla: print "variable length" for unresolved dynamic bounds
>   vla: support for DW_AT_count
>   vla: resolve dynamic bounds if value contents is a constant
>     byte-sequence
>   vla: evaluate operand of sizeof if its type is a vla
>   test: cover subranges with present DW_AT_count attribute
>   test: multi-dimensional c99 vla.
>   test: evaluate pointers to C99 vla correctly.
>   test: basic c99 vla tests for C primitives
>   test: add mi vla test

Success!!! The entire series is now approved (with some minor trivial
request in 3 of the patches).

You may now push the patch series. If you do not have write privileges
yet, we can request them for you, or I can push this patch series in.
Let me know.

Thanks again for this contribution.
-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-10 14:39 ` [PATCH v6 00/15] Please have a final look Joel Brobecker
@ 2014-04-10 14:46   ` Joel Brobecker
  2014-04-22 15:33     ` Agovic, Sanimir
  2014-04-11 12:50   ` Agovic, Sanimir
  1 sibling, 1 reply; 46+ messages in thread
From: Joel Brobecker @ 2014-04-10 14:46 UTC (permalink / raw)
  To: Sanimir Agovic; +Cc: gdb-patches, tromey

> You may now push the patch series. If you do not have write privileges
> yet, we can request them for you, or I can push this patch series in.
> Let me know.

I forgot - once the patch series is in, we will need a NEWS entry.
The contents should be high level, for users to be able to understand
what it is that has changed.

Thanks!
-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [PATCH v6 00/15] Please have a final look
  2014-04-10 14:39 ` [PATCH v6 00/15] Please have a final look Joel Brobecker
  2014-04-10 14:46   ` Joel Brobecker
@ 2014-04-11 12:50   ` Agovic, Sanimir
  2014-04-11 20:03     ` Keith Seitz
  1 sibling, 1 reply; 46+ messages in thread
From: Agovic, Sanimir @ 2014-04-11 12:50 UTC (permalink / raw)
  To: 'Joel Brobecker', Jan Kratochvil (jan.kratochvil@redhat.com)
  Cc: gdb-patches, tromey

> Success!!! The entire series is now approved (with some minor trivial
> request in 3 of the patches).
> 
Thank you Joel for helping me out through the patch series! I just
committed the patches including the final adjustments.

Thanks Jan for kicking off the project with:

 https://sourceware.org/ml/gdb/2012-11/msg00094.html

 -Sanimir


Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-11 12:50   ` Agovic, Sanimir
@ 2014-04-11 20:03     ` Keith Seitz
  2014-04-11 20:27       ` Joel Brobecker
  0 siblings, 1 reply; 46+ messages in thread
From: Keith Seitz @ 2014-04-11 20:03 UTC (permalink / raw)
  To: Agovic, Sanimir; +Cc: gdb-patches

On 04/11/2014 05:50 AM, Agovic, Sanimir wrote:
>> Success!!! The entire series is now approved (with some minor trivial
>> request in 3 of the patches).
>>
> Thank you Joel for helping me out through the patch series! I just
> committed the patches including the final adjustments.

Unfortunatley, this patchset has regressed the following tests:

 > FAIL: gdb.base/pointers.exp: print array element w/ pointer arithmetic
 > FAIL: gdb.cp/koenig.exp: p foo(jca)
 > FAIL: gdb.mi/mi-read-memory.exp: 3x2, one byte offset by -6
 > FAIL: gdb.mi/mi-read-memory.exp: expression in quotes
 > FAIL: gdb.mi/mi-read-memory.exp: ascii and data
 > FAIL: gdb.mi/mi-read-memory.exp: decimal
 > FAIL: gdb.mi/mi-read-memory.exp: octal
 > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str2)
 > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str3)
 > FAIL: gdb.python/py-strfns.exp: p $_strlen (str1)
 > FAIL: gdb.python/py-strfns.exp: p $_strlen (buf1)
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Hello")
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Help")
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello")
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello.$")
 > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str2)
 > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str3)
 > FAIL: gdb.python/py-strfns.exp: p $_strlen (str1)
 > FAIL: gdb.python/py-strfns.exp: p $_strlen (buf1)
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Hello")
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Help")
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello")
 > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello.$")

With --target_board=native-gdbsever, remote.exp has two additional 
failures. This is using x86_64 Fedora 20 (gcc Red Hat 4.8.2-7).

Keith

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-11 20:03     ` Keith Seitz
@ 2014-04-11 20:27       ` Joel Brobecker
  2014-04-11 20:33         ` Keith Seitz
  0 siblings, 1 reply; 46+ messages in thread
From: Joel Brobecker @ 2014-04-11 20:27 UTC (permalink / raw)
  To: Keith Seitz; +Cc: Agovic, Sanimir, gdb-patches

> >Thank you Joel for helping me out through the patch series! I just
> >committed the patches including the final adjustments.
> 
> Unfortunatley, this patchset has regressed the following tests:

Argh! Sorry about that, and thanks for the heads up, Keith.

I'm doing a quick round of testing with what's left of my day today,
but we might have to revert the patch series to allow us more time
to investigate.

How come this didn't show up in Sanimir's testing?

> 
> > FAIL: gdb.base/pointers.exp: print array element w/ pointer arithmetic
> > FAIL: gdb.cp/koenig.exp: p foo(jca)
> > FAIL: gdb.mi/mi-read-memory.exp: 3x2, one byte offset by -6
> > FAIL: gdb.mi/mi-read-memory.exp: expression in quotes
> > FAIL: gdb.mi/mi-read-memory.exp: ascii and data
> > FAIL: gdb.mi/mi-read-memory.exp: decimal
> > FAIL: gdb.mi/mi-read-memory.exp: octal
> > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str2)
> > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str3)
> > FAIL: gdb.python/py-strfns.exp: p $_strlen (str1)
> > FAIL: gdb.python/py-strfns.exp: p $_strlen (buf1)
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Hello")
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Help")
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello")
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello.$")
> > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str2)
> > FAIL: gdb.python/py-strfns.exp: p $_streq (str1, str3)
> > FAIL: gdb.python/py-strfns.exp: p $_strlen (str1)
> > FAIL: gdb.python/py-strfns.exp: p $_strlen (buf1)
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Hello")
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "Help")
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello")
> > FAIL: gdb.python/py-strfns.exp: p $_regex (str1, "^Hello.$")
> 
> With --target_board=native-gdbsever, remote.exp has two additional
> failures. This is using x86_64 Fedora 20 (gcc Red Hat 4.8.2-7).
> 
> Keith

-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-11 20:27       ` Joel Brobecker
@ 2014-04-11 20:33         ` Keith Seitz
  2014-04-11 21:13           ` Joel Brobecker
  0 siblings, 1 reply; 46+ messages in thread
From: Keith Seitz @ 2014-04-11 20:33 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Agovic, Sanimir, gdb-patches

On 04/11/2014 01:27 PM, Joel Brobecker wrote:
>>> Thank you Joel for helping me out through the patch series! I just
>>> committed the patches including the final adjustments.
>>
>> Unfortunatley, this patchset has regressed the following tests:
>
> Argh! Sorry about that, and thanks for the heads up, Keith.
>

Not a problem -- I was just about to commit some patches -- one of which 
touches some bits of this patch set and noticed that a clean update/test 
had a few more FAILs than I expected. [We all keep a mental count of the 
"normal" number of FAILs on our systems, right? ;-)]

> I'm doing a quick round of testing with what's left of my day today,
> but we might have to revert the patch series to allow us more time
> to investigate.

Would you like me to hold off on committing my c++/16675 patchset? That 
touches eval.c:evaluate_subexp_for_sizeof. It's not a huge deal IMO. A 
Most of the "conflict" is simply that I chose to refactor this function 
a little. [i.e., remove all the "return value_from_longest" and collect 
them at the end of the function]

> How come this didn't show up in Sanimir's testing?

I don't know. Maybe my sandbox is messed up? It *is* Friday afterall! :-)

Keith

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-11 20:33         ` Keith Seitz
@ 2014-04-11 21:13           ` Joel Brobecker
  2014-04-11 21:19             ` Keith Seitz
  2014-04-11 22:33             ` Joel Brobecker
  0 siblings, 2 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-11 21:13 UTC (permalink / raw)
  To: Keith Seitz; +Cc: Agovic, Sanimir, gdb-patches

> >How come this didn't show up in Sanimir's testing?
> 
> I don't know. Maybe my sandbox is messed up? It *is* Friday afterall! :-)

It must be Friday for both of us, then - as I was able to reproduce
at least some of the failures. I am testing each patch in sequence
and so far, two of them cause additional failures:

commit 37c1ab67a35025d37d42c449deab5f254f9f59da
Subject: type: add c99 variable length array support

  This one only causes new failire in gdb.ada

commit bcd629a44fff61527430f353cf77e20fe3afc395
Subject: vla: update type from newly created value

  This one causes new failures in gdb.base, gdb.cp, etc.

> >I'm doing a quick round of testing with what's left of my day today,
> >but we might have to revert the patch series to allow us more time
> >to investigate.
> 
> Would you like me to hold off on committing my c++/16675 patchset?
> That touches eval.c:evaluate_subexp_for_sizeof. It's not a huge deal
> IMO. A Most of the "conflict" is simply that I chose to refactor
> this function a little. [i.e., remove all the "return
> value_from_longest" and collect them at the end of the function]

You should do whatever is convenient for you, and I will work around it.
No reason to inconvenience you further! So, if you are ready, just
go ahead and push. I will review the errors and decide from there
whether we can wait until early next week to fix them or else if
we should revert now.

Thanks!
-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-11 21:13           ` Joel Brobecker
@ 2014-04-11 21:19             ` Keith Seitz
  2014-04-11 22:33             ` Joel Brobecker
  1 sibling, 0 replies; 46+ messages in thread
From: Keith Seitz @ 2014-04-11 21:19 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches

On 04/11/2014 02:13 PM, Joel Brobecker wrote:
> It must be Friday for both of us, then - as I was able to reproduce
> at least some of the failures. I am testing each patch in sequence
> and so far, two of them cause additional failures:
>
> commit 37c1ab67a35025d37d42c449deab5f254f9f59da
> Subject: type: add c99 variable length array support
>
>    This one only causes new failire in gdb.ada
>
> commit bcd629a44fff61527430f353cf77e20fe3afc395
> Subject: vla: update type from newly created value
>
>    This one causes new failures in gdb.base, gdb.cp, etc.
>

Thanks for telling me -- I was beginning to worry that my build 
environment was really messed up!

> You should do whatever is convenient for you, and I will work around it.
> No reason to inconvenience you further! So, if you are ready, just
> go ahead and push. I will review the errors and decide from there
> whether we can wait until early next week to fix them or else if
> we should revert now.

Since it is such a minor conflict & very easily resolved, I've pushed 
the patchset.

Thanks!

Keith

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-11 21:13           ` Joel Brobecker
  2014-04-11 21:19             ` Keith Seitz
@ 2014-04-11 22:33             ` Joel Brobecker
  2014-04-14  8:34               ` Agovic, Sanimir
  1 sibling, 1 reply; 46+ messages in thread
From: Joel Brobecker @ 2014-04-11 22:33 UTC (permalink / raw)
  To: Keith Seitz; +Cc: Agovic, Sanimir, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 5553 bytes --]

> You should do whatever is convenient for you, and I will work around it.
> No reason to inconvenience you further! So, if you are ready, just
> go ahead and push. I will review the errors and decide from there
> whether we can wait until early next week to fix them or else if
> we should revert now.

It's not extremely bad in the sense that perhaps it's a question
of check_typedefs, but it triggers some assertions in gdb.ada,
and some really strange behavior in the other testsuite sections.

I've now reverted most of the series. Attached is the patch.
The commit subject says "Revert the entire VLA series", but
in fact, it's not accurate. I just realized that I didn't need
to revert the first couple of patches which are preparation work,
and could stay. I fixed that, but forgot to change the subject
of the commit :-( - just trying to run and I'm already an hour late.

I will get back to this on Monday.

----

This reverts the following patch series, as they cause some regresssions.

commit 37c1ab67a35025d37d42c449deab5f254f9f59da
type: add c99 variable length array support

	gdb/
	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
	(dwarf2_evaluate_property): New function.
	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
	* dwarf2read.c (attr_to_dynamic_prop): New function.
	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
	attribute.
	* gdbtypes.c: Include dwarf2loc.h.
	(is_dynamic_type): New function.
	(resolve_dynamic_type): New function.
	(resolve_dynamic_bounds): New function.
	(get_type_length): New function.
	(check_typedef): Use get_type_length to compute type length.
	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
	(TYPE_LOW_BOUND_KIND): New macro.
	(is_dynamic_type): New function prototype.
	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
	to resolve dynamic properties of the type. Update comment.
	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.

commit 26cb189f8b46dbe7b2d485525329a8919005ca8a
vla: enable sizeof operator to work with variable length arrays

	gdb/
	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
	passed to sizeof is dynamic evaluate the argument to compute the length.

commit 04b19544ef6a97b62b2cc4a3170b900e046ab185
vla: enable sizeof operator for indirection

	gdb/
	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
	value and retrieve the dynamic type size.

commit bcd629a44fff61527430f353cf77e20fe3afc395
vla: update type from newly created value

	gdb/
	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value.
	(ada_template_to_fixed_record_type_1): Likewise.
	(ada_to_fixed_type_1): Likewise.
	* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
	(cp_print_value): Likewise.
	* d-valprint.c (dynamic_array_type): Likewise.
	* eval.c (evaluate_subexp_with_coercion): Likewise.
	* findvar.c (address_of_variable): Likewise.
	* jv-valprint.c (java_value_print): Likewise.
	* valops.c (value_ind): Likewise.
	* value.c (coerce_ref): Likewise.

commit b86138fb0484f42db6cb83abed1e3d0ad2ec4eac
vla: print "variable length" for unresolved dynamic bounds

	gdb/
	* c-typeprint.c (c_type_print_varspec_suffix): Added
	check for not yet resolved high bound. If unresolved, print
	"variable length" string to the console instead of random
	length.

commit e1969afbd454c09c3aad1990305715f70bc47c3c
vla: support for DW_AT_count

	gdb/
	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
	property and store it as the high bound and flag the range accordingly.
	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
	RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
	* gdbtypes.h (enum range_flags): New enum.
	(struct range_bounds): Add flags member.

commit 92b09522dc5a93ba4bda3c1c0b3c58264e357c8a
vla: resolve dynamic bounds if value contents is a constant byte-sequence

	gdb/
	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
	points to a constant blob.

commit 3bce82377f683870cc89925ff43aefb7dcce4a77
vla: evaluate operand of sizeof if its type is a vla

	gdb/
	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
	(evaluate_subexp_standard): Pass noside argument.
	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
	if noside equals EVAL_NORMAL. If the subscript yields a vla type
	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.

	gdb/testsuite

	* gdb.base/vla-sideeffect.c: New file.
	* gdb.base/vla-sideeffect.exp: New file.

commit 504f34326e5ae7c78ebfcdd6ed03c7403b42048b
test: cover subranges with present DW_AT_count attribute

	gdb/testsuite/
	* gdb.dwarf2/count.exp: New file.

commit 1a237e0ee53bbdee97d72d794b5b42e774cc81c0
test: multi-dimensional c99 vla.

	gdb/testsuite/
	* gdb.base/vla-multi.c: New file.
	* gdb.base/vla-multi.exp: New file.

commit 024e13b46f9c33d151ae82fd9d64c53092fd9313
test: evaluate pointers to C99 vla correctly.

	gdb/testsuite/
	* gdb.base/vla-ptr.c: New file.
	* gdb.base/vla-ptr.exp: New file.

commit c8655f75e2f0fada311be193e3090087a77ec802
test: basic c99 vla tests for C primitives

	gdb/testsuite/
	* gdb.base/vla-datatypes.c: New file.
	* gdb.base/vla-datatypes.exp: New file.

commit 58a84dcf29b735ee776536b4c51ba90b51612b71
test: add mi vla test

	gdb/testsuite/
	* gdb.mi/mi-vla-c99.exp: New file.
	* gdb.mi/vla.c: New file.

-- 
Joel

[-- Attachment #2: 0001-Revert-the-entire-VLA-series.patch --]
[-- Type: text/x-diff, Size: 73749 bytes --]

From 6b662e19e420d2ef28f14b985390977080bcd341 Mon Sep 17 00:00:00 2001
From: Joel Brobecker <brobecker@adacore.com>
Date: Fri, 11 Apr 2014 14:47:15 -0700
Subject: [PATCH] Revert the entire VLA series.

This reverts the following patch series, as they cause some regresssions.

commit 37c1ab67a35025d37d42c449deab5f254f9f59da
type: add c99 variable length array support

	gdb/
	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
	(dwarf2_evaluate_property): New function.
	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
	* dwarf2read.c (attr_to_dynamic_prop): New function.
	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
	attribute.
	* gdbtypes.c: Include dwarf2loc.h.
	(is_dynamic_type): New function.
	(resolve_dynamic_type): New function.
	(resolve_dynamic_bounds): New function.
	(get_type_length): New function.
	(check_typedef): Use get_type_length to compute type length.
	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
	(TYPE_LOW_BOUND_KIND): New macro.
	(is_dynamic_type): New function prototype.
	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
	to resolve dynamic properties of the type. Update comment.
	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.

commit 26cb189f8b46dbe7b2d485525329a8919005ca8a
vla: enable sizeof operator to work with variable length arrays

	gdb/
	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
	passed to sizeof is dynamic evaluate the argument to compute the length.

commit 04b19544ef6a97b62b2cc4a3170b900e046ab185
vla: enable sizeof operator for indirection

	gdb/
	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
	value and retrieve the dynamic type size.

commit bcd629a44fff61527430f353cf77e20fe3afc395
vla: update type from newly created value

	gdb/
	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value.
	(ada_template_to_fixed_record_type_1): Likewise.
	(ada_to_fixed_type_1): Likewise.
	* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
	(cp_print_value): Likewise.
	* d-valprint.c (dynamic_array_type): Likewise.
	* eval.c (evaluate_subexp_with_coercion): Likewise.
	* findvar.c (address_of_variable): Likewise.
	* jv-valprint.c (java_value_print): Likewise.
	* valops.c (value_ind): Likewise.
	* value.c (coerce_ref): Likewise.

commit b86138fb0484f42db6cb83abed1e3d0ad2ec4eac
vla: print "variable length" for unresolved dynamic bounds

	gdb/
	* c-typeprint.c (c_type_print_varspec_suffix): Added
	check for not yet resolved high bound. If unresolved, print
	"variable length" string to the console instead of random
	length.

commit e1969afbd454c09c3aad1990305715f70bc47c3c
vla: support for DW_AT_count

	gdb/
	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
	property and store it as the high bound and flag the range accordingly.
	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
	RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
	* gdbtypes.h (enum range_flags): New enum.
	(struct range_bounds): Add flags member.

commit 92b09522dc5a93ba4bda3c1c0b3c58264e357c8a
vla: resolve dynamic bounds if value contents is a constant byte-sequence

	gdb/
	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
	points to a constant blob.

commit 3bce82377f683870cc89925ff43aefb7dcce4a77
vla: evaluate operand of sizeof if its type is a vla

	gdb/
	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
	(evaluate_subexp_standard): Pass noside argument.
	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
	if noside equals EVAL_NORMAL. If the subscript yields a vla type
	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.

	gdb/testsuite

	* gdb.base/vla-sideeffect.c: New file.
	* gdb.base/vla-sideeffect.exp: New file.

commit 504f34326e5ae7c78ebfcdd6ed03c7403b42048b
test: cover subranges with present DW_AT_count attribute

	gdb/testsuite/
	* gdb.dwarf2/count.exp: New file.

commit 1a237e0ee53bbdee97d72d794b5b42e774cc81c0
test: multi-dimensional c99 vla.

	gdb/testsuite/
	* gdb.base/vla-multi.c: New file.
	* gdb.base/vla-multi.exp: New file.

commit 024e13b46f9c33d151ae82fd9d64c53092fd9313
test: evaluate pointers to C99 vla correctly.

	gdb/testsuite/
	* gdb.base/vla-ptr.c: New file.
	* gdb.base/vla-ptr.exp: New file.

commit c8655f75e2f0fada311be193e3090087a77ec802
test: basic c99 vla tests for C primitives

	gdb/testsuite/
	* gdb.base/vla-datatypes.c: New file.
	* gdb.base/vla-datatypes.exp: New file.

commit 58a84dcf29b735ee776536b4c51ba90b51612b71
test: add mi vla test

	gdb/testsuite/
	* gdb.mi/mi-vla-c99.exp: New file.
	* gdb.mi/vla.c: New file.
---
 gdb/ChangeLog                             |  64 +++++++++
 gdb/ada-lang.c                            |  13 +-
 gdb/c-typeprint.c                         |   6 +-
 gdb/cp-valprint.c                         |   2 -
 gdb/d-valprint.c                          |   1 -
 gdb/dwarf2loc.c                           | 119 -----------------
 gdb/dwarf2loc.h                           |  28 ----
 gdb/dwarf2read.c                          | 122 +++++------------
 gdb/eval.c                                |  59 +-------
 gdb/findvar.c                             |  12 +-
 gdb/gdbtypes.c                            | 214 ++++++++----------------------
 gdb/gdbtypes.h                            |  20 ---
 gdb/jv-valprint.c                         |   1 -
 gdb/testsuite/ChangeLog                   |  21 +++
 gdb/testsuite/gdb.base/vla-datatypes.c    |  86 ------------
 gdb/testsuite/gdb.base/vla-datatypes.exp  | 139 -------------------
 gdb/testsuite/gdb.base/vla-multi.c        |  48 -------
 gdb/testsuite/gdb.base/vla-multi.exp      |  41 ------
 gdb/testsuite/gdb.base/vla-ptr.c          |  58 --------
 gdb/testsuite/gdb.base/vla-ptr.exp        |  41 ------
 gdb/testsuite/gdb.base/vla-sideeffect.c   |  42 ------
 gdb/testsuite/gdb.base/vla-sideeffect.exp |  89 -------------
 gdb/testsuite/gdb.dwarf2/count.exp        | 125 -----------------
 gdb/testsuite/gdb.mi/mi-vla-c99.exp       |  82 ------------
 gdb/testsuite/gdb.mi/vla.c                |  37 ------
 gdb/valops.c                              |  19 +--
 gdb/value.c                               |  20 +--
 27 files changed, 193 insertions(+), 1316 deletions(-)
 delete mode 100644 gdb/testsuite/gdb.base/vla-datatypes.c
 delete mode 100644 gdb/testsuite/gdb.base/vla-datatypes.exp
 delete mode 100644 gdb/testsuite/gdb.base/vla-multi.c
 delete mode 100644 gdb/testsuite/gdb.base/vla-multi.exp
 delete mode 100644 gdb/testsuite/gdb.base/vla-ptr.c
 delete mode 100644 gdb/testsuite/gdb.base/vla-ptr.exp
 delete mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.c
 delete mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.exp
 delete mode 100644 gdb/testsuite/gdb.dwarf2/count.exp
 delete mode 100644 gdb/testsuite/gdb.mi/mi-vla-c99.exp
 delete mode 100644 gdb/testsuite/gdb.mi/vla.c

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 26bd07b..2184479 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,67 @@
+2014-04-11  Joel Brobecker  <brobecker@adacore.com>
+
+	Revert the following changes due to regressions:
+
+	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
+	(dwarf2_evaluate_property): New function.
+	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
+	* dwarf2read.c (attr_to_dynamic_prop): New function.
+	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
+	attribute.
+	* gdbtypes.c: Include dwarf2loc.h.
+	(is_dynamic_type): New function.
+	(resolve_dynamic_type): New function.
+	(resolve_dynamic_bounds): New function.
+	(get_type_length): New function.
+	(check_typedef): Use get_type_length to compute type length.
+	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
+	(TYPE_LOW_BOUND_KIND): New macro.
+	(is_dynamic_type): New function prototype.
+	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
+	to resolve dynamic properties of the type. Update comment.
+	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.
+
+	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
+	passed to sizeof is dynamic evaluate the argument to compute the length.
+
+	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
+	value and retrieve the dynamic type size.
+
+	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value.
+	(ada_template_to_fixed_record_type_1): Likewise.
+	(ada_to_fixed_type_1): Likewise.
+	* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
+	(cp_print_value): Likewise.
+	* d-valprint.c (dynamic_array_type): Likewise.
+	* eval.c (evaluate_subexp_with_coercion): Likewise.
+	* findvar.c (address_of_variable): Likewise.
+	* jv-valprint.c (java_value_print): Likewise.
+	* valops.c (value_ind): Likewise.
+	* value.c (coerce_ref): Likewise.
+
+	* c-typeprint.c (c_type_print_varspec_suffix): Added
+	check for not yet resolved high bound. If unresolved, print
+	"variable length" string to the console instead of random
+	length.
+
+	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
+	property and store it as the high bound and flag the range accordingly.
+	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
+	RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
+	* gdbtypes.h (enum range_flags): New enum.
+	(struct range_bounds): Add flags member.
+
+	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
+	points to a constant blob.
+
+	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
+	(evaluate_subexp_standard): Pass noside argument.
+	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
+	if noside equals EVAL_NORMAL. If the subscript yields a vla type
+	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
+	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
+	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.
+
 2014-04-11  Keith Seitz  <keiths@redhat.com>
 
 	PR c++/16675
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index e268eba..9544758 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2406,7 +2406,6 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
   else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
     {
       v = value_at (type, value_address (obj));
-      type = value_type (v);
       bytes = (unsigned char *) alloca (len);
       read_memory (value_address (v) + offset, bytes, len);
     }
@@ -7889,7 +7888,6 @@ ada_template_to_fixed_record_type_1 (struct type *type,
 		 size first before creating the value.  */
 	      check_size (rtype);
 	      dval = value_from_contents_and_address (rtype, valaddr, address);
-	      rtype = value_type (dval);
 	    }
           else
             dval = dval0;
@@ -7992,10 +7990,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
       off = TYPE_FIELD_BITPOS (rtype, variant_field);
 
       if (dval0 == NULL)
-	{
-	  dval = value_from_contents_and_address (rtype, valaddr, address);
-	  rtype = value_type (dval);
-	}
+        dval = value_from_contents_and_address (rtype, valaddr, address);
       else
         dval = dval0;
 
@@ -8136,10 +8131,7 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
     return type;
 
   if (dval0 == NULL)
-    {
-      dval = value_from_contents_and_address (type, valaddr, address);
-      type = value_type (dval);
-    }
+    dval = value_from_contents_and_address (type, valaddr, address);
   else
     dval = dval0;
 
@@ -8437,7 +8429,6 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
 	      value_from_contents_and_address (fixed_record_type,
 					       valaddr,
 					       address);
-            fixed_record_type = value_type (obj);
             if (real_type != NULL)
               return to_fixed_record_type
 		(real_type, NULL,
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index d910058..4edc9ec 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -689,11 +689,7 @@ c_type_print_varspec_suffix (struct type *type,
 
 	fprintf_filtered (stream, (is_vector ?
 				   " __attribute__ ((vector_size(" : "["));
-	/* Bounds are not yet resolved, print a bounds placeholder instead.  */
-	if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
-	    || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
-	  fprintf_filtered (stream, "variable length");
-	else if (get_array_bounds (type, &low_bound, &high_bound))
+	if (get_array_bounds (type, &low_bound, &high_bound))
 	  fprintf_filtered (stream, "%s", 
 			    plongest (high_bound - low_bound + 1));
 	fprintf_filtered (stream, (is_vector ? ")))" : "]"));
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 3e1d6ed..2d366b9 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -443,7 +443,6 @@ cp_print_value_fields_rtti (struct type *type,
       /* Ugh, we have to convert back to a value here.  */
       value = value_from_contents_and_address (type, valaddr + offset,
 					       address + offset);
-      type = value_type (value);
       /* We don't actually care about most of the result here -- just
 	 the type.  We already have the correct offset, due to how
 	 val_print was initially called.  */
@@ -546,7 +545,6 @@ cp_print_value (struct type *type, struct type *real_type,
 		  base_val = value_from_contents_and_address (baseclass,
 							      buf,
 							      address + boffset);
-		  baseclass = value_type (base_val);
 		  thisoffset = 0;
 		  boffset = 0;
 		  thistype = baseclass;
diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c
index 755f180..90095cd 100644
--- a/gdb/d-valprint.c
+++ b/gdb/d-valprint.c
@@ -59,7 +59,6 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr,
 
       true_type = lookup_array_range_type (true_type, 0, length - 1);
       ival = value_at (true_type, addr);
-      true_type = value_type (ival);
 
       d_val_print (true_type,
 		   value_contents_for_printing (ival),
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index addae13..e91b764 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2432,125 +2432,6 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
   return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
 }
 
-/* Evaluates a dwarf expression and stores the result in VAL, expecting
-   that the dwarf expression only produces a single CORE_ADDR.  ADDR is a
-   context (location of a variable) and might be needed to evaluate the
-   location expression.
-   Returns 1 on success, 0 otherwise.   */
-
-static int
-dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
-			   CORE_ADDR addr, CORE_ADDR *valp)
-{
-  struct dwarf_expr_context *ctx;
-  struct dwarf_expr_baton baton;
-  struct objfile *objfile;
-  struct cleanup *cleanup;
-
-  if (dlbaton == NULL || dlbaton->size == 0)
-    return 0;
-
-  ctx = new_dwarf_expr_context ();
-  cleanup = make_cleanup_free_dwarf_expr_context (ctx);
-
-  baton.frame = get_selected_frame (NULL);
-  baton.per_cu = dlbaton->per_cu;
-
-  objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
-
-  ctx->gdbarch = get_objfile_arch (objfile);
-  ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
-  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
-  ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
-  ctx->funcs = &dwarf_expr_ctx_funcs;
-  ctx->baton = &baton;
-
-  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
-
-  switch (ctx->location)
-    {
-    case DWARF_VALUE_REGISTER:
-    case DWARF_VALUE_MEMORY:
-    case DWARF_VALUE_STACK:
-      *valp = dwarf_expr_fetch_address (ctx, 0);
-      if (ctx->location == DWARF_VALUE_REGISTER)
-	*valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
-      do_cleanups (cleanup);
-      return 1;
-    case DWARF_VALUE_LITERAL:
-      *valp = extract_signed_integer (ctx->data, ctx->len,
-				      gdbarch_byte_order (ctx->gdbarch));
-      do_cleanups (cleanup);
-      return 1;
-      /* Unsupported dwarf values.  */
-    case DWARF_VALUE_OPTIMIZED_OUT:
-    case DWARF_VALUE_IMPLICIT_POINTER:
-      break;
-    }
-
-  do_cleanups (cleanup);
-  return 0;
-}
-
-/* See dwarf2loc.h.  */
-
-int
-dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address,
-			  CORE_ADDR *value)
-{
-  if (prop == NULL)
-    return 0;
-
-  switch (prop->kind)
-    {
-    case PROP_LOCEXPR:
-      {
-	const struct dwarf2_property_baton *baton = prop->data.baton;
-
-	if (dwarf2_locexpr_baton_eval (&baton->locexpr, address, value))
-	  {
-	    if (baton->referenced_type)
-	      {
-		struct value *val = value_at (baton->referenced_type, *value);
-
-		*value = value_as_address (val);
-	      }
-	    return 1;
-	  }
-      }
-      break;
-
-    case PROP_LOCLIST:
-      {
-	struct dwarf2_property_baton *baton = prop->data.baton;
-	struct frame_info *frame = get_selected_frame (NULL);
-	CORE_ADDR pc = get_frame_address_in_block (frame);
-	const gdb_byte *data;
-	struct value *val;
-	size_t size;
-
-	data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
-	if (data != NULL)
-	  {
-	    val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data,
-					    size, baton->loclist.per_cu);
-	    if (!value_optimized_out (val))
-	      {
-		*value = value_as_address (val);
-		return 1;
-	      }
-	  }
-      }
-      break;
-
-    case PROP_CONST:
-      *value = prop->data.const_val;
-      return 1;
-    }
-
-  return 0;
-}
-
 \f
 /* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 36173c5..786e77c 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -90,14 +90,6 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
 					size_t size,
 					struct dwarf2_per_cu_data *per_cu);
 
-/* Converts a dynamic property into a static one.  ADDR is the address of
-   the object currently being evaluated and might be nedded.
-   Returns 1 if PROP could be converted and the static value is passed back
-   into VALUE, otherwise returns 0.  */
-
-int dwarf2_evaluate_property (const struct dynamic_prop *prop,
-			      CORE_ADDR addr, CORE_ADDR *value);
-
 CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
 				  unsigned int addr_index);
 
@@ -143,26 +135,6 @@ struct dwarf2_loclist_baton
   unsigned char from_dwo;
 };
 
-/* A dynamic property is either expressed as a single location expression
-   or a location list.  If the property is an indirection, pointing to
-   another die, keep track of the targeted type in REFERENCED_TYPE.  */
-
-struct dwarf2_property_baton
-{
-  /* If the property is an indirection, we need to evaluate the location
-     LOCEXPR or LOCLIST in the context of the type REFERENCED_TYPE.
-     If NULL, the location is the actual value of the property.  */
-  struct type *referenced_type;
-  union
-  {
-    /* Location expression.  */
-    struct dwarf2_locexpr_baton locexpr;
-
-    /* Location list to be evaluated in the context of REFERENCED_TYPE.  */
-    struct dwarf2_loclist_baton loclist;
-  };
-};
-
 extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
 extern const struct symbol_computed_ops dwarf2_loclist_funcs;
 
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 7c64491..152c8d2 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14405,84 +14405,6 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
-/* Parse dwarf attribute if it's a block, reference or constant and put the
-   resulting value of the attribute into struct bound_prop.
-   Returns 1 if ATTR could be resolved into PROP, 0 otherwise.  */
-
-static int
-attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
-		      struct dwarf2_cu *cu, struct dynamic_prop *prop)
-{
-  struct dwarf2_property_baton *baton;
-  struct obstack *obstack = &cu->objfile->objfile_obstack;
-
-  if (attr == NULL || prop == NULL)
-    return 0;
-
-  if (attr_form_is_block (attr))
-    {
-      baton = obstack_alloc (obstack, sizeof (*baton));
-      baton->referenced_type = NULL;
-      baton->locexpr.per_cu = cu->per_cu;
-      baton->locexpr.size = DW_BLOCK (attr)->size;
-      baton->locexpr.data = DW_BLOCK (attr)->data;
-      prop->data.baton = baton;
-      prop->kind = PROP_LOCEXPR;
-      gdb_assert (prop->data.baton != NULL);
-    }
-  else if (attr_form_is_ref (attr))
-    {
-      struct dwarf2_cu *target_cu = cu;
-      struct die_info *target_die;
-      struct attribute *target_attr;
-
-      target_die = follow_die_ref (die, attr, &target_cu);
-      target_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
-      if (target_attr == NULL)
-	return 0;
-
-      if (attr_form_is_section_offset (target_attr))
-	{
-	  baton = obstack_alloc (obstack, sizeof (*baton));
-	  baton->referenced_type = die_type (target_die, target_cu);
-	  fill_in_loclist_baton (cu, &baton->loclist, target_attr);
-	  prop->data.baton = baton;
-	  prop->kind = PROP_LOCLIST;
-	  gdb_assert (prop->data.baton != NULL);
-	}
-      else if (attr_form_is_block (target_attr))
-	{
-	  baton = obstack_alloc (obstack, sizeof (*baton));
-	  baton->referenced_type = die_type (target_die, target_cu);
-	  baton->locexpr.per_cu = cu->per_cu;
-	  baton->locexpr.size = DW_BLOCK (target_attr)->size;
-	  baton->locexpr.data = DW_BLOCK (target_attr)->data;
-	  prop->data.baton = baton;
-	  prop->kind = PROP_LOCEXPR;
-	  gdb_assert (prop->data.baton != NULL);
-	}
-      else
-	{
-	  dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
-						 "dynamic property");
-	  return 0;
-	}
-    }
-  else if (attr_form_is_constant (attr))
-    {
-      prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
-      prop->kind = PROP_CONST;
-    }
-  else
-    {
-      dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
-					     dwarf2_name (die, cu));
-      return 0;
-    }
-
-  return 1;
-}
-
 /* Read the given DW_AT_subrange DIE.  */
 
 static struct type *
@@ -14493,7 +14415,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   struct attribute *attr;
   struct dynamic_prop low, high;
   int low_default_is_valid;
-  int high_bound_is_count = 0;
   const char *name;
   LONGEST negative_mask;
 
@@ -14557,16 +14478,38 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 	       die->offset.sect_off, objfile_name (cu->objfile));
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
-  if (!attr_to_dynamic_prop (attr, die, cu, &high))
+  if (attr)
+    {
+      if (attr_form_is_block (attr) || attr_form_is_ref (attr))
+        {
+          /* GCC encodes arrays with unspecified or dynamic length
+             with a DW_FORM_block1 attribute or a reference attribute.
+             FIXME: GDB does not yet know how to handle dynamic
+             arrays properly, treat them as arrays with unspecified
+             length for now.
+
+             FIXME: jimb/2003-09-22: GDB does not really know
+             how to handle arrays of unspecified length
+             either; we just represent them as zero-length
+             arrays.  Choose an appropriate upper bound given
+             the lower bound we've computed above.  */
+          high.data.const_val = low.data.const_val - 1;
+        }
+      else
+        high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
+    }
+  else
     {
       attr = dwarf2_attr (die, DW_AT_count, cu);
-      if (attr_to_dynamic_prop (attr, die, cu, &high))
+      if (attr)
 	{
-	  /* If bounds are constant do the final calculation here.  */
-	  if (low.kind == PROP_CONST && high.kind == PROP_CONST)
-	    high.data.const_val = low.data.const_val + high.data.const_val - 1;
-	  else
-	    high_bound_is_count = 1;
+	  int count = dwarf2_get_attr_constant_value (attr, 1);
+	  high.data.const_val = low.data.const_val + count - 1;
+	}
+      else
+	{
+	  /* Unspecified array length.  */
+	  high.data.const_val = low.data.const_val - 1;
 	}
     }
 
@@ -14626,8 +14569,11 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   range_type = create_range_type (NULL, orig_base_type, &low, &high);
 
-  if (high_bound_is_count)
-    TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1;
+  /* Mark arrays with dynamic length at least as an array of unspecified
+     length.  GDB could check the boundary but before it gets implemented at
+     least allow accessing the array elements.  */
+  if (attr && attr_form_is_block (attr))
+    TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
 
   /* Ada expects an empty array on no boundary attributes.  */
   if (attr == NULL && cu->language != language_ada)
diff --git a/gdb/eval.c b/gdb/eval.c
index 2a1c662..c1e47e0 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -50,8 +50,7 @@ extern int overload_resolution;
 
 /* Prototypes for local functions.  */
 
-static struct value *evaluate_subexp_for_sizeof (struct expression *, int *,
-						 enum noside);
+static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
 
 static struct value *evaluate_subexp_for_address (struct expression *,
 						  int *, enum noside);
@@ -2563,7 +2562,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	  evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
 	  goto nosideret;
 	}
-      return evaluate_subexp_for_sizeof (exp, pos, noside);
+      return evaluate_subexp_for_sizeof (exp, pos);
 
     case UNOP_CAST:
       (*pos) += 2;
@@ -2985,7 +2984,6 @@ evaluate_subexp_with_coercion (struct expression *exp,
 	{
 	  (*pos) += 4;
 	  val = address_of_variable (var, exp->elts[pc + 1].block);
-	  type = value_type (val);
 	  return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
 			     val);
 	}
@@ -2998,13 +2996,10 @@ evaluate_subexp_with_coercion (struct expression *exp,
 
 /* Evaluate a subexpression of EXP, at index *POS,
    and return a value for the size of that subexpression.
-   Advance *POS over the subexpression.  If NOSIDE is EVAL_NORMAL
-   we allow side-effects on the operand if its type is a variable
-   length array.   */
+   Advance *POS over the subexpression.  */
 
 static struct value *
-evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
-			    enum noside noside)
+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;
@@ -3030,10 +3025,7 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
 	  && TYPE_CODE (type) != TYPE_CODE_REF
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
-      if (is_dynamic_type (type))
-	type = value_type (value_ind (val));
-      else
-	type = TYPE_TARGET_TYPE (type);
+      type = TYPE_TARGET_TYPE (type);
       break;
 
     case UNOP_MEMVAL:
@@ -3048,47 +3040,10 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
       break;
 
     case OP_VAR_VALUE:
-      type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol));
-      if (is_dynamic_type (type))
-	{
-	  val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
-	  type = value_type (val);
-	}
-      else
-	(*pos) += 4;
+      (*pos) += 4;
+      type = SYMBOL_TYPE (exp->elts[pc + 2].symbol);
       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
-	 side-effects. */
-    case BINOP_SUBSCRIPT:
-      if (noside == EVAL_NORMAL)
-	{
-	  int pc = (*pos) + 1;
-
-	  val = evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
-	  type = check_typedef (value_type (val));
-	  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
-	    {
-	      type = check_typedef (TYPE_TARGET_TYPE (type));
-	      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
-		{
-		  type = TYPE_INDEX_TYPE (type);
-		  /* Only re-evaluate the right hand side if the resulting type
-		     is a variable length type.  */
-		  if (TYPE_RANGE_DATA (type)->flag_bound_evaluated)
-		    {
-		      val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
-		      type = value_type (val);
-		      break;
-		    }
-		}
-	    }
-	}
-
-      /* Fall through.  */
-
     default:
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = value_type (val);
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 998a799..a2a7bb7 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -437,12 +437,7 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
   switch (SYMBOL_CLASS (var))
     {
     case LOC_CONST:
-      if (is_dynamic_type (type))
-	{
-	  /* Value is a constant byte-sequence and needs no memory access.  */
-	  type = resolve_dynamic_type (type, /* Unused address.  */ 0);
-	}
-      /* Put the constant back in target format. */
+      /* Put the constant back in target format.  */
       v = allocate_value (type);
       store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
 			    gdbarch_byte_order (get_type_arch (type)),
@@ -469,11 +464,6 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
       return v;
 
     case LOC_CONST_BYTES:
-      if (is_dynamic_type (type))
-	{
-	  /* Value is a constant byte-sequence and needs no memory access.  */
-	  type = resolve_dynamic_type (type, /* Unused address.  */ 0);
-	}
       v = allocate_value (type);
       memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
 	      TYPE_LENGTH (type));
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 47b2120..231139b 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -853,17 +853,6 @@ create_static_range_type (struct type *result_type, struct type *index_type,
   return result_type;
 }
 
-/* Predicate tests whether BOUNDS are static.  Returns 1 if all bounds values
-   are static, otherwise returns 0.  */
-
-static int
-has_static_range (const struct range_bounds *bounds)
-{
-  return (bounds->low.kind == PROP_CONST
-	  && bounds->high.kind == PROP_CONST);
-}
-
-
 /* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
    TYPE.  Return 1 if type is a range type, 0 if it is discrete (and
    bounds will fit in LONGEST), or -1 otherwise.  */
@@ -997,41 +986,27 @@ create_array_type_with_stride (struct type *result_type,
 			       struct type *range_type,
 			       unsigned int bit_stride)
 {
+  LONGEST low_bound, high_bound;
+
   if (result_type == NULL)
     result_type = alloc_type_copy (range_type);
 
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
-  if (has_static_range (TYPE_RANGE_DATA (range_type)))
-    {
-      LONGEST low_bound, high_bound;
-
-      if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
-	low_bound = high_bound = 0;
-      CHECK_TYPEDEF (element_type);
-      /* Be careful when setting the array length.  Ada arrays can be
-	 empty arrays with the high_bound being smaller than the low_bound.
-	 In such cases, the array length should be zero.  */
-      if (high_bound < low_bound)
-	TYPE_LENGTH (result_type) = 0;
-      else if (bit_stride > 0)
-	TYPE_LENGTH (result_type) =
-	  (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
-      else
-	TYPE_LENGTH (result_type) =
-	  TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
-    }
+  if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+    low_bound = high_bound = 0;
+  CHECK_TYPEDEF (element_type);
+  /* Be careful when setting the array length.  Ada arrays can be
+     empty arrays with the high_bound being smaller than the low_bound.
+     In such cases, the array length should be zero.  */
+  if (high_bound < low_bound)
+    TYPE_LENGTH (result_type) = 0;
+  else if (bit_stride > 0)
+    TYPE_LENGTH (result_type) =
+      (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
   else
-    {
-      /* This type is dynamic and its length needs to be computed
-         on demand.  In the meantime, avoid leaving the TYPE_LENGTH
-         undefined by setting it to zero.  Although we are not expected
-         to trust TYPE_LENGTH in this case, setting the size to zero
-         allows us to avoid allocating objects of random sizes in case
-         we accidently do.  */
-      TYPE_LENGTH (result_type) = 0;
-    }
-
+    TYPE_LENGTH (result_type) =
+      TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
   TYPE_NFIELDS (result_type) = 1;
   TYPE_FIELDS (result_type) =
     (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
@@ -1610,126 +1585,6 @@ stub_noname_complaint (void)
   complaint (&symfile_complaints, _("stub type has NULL name"));
 }
 
-/* See gdbtypes.h.  */
-
-int
-is_dynamic_type (struct type *type)
-{
-  type = check_typedef (type);
-
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
-    type = check_typedef (TYPE_TARGET_TYPE (type));
-
-  switch (TYPE_CODE (type))
-    {
-    case TYPE_CODE_ARRAY:
-      {
-	const struct type *range_type;
-
-	gdb_assert (TYPE_NFIELDS (type) == 1);
-	range_type = TYPE_INDEX_TYPE (type);
-	if (!has_static_range (TYPE_RANGE_DATA (range_type)))
-	  return 1;
-	else
-	  return is_dynamic_type (TYPE_TARGET_TYPE (type));
-	break;
-      }
-    default:
-      return 0;
-      break;
-    }
-}
-
-/* Resolves dynamic bound values of an array type TYPE to static ones.
-   ADDRESS might be needed to resolve the subrange bounds, it is the location
-   of the associated array.  */
-
-static struct type *
-resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
-{
-  CORE_ADDR value;
-  struct type *elt_type;
-  struct type *range_type;
-  struct type *ary_dim;
-  const struct dynamic_prop *prop;
-  const struct dwarf2_locexpr_baton *baton;
-  struct dynamic_prop low_bound, high_bound;
-
-  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
-    {
-      struct type *copy = copy_type (type);
-
-      TYPE_TARGET_TYPE (copy)
-	= resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
-
-      return copy;
-    }
-
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
-
-  elt_type = type;
-  range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
-
-  prop = &TYPE_RANGE_DATA (range_type)->low;
-  if (dwarf2_evaluate_property (prop, addr, &value))
-    {
-      low_bound.kind = PROP_CONST;
-      low_bound.data.const_val = value;
-    }
-  else
-    {
-      low_bound.kind = PROP_UNDEFINED;
-      low_bound.data.const_val = 0;
-    }
-
-  prop = &TYPE_RANGE_DATA (range_type)->high;
-  if (dwarf2_evaluate_property (prop, addr, &value))
-    {
-      high_bound.kind = PROP_CONST;
-      high_bound.data.const_val = value;
-
-      if (TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count)
-	high_bound.data.const_val
-	  = low_bound.data.const_val + high_bound.data.const_val - 1;
-    }
-  else
-    {
-      high_bound.kind = PROP_UNDEFINED;
-      high_bound.data.const_val = 0;
-    }
-
-  ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
-
-  if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
-    elt_type = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
-  else
-    elt_type = TYPE_TARGET_TYPE (type);
-
-  range_type = create_range_type (NULL,
-				  TYPE_TARGET_TYPE (range_type),
-				  &low_bound, &high_bound);
-  TYPE_RANGE_DATA (range_type)->flag_bound_evaluated = 1;
-  return create_array_type (copy_type (type),
-			    elt_type,
-			    range_type);
-}
-
-/* See gdbtypes.h  */
-
-struct type *
-resolve_dynamic_type (struct type *type, CORE_ADDR addr)
-{
-  struct type *real_type = check_typedef (type);
-  struct type *resolved_type;
-
-  if (!is_dynamic_type (real_type))
-    return type;
-
-  resolved_type = resolve_dynamic_bounds (type, addr);
-
-  return resolved_type;
-}
-
 /* Find the real type of TYPE.  This function returns the real type,
    after removing all layers of typedefs, and completing opaque or stub
    types.  Completion changes the TYPE argument, but stripping of
@@ -1905,6 +1760,45 @@ check_typedef (struct type *type)
 	{
 	  /* Nothing we can do.  */
 	}
+      else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
+	       && TYPE_NFIELDS (type) == 1
+	       && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
+		   == TYPE_CODE_RANGE))
+	{
+	  /* Now recompute the length of the array type, based on its
+	     number of elements and the target type's length.
+	     Watch out for Ada null Ada arrays where the high bound
+	     is smaller than the low bound.  */
+	  const LONGEST low_bound = TYPE_LOW_BOUND (range_type);
+	  const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
+	  ULONGEST len;
+
+	  if (high_bound < low_bound)
+	    len = 0;
+	  else
+	    {
+	      /* For now, we conservatively take the array length to be 0
+		 if its length exceeds UINT_MAX.  The code below assumes
+		 that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
+		 which is technically not guaranteed by C, but is usually true
+		 (because it would be true if x were unsigned with its
+		 high-order bit on).  It uses the fact that
+		 high_bound-low_bound is always representable in
+		 ULONGEST and that if high_bound-low_bound+1 overflows,
+		 it overflows to 0.  We must change these tests if we 
+		 decide to increase the representation of TYPE_LENGTH
+		 from unsigned int to ULONGEST.  */
+	      ULONGEST ulow = low_bound, uhigh = high_bound;
+	      ULONGEST tlen = TYPE_LENGTH (target_type);
+
+	      len = tlen * (uhigh - ulow + 1);
+	      if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh 
+		  || len > UINT_MAX)
+		len = 0;
+	    }
+	  TYPE_LENGTH (type) = len;
+	  TYPE_TARGET_STUB (type) = 0;
+	}
       else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
 	{
 	  TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 4c9d7c2..e91ab97 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1,4 +1,3 @@
-
 /* Internal type definitions for GDB.
 
    Copyright (C) 1992-2014 Free Software Foundation, Inc.
@@ -663,16 +662,6 @@ struct main_type
       /* * High bound of range.  */
 
       struct dynamic_prop high;
-
-      /* True if HIGH range bound contains the number of elements in the
-	 subrange. This affects how the final hight bound is computed.  */
-
-      int flag_upper_bound_is_count : 1;
-
-      /* True if LOW or/and HIGH are resolved into a static bound from
-	 a dynamic one.  */
-
-      int flag_bound_evaluated : 1;
     } *bounds;
 
   } flds_bnds;
@@ -1693,15 +1682,6 @@ extern void get_unsigned_type_max (struct type *, ULONGEST *);
 
 extern void get_signed_type_minmax (struct type *, LONGEST *, LONGEST *);
 
-/* * Resolve all dynamic values of a type e.g. array bounds to static values.
-   ADDR specifies the location of the variable the type is bound to.
-   If TYPE has no dynamic properties return TYPE; otherwise a new type with
-   static properties is returned.  */
-extern struct type *resolve_dynamic_type (struct type *type, CORE_ADDR addr);
-
-/* * Predicate if the type has dynamic values, which are not resolved yet.  */
-extern int is_dynamic_type (struct type *type);
-
 extern struct type *check_typedef (struct type *);
 
 #define CHECK_TYPEDEF(TYPE)			\
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
index a7bb494..82bdd9b 100644
--- a/gdb/jv-valprint.c
+++ b/gdb/jv-valprint.c
@@ -65,7 +65,6 @@ java_value_print (struct value *val, struct ui_file *stream,
 	  type = lookup_pointer_type (type);
 
 	  val = value_at (type, address);
-	  type = value_type (val);
 	}
     }
 
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 93f2185..87fd598 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,24 @@
+2014-04-11  Joel Brobecker  <brobecker@adacore.com>
+
+	Revert the following changes (regressions):
+
+	* gdb.base/vla-sideeffect.c: New file.
+	* gdb.base/vla-sideeffect.exp: New file.
+
+	* gdb.dwarf2/count.exp: New file.
+
+	* gdb.base/vla-multi.c: New file.
+	* gdb.base/vla-multi.exp: New file.
+
+	* gdb.base/vla-ptr.c: New file.
+	* gdb.base/vla-ptr.exp: New file.
+
+	* gdb.base/vla-datatypes.c: New file.
+	* gdb.base/vla-datatypes.exp: New file.
+
+	* gdb.mi/mi-vla-c99.exp: New file.
+	* gdb.mi/vla.c: New file.
+
 2014-04-11  Keith Seitz  <keiths@redhat.com>
 
 	PR c++/16675
diff --git a/gdb/testsuite/gdb.base/vla-datatypes.c b/gdb/testsuite/gdb.base/vla-datatypes.c
deleted file mode 100644
index 51e342e..0000000
--- a/gdb/testsuite/gdb.base/vla-datatypes.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2014 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include <stddef.h>
-#define SIZE 5
-
-struct foo
-{
-  int a;
-};
-
-typedef struct bar
-{
-  int x;
-  struct foo y;
-} BAR;
-
-void
-vla_factory (int n)
-{
-  int             int_vla[n];
-  unsigned int    unsigned_int_vla[n];
-  double          double_vla[n];
-  float           float_vla[n];
-  long            long_vla[n];
-  unsigned long   unsigned_long_vla[n];
-  char            char_vla[n];
-  short           short_vla[n];
-  unsigned short  unsigned_short_vla[n];
-  unsigned char   unsigned_char_vla[n];
-  struct foo      foo_vla[n];
-  BAR             bar_vla[n];
-  int i;
-
-  for (i = 0; i < n; i++)
-    {
-      int_vla[i] = i*2;
-      unsigned_int_vla[i] = i*2;
-      double_vla[i] = i/2.0;
-      float_vla[i] = i/2.0f;
-      long_vla[i] = i*2;
-      unsigned_long_vla[i] = i*2;
-      char_vla[i] = 'A';
-      short_vla[i] = i*2;
-      unsigned_short_vla[i] = i*2;
-      unsigned_char_vla[i] = 'A';
-      foo_vla[i].a = i*2;
-      bar_vla[i].x = i*2;
-      bar_vla[i].y.a = i*2;
-    }
-
-  size_t int_size        = sizeof(int_vla);     /* vlas_filled */
-  size_t uint_size       = sizeof(unsigned_int_vla);
-  size_t double_size     = sizeof(double_vla);
-  size_t float_size      = sizeof(float_vla);
-  size_t long_size       = sizeof(long_vla);
-  size_t char_size       = sizeof(char_vla);
-  size_t short_size      = sizeof(short_vla);
-  size_t ushort_size     = sizeof(unsigned_short_vla);
-  size_t uchar_size      = sizeof(unsigned_char_vla);
-  size_t foo_size        = sizeof(foo_vla);
-  size_t bar_size        = sizeof(bar_vla);
-
-  return;                                 /* break_end_of_vla_factory */
-}
-
-int
-main (void)
-{
-  vla_factory(SIZE);
-  return 0;
-}
diff --git a/gdb/testsuite/gdb.base/vla-datatypes.exp b/gdb/testsuite/gdb.base/vla-datatypes.exp
deleted file mode 100644
index 8247658..0000000
--- a/gdb/testsuite/gdb.base/vla-datatypes.exp
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright 2014 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-standard_testfile
-
-if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
-    return -1
-}
-
-if ![runto_main] {
-    return -1
-}
-
-gdb_breakpoint [gdb_get_line_number "vlas_filled"]
-gdb_continue_to_breakpoint "vlas_filled"
-
-# Check the values of VLA's.
-gdb_test "print int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
-         "print int_vla"
-gdb_test "print unsigned_int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
-         "print unsigned_int_vla"
-gdb_test "print double_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
-         "print double_vla"
-gdb_test "print float_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
-         "print float_vla"
-gdb_test "print long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
-         "print long_vla"
-gdb_test "print unsigned_long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
-         "print unsigned_long_vla"
-gdb_test "print char_vla" " = \"AAAAA\"" \
-         "print char_vla"
-gdb_test "print short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
-         "print short_vla"
-gdb_test "print unsigned_short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
-         "print unsigned_short_vla"
-gdb_test "print unsigned_char_vla" " = \"AAAAA\"" \
-         "print unsigned_char_vla"
-gdb_test "print foo_vla" \
-         "\\\{\\\{a = 0\\\}, \\\{a = 2\\\}, \\\{a = 4\\\}, \\\{a = 6\\\}, \\\{a = 8\\\}\\\}" \
-         "print foo_vla"
-gdb_test "print bar_vla" \
-         "\\\{\\\{x = 0, y = \\\{a = 0\\\}\\\}, \\\{x = 2, y = \\\{a = 2\\\}\\\}, \\\{x = 4, y = \\\{a = 4\\\}\\\}, \\\{x = 6, y = \\\{a = 6\\\}\\\}, \\\{x = 8, y = \\\{a = 8\\\}\\\}\\\}" \
-         "print bar_vla"
-
-# Check whatis of VLA's.
-gdb_test "whatis int_vla" "type = int \\\[5\\\]" "whatis int_vla"
-gdb_test "whatis unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
-         "whatis unsigned_int_vla"
-gdb_test "whatis double_vla" "type = double \\\[5\\\]" "whatis double_vla"
-gdb_test "whatis float_vla" "type = float \\\[5\\\]" "whatis float_vla"
-gdb_test "whatis long_vla" "type = long( int)? \\\[5\\\]" "whatis long_vla"
-gdb_test "whatis unsigned_long_vla" \
-         "type = (long unsigned int|unsigned long) \\\[5\\\]" \
-         "whatis unsigned_long_vla"
-gdb_test "whatis char_vla" "type = char \\\[5\\\]" "whatis char_vla"
-gdb_test "whatis short_vla" "type = short( int)? \\\[5\\\]" \
-         "whatis short_vla"
-gdb_test "whatis unsigned_short_vla" \
-         "type = (short unsigned int|unsigned short) \\\[5\\\]" \
-         "whatis unsigned_short_vla"
-gdb_test "whatis unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
-         "whatis unsigned_char_vla"
-gdb_test "whatis foo_vla" "type = struct foo \\\[5\\\]" "whatis foo_vla"
-gdb_test "whatis bar_vla" "type = BAR \\\[5\\\]" "whatis bar_vla"
-
-# Check ptype of VLA's.
-gdb_test "ptype int_vla" "type = int \\\[5\\\]" "ptype int_vla"
-gdb_test "ptype unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
-         "ptype unsigned_int_vla"
-gdb_test "ptype double_vla" "type = double \\\[5\\\]" "ptype double_vla"
-gdb_test "ptype float_vla" "type = float \\\[5\\\]" "ptype float_vla"
-gdb_test "ptype long_vla" "type = long( int)? \\\[5\\\]" "ptype long_vla"
-gdb_test "ptype unsigned_long_vla" "type = unsigned long \\\[5\\\]" \
-         "ptype unsigned_long_vla"
-gdb_test "ptype char_vla" "type = char \\\[5\\\]" "ptype char_vla"
-gdb_test "ptype short_vla" "type = short( int)? \\\[5\\\]" \
-         "ptype short_vla"
-gdb_test "ptype unsigned_short_vla" "type = unsigned short \\\[5\\\]" \
-         "ptype unsigned_short_vla"
-gdb_test "ptype unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
-         "ptype unsigned_char_vla"
-gdb_test "ptype foo_vla" "type = struct foo {\r\n\\s+int a;\r\n} \\\[5\\\]" \
-         "ptype foo_vla"
-gdb_test "ptype bar_vla" \
-         "type = struct bar {\r\n\\s+int x;\r\n\\s+struct foo y;\r\n} \\\[5\\\]" \
-         "ptype bar_vla"
-
-# Check the size of the VLA's.
-gdb_breakpoint [gdb_get_line_number "break_end_of_vla_factory"]
-gdb_continue_to_breakpoint "break_end_of_vla_factory"
-gdb_test "print int_size == sizeof(int_vla)" " = 1" "size of int_vla"
-gdb_test "print uint_size == sizeof(unsigned_int_vla)" " = 1" \
-         "size of unsigned_int_vla"
-gdb_test "print double_size == sizeof(double_vla)" " = 1" \
-         "size of double_vla"
-gdb_test "print float_size == sizeof(float_vla)" " = 1" \
-         "size of float_vla"
-gdb_test "print long_size == sizeof(long_vla)" " = 1" \
-         "size of long_vla"
-gdb_test "print char_size == sizeof(char_vla)" " = 1" \
-         "size of char_vla"
-gdb_test "print short_size == sizeof(short_vla)" " = 1" \
-         "size of short_vla"
-gdb_test "print ushort_size == sizeof(unsigned_short_vla)" " = 1" \
-         "size of unsigned_short_vla"
-gdb_test "print uchar_size == sizeof(unsigned_char_vla)" " = 1" \
-         "size of unsigned_char_vla"
-gdb_test "print foo_size == sizeof(foo_vla)" " = 1" "size of foo_vla"
-gdb_test "print bar_size == sizeof(bar_vla)" " = 1" "size of bar_vla"
-
-# Check side effects for sizeof argument.
-set sizeof_int [get_sizeof "int" 4]
-gdb_test_no_output  "set variable int_vla\[0\] = 42" \
-                    "set variable int_vla\[0\] = 42"
-
-gdb_test "print sizeof (++int_vla\[0\])" " = ${sizeof_int}" \
-         "print sizeof (++int_vla\[0\])"
-gdb_test "print int_vla\[0\]" " = 42" \
-         "print int_vla\[0\] - sizeof no side effects"
-
-gdb_test "ptype ++int_vla\[0\]" "type = int" "ptype ++int_vla\[0\]"
-gdb_test "print int_vla\[0\]" " = 42" \
-         "print int_vla\[0\] - ptype no side effects"
-
-gdb_test "whatis ++int_vla\[0\]" "type = int" "whatis ++int_vla\[0\]"
-gdb_test "print int_vla\[0\]" " = 42" \
-         "print int_vla\[0\] - whatis no side effects"
diff --git a/gdb/testsuite/gdb.base/vla-multi.c b/gdb/testsuite/gdb.base/vla-multi.c
deleted file mode 100644
index e5bf9e2..0000000
--- a/gdb/testsuite/gdb.base/vla-multi.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2014 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-void
-f1 (int n, int m, int vla_ptr[n][m])
-{
-  return;                                 /* f1_breakpoint */
-}
-
-void
-vla_mult (int n, int m)
-{
-  int vla[n][m];
-  int i, j;
-
-  for (i = 0; i < n; i++)
-    {
-      for (j = 0; j < m; j++)
-        {
-          vla[i][j] = i + j;
-        }
-    }
-
-  f1(n, m, vla);                          /* vla_filled */
-
-  return;
-}
-
-int
-main(void)
-{
-  vla_mult(2, 2);
-  return 0;
-}
diff --git a/gdb/testsuite/gdb.base/vla-multi.exp b/gdb/testsuite/gdb.base/vla-multi.exp
deleted file mode 100644
index afc2b61..0000000
--- a/gdb/testsuite/gdb.base/vla-multi.exp
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-standard_testfile
-
-if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
-    return -1
-}
-
-if ![runto_main] {
-    return -1
-}
-
-set sizeof_int [get_sizeof "int" 4]
-
-gdb_breakpoint [gdb_get_line_number "vla_filled"]
-gdb_continue_to_breakpoint "vla_filled"
-gdb_test "print vla" " = \\\{\\\{0, 1\\\}, \\\{1, 2\\\}\\\}" \
-         "print vla"
-gdb_test "print vla\[0\]\[1\]" " = 1" "print vla\[0\]\[1\]"
-
-gdb_breakpoint [gdb_get_line_number "f1_breakpoint"]
-gdb_continue_to_breakpoint "f1_breakpoint"
-
-# Calculate the overall size of the vla.
-set sizeof_vla [ expr "2" * "$sizeof_int" ]
-gdb_test "ptype &vla_ptr" \
-    "type = int \\\(\\\*\\\*\\\)\\\[variable length\\\]" \
-    "ptype &vla_ptr"
diff --git a/gdb/testsuite/gdb.base/vla-ptr.c b/gdb/testsuite/gdb.base/vla-ptr.c
deleted file mode 100644
index 54d04a6..0000000
--- a/gdb/testsuite/gdb.base/vla-ptr.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2014 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#define SIZE 5
-
-void
-foo (int n, int vla_ptr[n])
-{
-  return;         /* foo_bp */
-}
-
-void
-bar (int *vla_ptr)
-{
-  return;         /* bar_bp */
-}
-
-void
-vla_func (int n)
-{
-  int vla[n];
-  typedef int typedef_vla[n];
-  typedef_vla td_vla;
-  int i;
-
-  for (i = 0; i < n; i++)
-    {
-      vla[i] = 2+i;
-      td_vla[i] = 4+i;
-    }
-
-  foo(n, vla);
-  bar(vla);
-
-  return;         /* vla_func_bp */
-}
-
-int
-main (void)
-{
-  vla_func(SIZE);
-
-  return 0;
-}
diff --git a/gdb/testsuite/gdb.base/vla-ptr.exp b/gdb/testsuite/gdb.base/vla-ptr.exp
deleted file mode 100644
index 56c9d5b..0000000
--- a/gdb/testsuite/gdb.base/vla-ptr.exp
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-standard_testfile
-
-if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
-    return -1
-}
-
-if ![runto_main] {
-    return -1
-}
-
-set sizeof_int [get_sizeof "int" 4]
-
-# Check that VLA passed to function (pointer) points to the first element.
-gdb_breakpoint [gdb_get_line_number "foo_bp"]
-gdb_continue_to_breakpoint "foo_bp"
-gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (foo)"
-gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (foo)"
-
-gdb_breakpoint [gdb_get_line_number "bar_bp"]
-gdb_continue_to_breakpoint "bar_bp"
-gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (bar)"
-gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (bar)"
-
-gdb_breakpoint [gdb_get_line_number "vla_func_bp"]
-gdb_continue_to_breakpoint "vla_func_bp"
-gdb_test "print td_vla" " = \\\{4, 5, 6, 7, 8\\\}" "print td_vla"
diff --git a/gdb/testsuite/gdb.base/vla-sideeffect.c b/gdb/testsuite/gdb.base/vla-sideeffect.c
deleted file mode 100644
index 6e42a64..0000000
--- a/gdb/testsuite/gdb.base/vla-sideeffect.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2014 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include <stddef.h>
-#define SIZE 10
-
-int
-main (void)
-{
-  int n = SIZE;
-  int i = 0;
-  int j = 0;
-  int vla2[SIZE][n];
-  int vla1[n];
-
-  for (i = 0; i < n; i++)
-    vla1[i] = (i * 2) + n;
-
-  for (i = 0; i < SIZE; i++)
-    for (j = 0; j < n; j++)
-      vla2[i][j] = (i + j) + n;
-
-
-  i = 0;
-  j = 0;
-
-  return 0;           /* vla-filled */
-}
diff --git a/gdb/testsuite/gdb.base/vla-sideeffect.exp b/gdb/testsuite/gdb.base/vla-sideeffect.exp
deleted file mode 100644
index 517d78b..0000000
--- a/gdb/testsuite/gdb.base/vla-sideeffect.exp
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2014 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Tests side-effects of sizeof evaluation.
-# Based on gcc/testsuite/gcc.dg/vla-4.c; vla-15.c
-
-standard_testfile
-
-if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
-    return -1
-}
-
-if ![runto_main] {
-    return -1
-}
-
-gdb_breakpoint [gdb_get_line_number "vla-filled"]
-gdb_continue_to_breakpoint "vla-filled"
-
-# Check side effects for sizeof argument.
-set sizeof_int [get_sizeof "int" 4]
-set sizeof_vla [ expr "10" * "$sizeof_int" ]
-
-gdb_test "print sizeof (vla1\[i++\])" " = ${sizeof_int}" \
-         "print sizeof (vla1\[i++\])"
-gdb_test "print i" " = 0" \
-         "print i - sizeof no side effects"
-
-gdb_test "print sizeof (++vla1\[0\])" " = ${sizeof_int}" \
-         "print sizeof (++vla1\[0\])"
-gdb_test "print vla1\[0\]" " = 10" \
-         "print vla1\[0\] - sizeof no side effects"
-
-gdb_test "ptype ++vla1\[0\]" "type = int" "ptype ++vla1\[0\]"
-gdb_test "print vla1\[0\]" " = 10" \
-         "print vla1\[0\] - ptype no side effects"
-
-gdb_test "whatis ++vla1\[0\]" "type = int" "whatis ++vla1\[0\]"
-gdb_test "print vla1\[0\]" " = 10" \
-         "print vla1\[0\] - whatis no side effects"
-
-
-gdb_test "print sizeof (vla2\[i++\])" " = ${sizeof_vla}" \
-         "print sizeof (vla2\[i++\])"
-gdb_test "print i" " = 1" \
-         "print i - sizeof with side effects (1)"
-
-gdb_test "print sizeof (vla2\[i++ + sizeof(j++)\])" " = ${sizeof_vla}" \
-         "print sizeof (vla2\[i++ + sizeof(j++)\])"
-gdb_test "print i" " = 2" \
-         "print i - sizeof with side effects (2)"
-gdb_test "print j" " = 0" \
-         "print j - sizeof with no side effects"
-
-gdb_test "ptype vla2\[i++\]" "type = int \\\[10\\\]" \
-         "ptype vla2\[i++\]"
-gdb_test "print i" " = 2" \
-         "print i - ptype with side effects (1)"
-
-gdb_test "ptype vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
-         "ptype vla2\[i++ + sizeof(j++)\]"
-gdb_test "print i" " = 2" \
-         "print i - ptype with side effects (2)"
-gdb_test "print j" " = 0" \
-         "print j - ptype with no side effects"
-
-gdb_test "whatis vla2\[i++\]" "type = int \\\[10\\\]" \
-         "whatis vla2\[i++\]"
-gdb_test "print i" " = 2" \
-         "print i - whatis with side effects (1)"
-
-gdb_test "whatis vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
-         "whatis vla2\[i++ + sizeof(j++)\]"
-gdb_test "print i" " = 2" \
-         "print i - whatis with side effects (2)"
-gdb_test "print j" " = 0" \
-         "print j - whatis with no side effects"
diff --git a/gdb/testsuite/gdb.dwarf2/count.exp b/gdb/testsuite/gdb.dwarf2/count.exp
deleted file mode 100644
index d52fa62..0000000
--- a/gdb/testsuite/gdb.dwarf2/count.exp
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright 2014 Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Tests to cover DW_AT_count attribute in subranges.
-
-load_lib dwarf.exp
-
-# Only run on targets which support dwarf and gas.
-if { ![dwarf2_support] } {
-    return 0
-}
-
-standard_testfile main.c count.S
-
-set asm_file [standard_output_file $srcfile2]
-Dwarf::assemble $asm_file {
-    cu {} {
-	compile_unit {{language @DW_LANG_C99}} {
-	    declare_labels char_label array_label array_label2 static_array_label
-
-	    char_label: base_type {
-		{name char}
-		{encoding @DW_ATE_signed}
-		{byte_size 1 DW_FORM_sdata}
-	    }
-
-	    array_label: array_type {
-		{type :$char_label}
-	    } {
-		subrange_type {
-		    {count {DW_OP_lit5} SPECIAL_expr}
-		    {type :$char_label}
-		}
-	    }
-
-	    array_label2: array_type {
-		{type :$char_label}
-	    } {
-		subrange_type {
-		    {count {DW_OP_lit1} SPECIAL_expr}
-		    {type :$char_label}
-		}
-	    }
-
-	    static_array_label: array_type {
-		{type :$char_label}
-	    } {
-		subrange_type {
-		    {count 5 DW_FORM_sdata}
-		    {type :$char_label}
-		}
-	    }
-
-	    DW_TAG_variable {
-		{name array2}
-		{type :$array_label2}
-		{const_value 65 DW_FORM_udata}
-	    }
-
-	    DW_TAG_variable {
-		{name array}
-		{type :$array_label}
-		{const_value hello DW_FORM_block1}
-	    }
-
-	    DW_TAG_variable {
-		{name static_array}
-		{type :$static_array_label}
-		{const_value world DW_FORM_block1}
-	    }
-	}
-    }
-}
-
-if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
-	  object {nodebug}] != "" } {
-    return -1
-}
-
-if { [gdb_compile $asm_file ${binfile}2.o object {nodebug}] != "" } {
-    return -1
-}
-
-if { [gdb_compile [list ${binfile}1.o ${binfile}2.o] \
-	  "${binfile}" executable {}] != "" } {
-    return -1
-}
-
-global GDBFLAGS
-set saved_gdbflags $GDBFLAGS
-set GDBFLAGS [concat $GDBFLAGS " -readnow"]
-clean_restart ${testfile}
-set GDBFLAGS $saved_gdbflags
-
-if ![runto_main] {
-    perror "couldn't run to main"
-    return -1
-}
-
-gdb_test "ptype array" "type = char \\\[5\\\]" "ptype array"
-gdb_test "whatis array" "type = char \\\[5\\\]" "whatis array"
-gdb_test "print array" " = \"hello\"" "print array"
-gdb_test "print sizeof array" " = 5" "print sizeof array"
-
-gdb_test "ptype array2" "type = char \\\[1\\\]" "ptype array"
-gdb_test "whatis array2" "type = char \\\[1\\\]" "whatis array"
-gdb_test "print array2" " = \"A\"" "print array"
-gdb_test "print sizeof array2" " = 1" "print sizeof array"
-
-gdb_test "ptype static_array" "type = char \\\[5\\\]" "ptype static_array"
-gdb_test "whatis static_array" "type = char \\\[5\\\]" "whatis static_array"
-gdb_test "print static_array" " = \"world\"" "print static_array"
-gdb_test "print sizeof static_array" " = 5" "print sizeof static_array"
diff --git a/gdb/testsuite/gdb.mi/mi-vla-c99.exp b/gdb/testsuite/gdb.mi/mi-vla-c99.exp
deleted file mode 100644
index 618e8ab..0000000
--- a/gdb/testsuite/gdb.mi/mi-vla-c99.exp
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2014 Free Software Foundation, Inc.
-
-# Contributed by Intel Corp. <keven.boell@intel.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-# Verify that, using the MI, we can evaluate a simple C Variable Length
-# Array (VLA).
-
-load_lib mi-support.exp
-set MIFLAGS "-i=mi"
-
-gdb_exit
-if [mi_gdb_start] {
-    continue
-}
-
-standard_testfile vla.c
-
-if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" \
-                  "${binfile}" executable {debug}] != "" } {
-     untested mi-vla-basics.exp
-     return -1
-}
-
-mi_delete_breakpoints
-mi_gdb_reinitialize_dir $srcdir/$subdir
-mi_gdb_load ${binfile}
-
-set bp_lineno [gdb_get_line_number "vla-filled"]
-
-mi_create_breakpoint "-t vla.c:$bp_lineno" 1 "del" "func" \
-             ".*vla.c" $bp_lineno $hex \
-             "insert breakpoint at line $bp_lineno after vla is filled"
-mi_run_cmd
-mi_expect_stop "breakpoint-hit" "func" "\{name=\"n\",value=\"5\"\}" \
-               ".*vla.c" "$bp_lineno" { "" "disp=\"del\"" } \
-               "run to breakpoint at line $bp_lineno"
-
-mi_gdb_test "500-data-evaluate-expression vla" \
-    "500\\^done,value=\"\\{0, 1, 2, 3, 4\\}\"" "evaluate complete vla"
-
-mi_gdb_test "501-data-evaluate-expression vla\[0\]" \
-    "501\\^done,value=\"0\"" "evaluate vla\[0\]"
-
-mi_gdb_test "502-data-evaluate-expression vla\[2\]" \
-    "502\\^done,value=\"2\"" "evaluate vla\[2\]"
-
-mi_gdb_test "503-data-evaluate-expression vla\[4\]" \
-    "503\\^done,value=\"4\"" "evaluate vla\[4\]"
-
-mi_create_varobj_checked vla vla "int \\\[5\\\]" \
-                                 "create local variable vla"
-
-mi_gdb_test "504-var-info-type vla" \
-    "504\\^done,type=\"int \\\[5\\\]\"" \
-    "info type variable vla"
-
-mi_gdb_test "505-var-show-format vla" \
-    "505\\^done,format=\"natural\"" \
-    "show format variable vla"
-
-mi_gdb_test "506-var-evaluate-expression vla" \
-    "506\\^done,value=\"\\\[5\\\]\"" \
-    "eval variable vla"
-
-mi_list_array_varobj_children "vla" "5" "int" \
-    "get children of vla"
-
-mi_gdb_exit
-return 0
diff --git a/gdb/testsuite/gdb.mi/vla.c b/gdb/testsuite/gdb.mi/vla.c
deleted file mode 100644
index a26244b..0000000
--- a/gdb/testsuite/gdb.mi/vla.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Contributed by Intel Corp. <keven.boell@intel.com>
-
-   Copyright 2014 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-int
-func (int n)
-{
-  int vla[n], i;
-
-  for (i = 0; i < n; i++)
-    vla[i] = i;
-
-  return n;                 /* vla-filled */
-}
-
-int
-main (void)
-{
-  func (5);
-
-  return 0;
-}
diff --git a/gdb/valops.c b/gdb/valops.c
index a155379..1fa188f 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -266,7 +266,6 @@ value_cast_structs (struct type *type, struct value *v2)
 	{
 	  v = value_full_object (v2, real_type, full, top, using_enc);
 	  v = value_at_lazy (real_type, value_address (v));
-	  real_type = value_type (v);
 
 	  /* We might be trying to cast to the outermost enclosing
 	     type, in which case search_struct_field won't work.  */
@@ -802,7 +801,6 @@ value_dynamic_cast (struct type *type, struct value *arg)
     return value_at_lazy (type, addr);
 
   tem = value_at (type, addr);
-  type = value_type (tem);
 
   /* The first dynamic check specified in 5.2.7.  */
   if (is_public_ancestor (arg_type, TYPE_TARGET_TYPE (resolved_type)))
@@ -902,10 +900,7 @@ value_one (struct type *type)
   return val;
 }
 
-/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.
-   The type of the created value may differ from the passed type TYPE.
-   Make sure to retrieve the returned values's new type after this call
-   e.g. in case the type is a variable length array.  */
+/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.  */
 
 static struct value *
 get_value_at (struct type *type, CORE_ADDR addr, int lazy)
@@ -930,10 +925,7 @@ get_value_at (struct type *type, CORE_ADDR addr, int lazy)
    value_at_lazy instead.  value_at_lazy simply records the address of
    the data and sets the lazy-evaluation-required flag.  The lazy flag
    is tested in the value_contents macro, which is used if and when
-   the contents are actually required.  The type of the created value
-   may differ from the passed type TYPE.  Make sure to retrieve the
-   returned values's new type after this call e.g. in case the type
-   is a variable length array.
+   the contents are actually required.
 
    Note: value_at does *NOT* handle embedded offsets; perform such
    adjustments before or after calling it.  */
@@ -944,10 +936,7 @@ value_at (struct type *type, CORE_ADDR addr)
   return get_value_at (type, addr, 0);
 }
 
-/* Return a lazy value with type TYPE located at ADDR (cf. value_at).
-   The type of the created value may differ from the passed type TYPE.
-   Make sure to retrieve the returned values's new type after this call
-   e.g. in case the type is a variable length array.  */
+/* Return a lazy value with type TYPE located at ADDR (cf. value_at).  */
 
 struct value *
 value_at_lazy (struct type *type, CORE_ADDR addr)
@@ -1322,7 +1311,6 @@ address_of_variable (struct symbol *var, const struct block *b)
      Lazy evaluation pays off here.  */
 
   val = value_of_variable (var, b);
-  type = value_type (val);
 
   if ((VALUE_LVAL (val) == lval_memory && value_lazy (val))
       || TYPE_CODE (type) == TYPE_CODE_FUNC)
@@ -1571,7 +1559,6 @@ value_ind (struct value *arg1)
 			      (value_as_address (arg1)
 			       - value_pointed_to_offset (arg1)));
 
-      enc_type = value_type (arg2);
       return readjust_indirect_value_type (arg2, enc_type, base_type, arg1);
     }
 
diff --git a/gdb/value.c b/gdb/value.c
index d125a09..27043ee 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3319,39 +3319,32 @@ value_from_ulongest (struct type *type, ULONGEST num)
 
 
 /* Create a value representing a pointer of type TYPE to the address
-   ADDR.  The type of the created value may differ from the passed
-   type TYPE. Make sure to retrieve the returned values's new type
-   after this call e.g. in case of an variable length array.  */
-
+   ADDR.  */
 struct value *
 value_from_pointer (struct type *type, CORE_ADDR addr)
 {
-  struct type *resolved_type = resolve_dynamic_type (type, addr);
-  struct value *val = allocate_value (resolved_type);
+  struct value *val = allocate_value (type);
 
-  store_typed_address (value_contents_raw (val),
-		       check_typedef (resolved_type), addr);
+  store_typed_address (value_contents_raw (val), check_typedef (type), addr);
   return val;
 }
 
 
 /* Create a value of type TYPE whose contents come from VALADDR, if it
    is non-null, and whose memory address (in the inferior) is
-   ADDRESS.  The type of the created value may differ from the passed
-   type TYPE.  Make sure to retrieve values new type after this call.  */
+   ADDRESS.  */
 
 struct value *
 value_from_contents_and_address (struct type *type,
 				 const gdb_byte *valaddr,
 				 CORE_ADDR address)
 {
-  struct type *resolved_type = resolve_dynamic_type (type, address);
   struct value *v;
 
   if (valaddr == NULL)
-    v = allocate_value_lazy (resolved_type);
+    v = allocate_value_lazy (type);
   else
-    v = value_from_contents (resolved_type, valaddr);
+    v = value_from_contents (type, valaddr);
   set_value_address (v, address);
   VALUE_LVAL (v) = lval_memory;
   return v;
@@ -3505,7 +3498,6 @@ coerce_ref (struct value *arg)
   retval = value_at_lazy (enc_type,
                           unpack_pointer (value_type (arg),
                                           value_contents (arg)));
-  enc_type = value_type (retval);
   return readjust_indirect_value_type (retval, enc_type,
                                        value_type_arg_tmp, arg);
 }
-- 
1.8.3.2


^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [PATCH v6 00/15] Please have a final look
  2014-04-11 22:33             ` Joel Brobecker
@ 2014-04-14  8:34               ` Agovic, Sanimir
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
  0 siblings, 1 reply; 46+ messages in thread
From: Agovic, Sanimir @ 2014-04-14  8:34 UTC (permalink / raw)
  To: 'Joel Brobecker', Keith Seitz; +Cc: gdb-patches

Keith, Joel, all, sorry for causing any inconvenience and thanks to
you both for taking care of the issue on Friday.

The root cause was this code fragment below. It was in my repo and I
git-amend it accidently as I was playing around with an alternative to
solve the pointer-to-vla issue.

@@ -2985,7 +2984,6 @@ evaluate_subexp_with_coercion (struct expression *exp,
        {
          (*pos) += 4;
          val = address_of_variable (var, exp->elts[pc + 1].block);
-         type = value_type (val);
          return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
                             val);

In addition I refactored the code for handling the sizeof operator to
match Keith latest fix for PR c++/16675 (245a5f0) in:

  #02 vla: enable sizeof operator to work with variable length arrays

I used Jans diffgdb script to compare two runs (pre-/post vla) of 'make
check' and now the patch series is free of regression as it should be.

You will find the latest patch series at:

  https://github.com/intel-gdb/vla/tree/vla-c99

Apologize and thanks again.

 -Sanimir

> -----Original Message-----
> From: Joel Brobecker [mailto:brobecker@adacore.com]
> Sent: Saturday, April 12, 2014 12:33 AM
> To: Keith Seitz
> Cc: Agovic, Sanimir; gdb-patches@sourceware.org
> Subject: Re: [PATCH v6 00/15] Please have a final look
> 
> > You should do whatever is convenient for you, and I will work around it.
> > No reason to inconvenience you further! So, if you are ready, just
> > go ahead and push. I will review the errors and decide from there
> > whether we can wait until early next week to fix them or else if
> > we should revert now.
> 
> It's not extremely bad in the sense that perhaps it's a question
> of check_typedefs, but it triggers some assertions in gdb.ada,
> and some really strange behavior in the other testsuite sections.
> 
> I've now reverted most of the series. Attached is the patch.
> The commit subject says "Revert the entire VLA series", but
> in fact, it's not accurate. I just realized that I didn't need
> to revert the first couple of patches which are preparation work,
> and could stay. I fixed that, but forgot to change the subject
> of the commit :-( - just trying to run and I'm already an hour late.
> 
> I will get back to this on Monday.
> 
> ----
> 
> This reverts the following patch series, as they cause some regresssions.
> 
> commit 37c1ab67a35025d37d42c449deab5f254f9f59da
> type: add c99 variable length array support
> 
> 	gdb/
> 	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
> 	(dwarf2_evaluate_property): New function.
> 	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
> 	* dwarf2read.c (attr_to_dynamic_prop): New function.
> 	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
> 	attribute.
> 	* gdbtypes.c: Include dwarf2loc.h.
> 	(is_dynamic_type): New function.
> 	(resolve_dynamic_type): New function.
> 	(resolve_dynamic_bounds): New function.
> 	(get_type_length): New function.
> 	(check_typedef): Use get_type_length to compute type length.
> 	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
> 	(TYPE_LOW_BOUND_KIND): New macro.
> 	(is_dynamic_type): New function prototype.
> 	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
> 	to resolve dynamic properties of the type. Update comment.
> 	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.
> 
> commit 26cb189f8b46dbe7b2d485525329a8919005ca8a
> vla: enable sizeof operator to work with variable length arrays
> 
> 	gdb/
> 	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
> 	passed to sizeof is dynamic evaluate the argument to compute the length.
> 
> commit 04b19544ef6a97b62b2cc4a3170b900e046ab185
> vla: enable sizeof operator for indirection
> 
> 	gdb/
> 	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
> 	value and retrieve the dynamic type size.
> 
> commit bcd629a44fff61527430f353cf77e20fe3afc395
> vla: update type from newly created value
> 
> 	gdb/
> 	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value.
> 	(ada_template_to_fixed_record_type_1): Likewise.
> 	(ada_to_fixed_type_1): Likewise.
> 	* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
> 	(cp_print_value): Likewise.
> 	* d-valprint.c (dynamic_array_type): Likewise.
> 	* eval.c (evaluate_subexp_with_coercion): Likewise.
> 	* findvar.c (address_of_variable): Likewise.
> 	* jv-valprint.c (java_value_print): Likewise.
> 	* valops.c (value_ind): Likewise.
> 	* value.c (coerce_ref): Likewise.
> 
> commit b86138fb0484f42db6cb83abed1e3d0ad2ec4eac
> vla: print "variable length" for unresolved dynamic bounds
> 
> 	gdb/
> 	* c-typeprint.c (c_type_print_varspec_suffix): Added
> 	check for not yet resolved high bound. If unresolved, print
> 	"variable length" string to the console instead of random
> 	length.
> 
> commit e1969afbd454c09c3aad1990305715f70bc47c3c
> vla: support for DW_AT_count
> 
> 	gdb/
> 	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
> 	property and store it as the high bound and flag the range accordingly.
> 	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
> 	RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
> 	* gdbtypes.h (enum range_flags): New enum.
> 	(struct range_bounds): Add flags member.
> 
> commit 92b09522dc5a93ba4bda3c1c0b3c58264e357c8a
> vla: resolve dynamic bounds if value contents is a constant byte-sequence
> 
> 	gdb/
> 	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
> 	points to a constant blob.
> 
> commit 3bce82377f683870cc89925ff43aefb7dcce4a77
> vla: evaluate operand of sizeof if its type is a vla
> 
> 	gdb/
> 	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
> 	(evaluate_subexp_standard): Pass noside argument.
> 	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
> 	if noside equals EVAL_NORMAL. If the subscript yields a vla type
> 	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
> 	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
> 	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.
> 
> 	gdb/testsuite
> 
> 	* gdb.base/vla-sideeffect.c: New file.
> 	* gdb.base/vla-sideeffect.exp: New file.
> 
> commit 504f34326e5ae7c78ebfcdd6ed03c7403b42048b
> test: cover subranges with present DW_AT_count attribute
> 
> 	gdb/testsuite/
> 	* gdb.dwarf2/count.exp: New file.
> 
> commit 1a237e0ee53bbdee97d72d794b5b42e774cc81c0
> test: multi-dimensional c99 vla.
> 
> 	gdb/testsuite/
> 	* gdb.base/vla-multi.c: New file.
> 	* gdb.base/vla-multi.exp: New file.
> 
> commit 024e13b46f9c33d151ae82fd9d64c53092fd9313
> test: evaluate pointers to C99 vla correctly.
> 
> 	gdb/testsuite/
> 	* gdb.base/vla-ptr.c: New file.
> 	* gdb.base/vla-ptr.exp: New file.
> 
> commit c8655f75e2f0fada311be193e3090087a77ec802
> test: basic c99 vla tests for C primitives
> 
> 	gdb/testsuite/
> 	* gdb.base/vla-datatypes.c: New file.
> 	* gdb.base/vla-datatypes.exp: New file.
> 
> commit 58a84dcf29b735ee776536b4c51ba90b51612b71
> test: add mi vla test
> 
> 	gdb/testsuite/
> 	* gdb.mi/mi-vla-c99.exp: New file.
> 	* gdb.mi/vla.c: New file.
> 
> --
> Joel
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 08/12] vla: evaluate operand of sizeof if its type is a vla
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 01/12] type: add c99 variable length array support Joel Brobecker
                                     ` (11 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

The c99 standard in "6.5.3.4 The sizeof operator" states:

 If the type of the operand is a variable length array type, the operand
 is evaluated;[...]

This patch mirrors the following c99 semantic in gdb:

 1| int vla[n][m];
 2| int i = 1;
 3| sizeof(vla[i++][0]); // No sideffect
 4| assert (i == 1);
 5| sizeof(vla[i++]);    // With sideffect
 6| assert (i == 2);

Note: ptype/whatis still do not allow any sideeffects.

This patch was motivated by:

  https://sourceware.org/ml/gdb-patches/2014-01/msg00732.html

gdb/ChangeLog:

	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
	(evaluate_subexp_standard): Pass noside argument.
	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
	if noside equals EVAL_NORMAL. If the subscript yields a vla type
	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.

testsuite/ChangeLog:

	* gdb.base/vla-sideeffect.c: New file.
	* gdb.base/vla-sideeffect.exp: New file.
---
 gdb/ChangeLog                             | 10 ++++
 gdb/eval.c                                | 43 +++++++++++++--
 gdb/gdbtypes.c                            |  1 +
 gdb/gdbtypes.h                            |  5 ++
 gdb/testsuite/ChangeLog                   |  5 ++
 gdb/testsuite/gdb.base/vla-sideeffect.c   | 42 +++++++++++++++
 gdb/testsuite/gdb.base/vla-sideeffect.exp | 89 +++++++++++++++++++++++++++++++
 7 files changed, 191 insertions(+), 4 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.c
 create mode 100644 gdb/testsuite/gdb.base/vla-sideeffect.exp

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3ea7687..3717d0d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* eval.c (evaluate_subexp_for_sizeof): Add enum noside argument.
+	(evaluate_subexp_standard): Pass noside argument.
+	(evaluate_subexp_for_sizeof) <BINOP_SUBSCRIPT>: Handle subscript case
+	if noside equals EVAL_NORMAL. If the subscript yields a vla type
+	re-evaluate subscript operation with EVAL_NORMAL to enable sideffects.
+	* gdbtypes.c (resolve_dynamic_bounds): Mark bound as evaluated.
+	* gdbtypes.h (enum range_flags): Add RANGE_EVALUATED case.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
 	points to a constant blob.
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 22392eb..3e62eadc 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -50,7 +50,8 @@ extern int overload_resolution;
 
 /* Prototypes for local functions.  */
 
-static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
+static struct value *evaluate_subexp_for_sizeof (struct expression *, int *,
+						 enum noside);
 
 static struct value *evaluate_subexp_for_address (struct expression *,
 						  int *, enum noside);
@@ -2562,7 +2563,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	  evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
 	  goto nosideret;
 	}
-      return evaluate_subexp_for_sizeof (exp, pos);
+      return evaluate_subexp_for_sizeof (exp, pos, noside);
 
     case UNOP_CAST:
       (*pos) += 2;
@@ -2996,10 +2997,13 @@ evaluate_subexp_with_coercion (struct expression *exp,
 
 /* Evaluate a subexpression of EXP, at index *POS,
    and return a value for the size of that subexpression.
-   Advance *POS over the subexpression.  */
+   Advance *POS over the subexpression.  If NOSIDE is EVAL_NORMAL
+   we allow side-effects on the operand if its type is a variable
+   length array.   */
 
 static struct value *
-evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
+evaluate_subexp_for_sizeof (struct expression *exp, int *pos,
+			    enum noside noside)
 {
   /* FIXME: This should be size_t.  */
   struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
@@ -3052,6 +3056,37 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
 	(*pos) += 4;
       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
+	 side-effects. */
+    case BINOP_SUBSCRIPT:
+      if (noside == EVAL_NORMAL)
+	{
+	  int pc = (*pos) + 1;
+
+	  val = evaluate_subexp (NULL_TYPE, exp, &pc, EVAL_AVOID_SIDE_EFFECTS);
+	  type = check_typedef (value_type (val));
+	  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+	    {
+	      type = check_typedef (TYPE_TARGET_TYPE (type));
+	      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+		{
+		  type = TYPE_INDEX_TYPE (type);
+		  /* Only re-evaluate the right hand side if the resulting type
+		     is a variable length type.  */
+		  if (TYPE_RANGE_DATA (type)->flag_bound_evaluated)
+		    {
+		      val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
+		      return value_from_longest
+			(size_type, (LONGEST) TYPE_LENGTH (value_type (val)));
+		    }
+		}
+	    }
+	}
+
+      /* Fall through.  */
+
     default:
       val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
       type = value_type (val);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 57101e1..b1102f6 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1719,6 +1719,7 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
   range_type = create_range_type (NULL,
 				  TYPE_TARGET_TYPE (range_type),
 				  &low_bound, &high_bound);
+  TYPE_RANGE_DATA (range_type)->flag_bound_evaluated = 1;
   return create_array_type (copy_type (type),
 			    elt_type,
 			    range_type);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 6c3bb33..4c9d7c2 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -668,6 +668,11 @@ struct main_type
 	 subrange. This affects how the final hight bound is computed.  */
 
       int flag_upper_bound_is_count : 1;
+
+      /* True if LOW or/and HIGH are resolved into a static bound from
+	 a dynamic one.  */
+
+      int flag_bound_evaluated : 1;
     } *bounds;
 
   } flds_bnds;
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 2e9024f..7d0bd2e 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
+	* gdb.base/vla-sideeffect.c: New file.
+	* gdb.base/vla-sideeffect.exp: New file.
+
 2014-04-14  David Blaikie <dblaikie@gmail.com>
 
 	* gdb.mi/non-stop.c: Add return value for non-void function return
diff --git a/gdb/testsuite/gdb.base/vla-sideeffect.c b/gdb/testsuite/gdb.base/vla-sideeffect.c
new file mode 100644
index 0000000..6e42a64
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-sideeffect.c
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#define SIZE 10
+
+int
+main (void)
+{
+  int n = SIZE;
+  int i = 0;
+  int j = 0;
+  int vla2[SIZE][n];
+  int vla1[n];
+
+  for (i = 0; i < n; i++)
+    vla1[i] = (i * 2) + n;
+
+  for (i = 0; i < SIZE; i++)
+    for (j = 0; j < n; j++)
+      vla2[i][j] = (i + j) + n;
+
+
+  i = 0;
+  j = 0;
+
+  return 0;           /* vla-filled */
+}
diff --git a/gdb/testsuite/gdb.base/vla-sideeffect.exp b/gdb/testsuite/gdb.base/vla-sideeffect.exp
new file mode 100644
index 0000000..517d78b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-sideeffect.exp
@@ -0,0 +1,89 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Tests side-effects of sizeof evaluation.
+# Based on gcc/testsuite/gcc.dg/vla-4.c; vla-15.c
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "vla-filled"]
+gdb_continue_to_breakpoint "vla-filled"
+
+# Check side effects for sizeof argument.
+set sizeof_int [get_sizeof "int" 4]
+set sizeof_vla [ expr "10" * "$sizeof_int" ]
+
+gdb_test "print sizeof (vla1\[i++\])" " = ${sizeof_int}" \
+         "print sizeof (vla1\[i++\])"
+gdb_test "print i" " = 0" \
+         "print i - sizeof no side effects"
+
+gdb_test "print sizeof (++vla1\[0\])" " = ${sizeof_int}" \
+         "print sizeof (++vla1\[0\])"
+gdb_test "print vla1\[0\]" " = 10" \
+         "print vla1\[0\] - sizeof no side effects"
+
+gdb_test "ptype ++vla1\[0\]" "type = int" "ptype ++vla1\[0\]"
+gdb_test "print vla1\[0\]" " = 10" \
+         "print vla1\[0\] - ptype no side effects"
+
+gdb_test "whatis ++vla1\[0\]" "type = int" "whatis ++vla1\[0\]"
+gdb_test "print vla1\[0\]" " = 10" \
+         "print vla1\[0\] - whatis no side effects"
+
+
+gdb_test "print sizeof (vla2\[i++\])" " = ${sizeof_vla}" \
+         "print sizeof (vla2\[i++\])"
+gdb_test "print i" " = 1" \
+         "print i - sizeof with side effects (1)"
+
+gdb_test "print sizeof (vla2\[i++ + sizeof(j++)\])" " = ${sizeof_vla}" \
+         "print sizeof (vla2\[i++ + sizeof(j++)\])"
+gdb_test "print i" " = 2" \
+         "print i - sizeof with side effects (2)"
+gdb_test "print j" " = 0" \
+         "print j - sizeof with no side effects"
+
+gdb_test "ptype vla2\[i++\]" "type = int \\\[10\\\]" \
+         "ptype vla2\[i++\]"
+gdb_test "print i" " = 2" \
+         "print i - ptype with side effects (1)"
+
+gdb_test "ptype vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
+         "ptype vla2\[i++ + sizeof(j++)\]"
+gdb_test "print i" " = 2" \
+         "print i - ptype with side effects (2)"
+gdb_test "print j" " = 0" \
+         "print j - ptype with no side effects"
+
+gdb_test "whatis vla2\[i++\]" "type = int \\\[10\\\]" \
+         "whatis vla2\[i++\]"
+gdb_test "print i" " = 2" \
+         "print i - whatis with side effects (1)"
+
+gdb_test "whatis vla2\[i++ + sizeof(j++)\]" "type = int \\\[10\\\]" \
+         "whatis vla2\[i++ + sizeof(j++)\]"
+gdb_test "print i" " = 2" \
+         "print i - whatis with side effects (2)"
+gdb_test "print j" " = 0" \
+         "print j - whatis with no side effects"
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 04/12] vla: update type from newly created value
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (3 preceding siblings ...)
  2014-04-14 17:13                   ` [PATCH 02/12] vla: enable sizeof operator to work with variable length arrays Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 05/12] vla: print "variable length" for unresolved dynamic bounds Joel Brobecker
                                     ` (7 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

Constructing a value based on a type and address might change the type
of the newly constructed value. Thus re-fetch type via value_type to ensure
we have the correct type at hand.

gdb/ChangeLog

	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from value.
	(ada_template_to_fixed_record_type_1): Likewise.
	(ada_to_fixed_type_1): Likewise.
	* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
	(cp_print_value): Likewise.
	* d-valprint.c (dynamic_array_type): Likewise.
	* findvar.c (address_of_variable): Likewise.
	* jv-valprint.c (java_value_print): Likewise.
	* valops.c (value_ind): Likewise.
	* value.c (coerce_ref): Likewise.
---
 gdb/ChangeLog     | 14 ++++++++++++++
 gdb/ada-lang.c    | 13 +++++++++++--
 gdb/cp-valprint.c |  2 ++
 gdb/d-valprint.c  |  1 +
 gdb/jv-valprint.c |  1 +
 gdb/valops.c      |  4 ++++
 gdb/value.c       |  1 +
 7 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c7efe62..955db91 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,19 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from
+	value.
+	(ada_template_to_fixed_record_type_1): Likewise.
+	(ada_to_fixed_type_1): Likewise.
+	* cp-valprint.c (cp_print_value_fields_rtti): Likewise.
+	(cp_print_value): Likewise.
+	* d-valprint.c (dynamic_array_type): Likewise.
+	* findvar.c (address_of_variable): Likewise.
+	* jv-valprint.c (java_value_print): Likewise.
+	* valops.c (value_ind): Likewise.
+	* value.c (coerce_ref): Likewise.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
 	value and retrieve the dynamic type size.
 
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 9544758..e268eba 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -2406,6 +2406,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr,
   else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj))
     {
       v = value_at (type, value_address (obj));
+      type = value_type (v);
       bytes = (unsigned char *) alloca (len);
       read_memory (value_address (v) + offset, bytes, len);
     }
@@ -7888,6 +7889,7 @@ ada_template_to_fixed_record_type_1 (struct type *type,
 		 size first before creating the value.  */
 	      check_size (rtype);
 	      dval = value_from_contents_and_address (rtype, valaddr, address);
+	      rtype = value_type (dval);
 	    }
           else
             dval = dval0;
@@ -7990,7 +7992,10 @@ ada_template_to_fixed_record_type_1 (struct type *type,
       off = TYPE_FIELD_BITPOS (rtype, variant_field);
 
       if (dval0 == NULL)
-        dval = value_from_contents_and_address (rtype, valaddr, address);
+	{
+	  dval = value_from_contents_and_address (rtype, valaddr, address);
+	  rtype = value_type (dval);
+	}
       else
         dval = dval0;
 
@@ -8131,7 +8136,10 @@ to_record_with_fixed_variant_part (struct type *type, const gdb_byte *valaddr,
     return type;
 
   if (dval0 == NULL)
-    dval = value_from_contents_and_address (type, valaddr, address);
+    {
+      dval = value_from_contents_and_address (type, valaddr, address);
+      type = value_type (dval);
+    }
   else
     dval = dval0;
 
@@ -8429,6 +8437,7 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
 	      value_from_contents_and_address (fixed_record_type,
 					       valaddr,
 					       address);
+            fixed_record_type = value_type (obj);
             if (real_type != NULL)
               return to_fixed_record_type
 		(real_type, NULL,
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 2d366b9..3e1d6ed 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -443,6 +443,7 @@ cp_print_value_fields_rtti (struct type *type,
       /* Ugh, we have to convert back to a value here.  */
       value = value_from_contents_and_address (type, valaddr + offset,
 					       address + offset);
+      type = value_type (value);
       /* We don't actually care about most of the result here -- just
 	 the type.  We already have the correct offset, due to how
 	 val_print was initially called.  */
@@ -545,6 +546,7 @@ cp_print_value (struct type *type, struct type *real_type,
 		  base_val = value_from_contents_and_address (baseclass,
 							      buf,
 							      address + boffset);
+		  baseclass = value_type (base_val);
 		  thisoffset = 0;
 		  boffset = 0;
 		  thistype = baseclass;
diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c
index 90095cd..755f180 100644
--- a/gdb/d-valprint.c
+++ b/gdb/d-valprint.c
@@ -59,6 +59,7 @@ dynamic_array_type (struct type *type, const gdb_byte *valaddr,
 
       true_type = lookup_array_range_type (true_type, 0, length - 1);
       ival = value_at (true_type, addr);
+      true_type = value_type (ival);
 
       d_val_print (true_type,
 		   value_contents_for_printing (ival),
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
index 82bdd9b..a7bb494 100644
--- a/gdb/jv-valprint.c
+++ b/gdb/jv-valprint.c
@@ -65,6 +65,7 @@ java_value_print (struct value *val, struct ui_file *stream,
 	  type = lookup_pointer_type (type);
 
 	  val = value_at (type, address);
+	  type = value_type (val);
 	}
     }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index 46e2639..a155379 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -266,6 +266,7 @@ value_cast_structs (struct type *type, struct value *v2)
 	{
 	  v = value_full_object (v2, real_type, full, top, using_enc);
 	  v = value_at_lazy (real_type, value_address (v));
+	  real_type = value_type (v);
 
 	  /* We might be trying to cast to the outermost enclosing
 	     type, in which case search_struct_field won't work.  */
@@ -801,6 +802,7 @@ value_dynamic_cast (struct type *type, struct value *arg)
     return value_at_lazy (type, addr);
 
   tem = value_at (type, addr);
+  type = value_type (tem);
 
   /* The first dynamic check specified in 5.2.7.  */
   if (is_public_ancestor (arg_type, TYPE_TARGET_TYPE (resolved_type)))
@@ -1320,6 +1322,7 @@ address_of_variable (struct symbol *var, const struct block *b)
      Lazy evaluation pays off here.  */
 
   val = value_of_variable (var, b);
+  type = value_type (val);
 
   if ((VALUE_LVAL (val) == lval_memory && value_lazy (val))
       || TYPE_CODE (type) == TYPE_CODE_FUNC)
@@ -1568,6 +1571,7 @@ value_ind (struct value *arg1)
 			      (value_as_address (arg1)
 			       - value_pointed_to_offset (arg1)));
 
+      enc_type = value_type (arg2);
       return readjust_indirect_value_type (arg2, enc_type, base_type, arg1);
     }
 
diff --git a/gdb/value.c b/gdb/value.c
index 9cc5e44..d125a09 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3505,6 +3505,7 @@ coerce_ref (struct value *arg)
   retval = value_at_lazy (enc_type,
                           unpack_pointer (value_type (arg),
                                           value_contents (arg)));
+  enc_type = value_type (retval);
   return readjust_indirect_value_type (retval, enc_type,
                                        value_type_arg_tmp, arg);
 }
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 02/12] vla: enable sizeof operator to work with variable length arrays
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (2 preceding siblings ...)
  2014-04-14 17:13                   ` [PATCH 07/12] vla: resolve dynamic bounds if value contents is a constant byte-sequence Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 04/12] vla: update type from newly created value Joel Brobecker
                                     ` (8 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

In C99 the sizeof operator computes the size of a variable length array
at runtime (6.5.3.4 The sizeof operator). This patch reflects the semantic
change in the debugger.

We now are able to get the size of a vla:

1| void foo (size_t n) {
2|   int vla[n];
3| }

(gdb) p sizeof(vla)

yields N * sizeof(int).

gdb/ChangeLog:

	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
	passed to sizeof is dynamic evaluate the argument to compute the length.
---
 gdb/ChangeLog | 5 +++++
 gdb/eval.c    | 8 +++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cf9a35d..1755609 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,9 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
+	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
+	passed to sizeof is dynamic evaluate the argument to compute the length.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 	    Joel Brobecker  <brobecker@adacore.com>
 
 	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
diff --git a/gdb/eval.c b/gdb/eval.c
index c1e47e0..85523cd 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -3040,8 +3040,14 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
       break;
 
     case OP_VAR_VALUE:
-      (*pos) += 4;
       type = SYMBOL_TYPE (exp->elts[pc + 2].symbol);
+      if (is_dynamic_type (type))
+	{
+	  val = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_NORMAL);
+	  type = value_type (val);
+	}
+      else
+	(*pos) += 4;
       break;
 
     default:
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 07/12] vla: resolve dynamic bounds if value contents is a constant byte-sequence
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 08/12] vla: evaluate operand of sizeof if its type is a vla Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 01/12] type: add c99 variable length array support Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 02/12] vla: enable sizeof operator to work with variable length arrays Joel Brobecker
                                     ` (9 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

A variable location might be a constant value and therefore no inferior memory
access is needed to read the content. In this case try to resolve the type
bounds.

gdb/ChangeLog:

	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
	points to a constant blob.
---
 gdb/ChangeLog |  5 +++++
 gdb/findvar.c | 12 +++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 717c197..3ea7687 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* findvar.c (default_read_var_value): Resolve dynamic bounds if location
+	points to a constant blob.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
 	property and store it as the high bound and flag the range accordingly.
 	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
diff --git a/gdb/findvar.c b/gdb/findvar.c
index a2a7bb7..998a799 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -437,7 +437,12 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
   switch (SYMBOL_CLASS (var))
     {
     case LOC_CONST:
-      /* Put the constant back in target format.  */
+      if (is_dynamic_type (type))
+	{
+	  /* Value is a constant byte-sequence and needs no memory access.  */
+	  type = resolve_dynamic_type (type, /* Unused address.  */ 0);
+	}
+      /* Put the constant back in target format. */
       v = allocate_value (type);
       store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type),
 			    gdbarch_byte_order (get_type_arch (type)),
@@ -464,6 +469,11 @@ default_read_var_value (struct symbol *var, struct frame_info *frame)
       return v;
 
     case LOC_CONST_BYTES:
+      if (is_dynamic_type (type))
+	{
+	  /* Value is a constant byte-sequence and needs no memory access.  */
+	  type = resolve_dynamic_type (type, /* Unused address.  */ 0);
+	}
       v = allocate_value (type);
       memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var),
 	      TYPE_LENGTH (type));
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 06/12] vla: support for DW_AT_count
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (5 preceding siblings ...)
  2014-04-14 17:13                   ` [PATCH 05/12] vla: print "variable length" for unresolved dynamic bounds Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 03/12] vla: enable sizeof operator for indirection Joel Brobecker
                                     ` (5 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

This patch adds support for DW_AT_count as requested in the code review:

  https://sourceware.org/ml/gdb-patches/2013-11/msg00200.html

gdb/ChangeLog:

	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
	property and store it as the high bound and flag the range accordingly.
	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
	RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
	* gdbtypes.h (enum range_flags): New enum.
	(struct range_bounds): Add flags member.
---
 gdb/ChangeLog    |  9 +++++++++
 gdb/dwarf2read.c | 18 ++++++++++--------
 gdb/gdbtypes.c   |  4 ++++
 gdb/gdbtypes.h   |  5 +++++
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0630f1c..717c197 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,14 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* dwarf2read.c (read_subrange_type): Convert DW_AT_count to a dynamic
+	property and store it as the high bound and flag the range accordingly.
+	* gdbtypes.c (resolve_dynamic_bounds): If range is flagged as
+	RANGE_UPPER_BOUND_IS_COUNT assign low + high - 1 as the new high bound.
+	* gdbtypes.h (enum range_flags): New enum.
+	(struct range_bounds): Add flags member.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* c-typeprint.c (c_type_print_varspec_suffix): Added
 	check for not yet resolved high bound. If unresolved, print
 	"variable length" string to the console instead of random
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index ff66cce..7c64491 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14493,6 +14493,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   struct attribute *attr;
   struct dynamic_prop low, high;
   int low_default_is_valid;
+  int high_bound_is_count = 0;
   const char *name;
   LONGEST negative_mask;
 
@@ -14559,15 +14560,13 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
   if (!attr_to_dynamic_prop (attr, die, cu, &high))
     {
       attr = dwarf2_attr (die, DW_AT_count, cu);
-      if (attr)
-	{
-	  int count = dwarf2_get_attr_constant_value (attr, 1);
-	  high.data.const_val = low.data.const_val + count - 1;
-	}
-      else
+      if (attr_to_dynamic_prop (attr, die, cu, &high))
 	{
-	  /* Unspecified array length.  */
-	  high.data.const_val = low.data.const_val - 1;
+	  /* If bounds are constant do the final calculation here.  */
+	  if (low.kind == PROP_CONST && high.kind == PROP_CONST)
+	    high.data.const_val = low.data.const_val + high.data.const_val - 1;
+	  else
+	    high_bound_is_count = 1;
 	}
     }
 
@@ -14627,6 +14626,9 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   range_type = create_range_type (NULL, orig_base_type, &low, &high);
 
+  if (high_bound_is_count)
+    TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1;
+
   /* Ada expects an empty array on no boundary attributes.  */
   if (attr == NULL && cu->language != language_ada)
     TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index d510ee6..57101e1 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1698,6 +1698,10 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
     {
       high_bound.kind = PROP_CONST;
       high_bound.data.const_val = value;
+
+      if (TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count)
+	high_bound.data.const_val
+	  = low_bound.data.const_val + high_bound.data.const_val - 1;
     }
   else
     {
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 97411d1..6c3bb33 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -663,6 +663,11 @@ struct main_type
       /* * High bound of range.  */
 
       struct dynamic_prop high;
+
+      /* True if HIGH range bound contains the number of elements in the
+	 subrange. This affects how the final hight bound is computed.  */
+
+      int flag_upper_bound_is_count : 1;
     } *bounds;
 
   } flds_bnds;
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 05/12] vla: print "variable length" for unresolved dynamic bounds
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (4 preceding siblings ...)
  2014-04-14 17:13                   ` [PATCH 04/12] vla: update type from newly created value Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 06/12] vla: support for DW_AT_count Joel Brobecker
                                     ` (6 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

1| void foo (size_t n) {
2|   int vla[n];
3| }

Given the following expression

  (gdb) ptype &vla

Gdb evaluates the expression with EVAL_AVOID_SIDE_EFFECTS and thus
does not resolve the bounds information and misinterprets the high
bound as a constant. The current output is:

  type = int (*)[1289346]

this patch deals with this case and prints:

  type = int (*)[variable length]

instead.

gdb/ChangeLog:

	* c-typeprint.c (c_type_print_varspec_suffix): Added
	check for not yet resolved high bound. If unresolved, print
	"variable length" string to the console instead of random
	length.
---
 gdb/ChangeLog     | 7 +++++++
 gdb/c-typeprint.c | 6 +++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 955db91..0630f1c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* c-typeprint.c (c_type_print_varspec_suffix): Added
+	check for not yet resolved high bound. If unresolved, print
+	"variable length" string to the console instead of random
+	length.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* ada-lang.c (ada_value_primitive_packed_val): Re-fetch type from
 	value.
 	(ada_template_to_fixed_record_type_1): Likewise.
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 4edc9ec..d910058 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -689,7 +689,11 @@ c_type_print_varspec_suffix (struct type *type,
 
 	fprintf_filtered (stream, (is_vector ?
 				   " __attribute__ ((vector_size(" : "["));
-	if (get_array_bounds (type, &low_bound, &high_bound))
+	/* Bounds are not yet resolved, print a bounds placeholder instead.  */
+	if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
+	    || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
+	  fprintf_filtered (stream, "variable length");
+	else if (get_array_bounds (type, &low_bound, &high_bound))
 	  fprintf_filtered (stream, "%s", 
 			    plongest (high_bound - low_bound + 1));
 	fprintf_filtered (stream, (is_vector ? ")))" : "]"));
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/12] vla: enable sizeof operator for indirection
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (6 preceding siblings ...)
  2014-04-14 17:13                   ` [PATCH 06/12] vla: support for DW_AT_count Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-14 17:14                   ` [PATCH 12/12] test: add mi vla test Joel Brobecker
                                     ` (4 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

This patch enables the sizeof operator for indirections:

1| void foo (size_t n) {
2|   int vla[n];
3|   int *vla_ptr = &vla;
4| }

(gdb) p sizeof(*vla_ptr)

yields sizeof (size_t) * n.

gdb/ChangeLog:

	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
	value and retrieve the dynamic type size.
---
 gdb/ChangeLog | 5 +++++
 gdb/eval.c    | 4 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1755609..c7efe62 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* eval.c (evaluate_subexp_for_sizeof) <UNOP_IND>: Create an indirect
+	value and retrieve the dynamic type size.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* eval.c (evaluate_subexp_for_sizeof) <OP_VAR_VALUE>: If the type
 	passed to sizeof is dynamic evaluate the argument to compute the length.
 
diff --git a/gdb/eval.c b/gdb/eval.c
index 85523cd..22392eb 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -3026,7 +3026,9 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
 	  && TYPE_CODE (type) != TYPE_CODE_ARRAY)
 	error (_("Attempt to take contents of a non-pointer value."));
       type = TYPE_TARGET_TYPE (type);
-      break;
+      if (is_dynamic_type (type))
+	type = value_type (value_ind (val));
+      return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
 
     case UNOP_MEMVAL:
       (*pos) += 3;
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 01/12] type: add c99 variable length array support
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 08/12] vla: evaluate operand of sizeof if its type is a vla Joel Brobecker
@ 2014-04-14 17:13                   ` Joel Brobecker
  2014-04-18 19:06                     ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 07/12] vla: resolve dynamic bounds if value contents is a constant byte-sequence Joel Brobecker
                                     ` (10 subsequent siblings)
  12 siblings, 1 reply; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

The dwarf standard allow certain attributes to be expressed as dwarf
expressions rather than constants. For instance upper-/lowerbound attributes.
In case of a c99 variable length array the upperbound is a dynamic attribute.

With this change c99 vla behave the same as with static arrays.

1| void foo (size_t n) {
2|   int ary[n];
3|   memset(ary, 0, sizeof(ary));
4| }

(gdb) print ary
$1 = {0 <repeats 42 times>}

gdb/ChangeLog:

	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
	(dwarf2_evaluate_property): New function.
	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
	* dwarf2read.c (attr_to_dynamic_prop): New function.
	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
	attribute.
	* gdbtypes.c: Include dwarf2loc.h.
	(is_dynamic_type): New function.
	(resolve_dynamic_type): New function.
	(resolve_dynamic_bounds): New function.
	(get_type_length): New function.
	(check_typedef): Use get_type_length to compute type length.
	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
	(TYPE_LOW_BOUND_KIND): New macro.
	(is_dynamic_type): New function prototype.
	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
	to resolve dynamic properties of the type. Update comment.
	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.
---
 gdb/ChangeLog    |  22 ++++++
 gdb/dwarf2loc.c  | 119 ++++++++++++++++++++++++++++++
 gdb/dwarf2loc.h  |  28 +++++++
 gdb/dwarf2read.c | 106 ++++++++++++++++++++-------
 gdb/gdbtypes.c   | 220 +++++++++++++++++++++++++++++++++++++++++--------------
 gdb/gdbtypes.h   |  10 +++
 gdb/valops.c     |  15 +++-
 gdb/value.c      |  19 +++--
 8 files changed, 449 insertions(+), 90 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 57fe8d9..cf9a35d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,25 @@
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+	    Joel Brobecker  <brobecker@adacore.com>
+
+	* dwarf2loc.c (dwarf2_locexpr_baton_eval): New function.
+	(dwarf2_evaluate_property): New function.
+	* dwarf2loc.h (dwarf2_evaluate_property): New function prototype.
+	* dwarf2read.c (attr_to_dynamic_prop): New function.
+	(read_subrange_type): Use attr_to_dynamic_prop to read high bound
+	attribute.
+	* gdbtypes.c: Include dwarf2loc.h.
+	(is_dynamic_type): New function.
+	(resolve_dynamic_type): New function.
+	(resolve_dynamic_bounds): New function.
+	(get_type_length): New function.
+	(check_typedef): Use get_type_length to compute type length.
+	* gdbtypes.h (TYPE_HIGH_BOUND_KIND): New macro.
+	(TYPE_LOW_BOUND_KIND): New macro.
+	(is_dynamic_type): New function prototype.
+	* value.c (value_from_contents_and_address): Call resolve_dynamic_type
+	to resolve dynamic properties of the type. Update comment.
+	* valops.c (get_value_at, value_at, value_at_lazy): Update comment.
+
 2014-04-14  Richard Henderson  <rth@redhat.com>
 
 	* alpha-linux-nat.c (_initialize_alpha_linux_nat): Fix prototype.
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index e91b764..addae13 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2432,6 +2432,125 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
   return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, 0);
 }
 
+/* Evaluates a dwarf expression and stores the result in VAL, expecting
+   that the dwarf expression only produces a single CORE_ADDR.  ADDR is a
+   context (location of a variable) and might be needed to evaluate the
+   location expression.
+   Returns 1 on success, 0 otherwise.   */
+
+static int
+dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
+			   CORE_ADDR addr, CORE_ADDR *valp)
+{
+  struct dwarf_expr_context *ctx;
+  struct dwarf_expr_baton baton;
+  struct objfile *objfile;
+  struct cleanup *cleanup;
+
+  if (dlbaton == NULL || dlbaton->size == 0)
+    return 0;
+
+  ctx = new_dwarf_expr_context ();
+  cleanup = make_cleanup_free_dwarf_expr_context (ctx);
+
+  baton.frame = get_selected_frame (NULL);
+  baton.per_cu = dlbaton->per_cu;
+
+  objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
+
+  ctx->gdbarch = get_objfile_arch (objfile);
+  ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
+  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
+  ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
+  ctx->funcs = &dwarf_expr_ctx_funcs;
+  ctx->baton = &baton;
+
+  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
+
+  switch (ctx->location)
+    {
+    case DWARF_VALUE_REGISTER:
+    case DWARF_VALUE_MEMORY:
+    case DWARF_VALUE_STACK:
+      *valp = dwarf_expr_fetch_address (ctx, 0);
+      if (ctx->location == DWARF_VALUE_REGISTER)
+	*valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
+      do_cleanups (cleanup);
+      return 1;
+    case DWARF_VALUE_LITERAL:
+      *valp = extract_signed_integer (ctx->data, ctx->len,
+				      gdbarch_byte_order (ctx->gdbarch));
+      do_cleanups (cleanup);
+      return 1;
+      /* Unsupported dwarf values.  */
+    case DWARF_VALUE_OPTIMIZED_OUT:
+    case DWARF_VALUE_IMPLICIT_POINTER:
+      break;
+    }
+
+  do_cleanups (cleanup);
+  return 0;
+}
+
+/* See dwarf2loc.h.  */
+
+int
+dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address,
+			  CORE_ADDR *value)
+{
+  if (prop == NULL)
+    return 0;
+
+  switch (prop->kind)
+    {
+    case PROP_LOCEXPR:
+      {
+	const struct dwarf2_property_baton *baton = prop->data.baton;
+
+	if (dwarf2_locexpr_baton_eval (&baton->locexpr, address, value))
+	  {
+	    if (baton->referenced_type)
+	      {
+		struct value *val = value_at (baton->referenced_type, *value);
+
+		*value = value_as_address (val);
+	      }
+	    return 1;
+	  }
+      }
+      break;
+
+    case PROP_LOCLIST:
+      {
+	struct dwarf2_property_baton *baton = prop->data.baton;
+	struct frame_info *frame = get_selected_frame (NULL);
+	CORE_ADDR pc = get_frame_address_in_block (frame);
+	const gdb_byte *data;
+	struct value *val;
+	size_t size;
+
+	data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
+	if (data != NULL)
+	  {
+	    val = dwarf2_evaluate_loc_desc (baton->referenced_type, frame, data,
+					    size, baton->loclist.per_cu);
+	    if (!value_optimized_out (val))
+	      {
+		*value = value_as_address (val);
+		return 1;
+	      }
+	  }
+      }
+      break;
+
+    case PROP_CONST:
+      *value = prop->data.const_val;
+      return 1;
+    }
+
+  return 0;
+}
+
 \f
 /* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
 
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 786e77c..36173c5 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -90,6 +90,14 @@ struct value *dwarf2_evaluate_loc_desc (struct type *type,
 					size_t size,
 					struct dwarf2_per_cu_data *per_cu);
 
+/* Converts a dynamic property into a static one.  ADDR is the address of
+   the object currently being evaluated and might be nedded.
+   Returns 1 if PROP could be converted and the static value is passed back
+   into VALUE, otherwise returns 0.  */
+
+int dwarf2_evaluate_property (const struct dynamic_prop *prop,
+			      CORE_ADDR addr, CORE_ADDR *value);
+
 CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
 				  unsigned int addr_index);
 
@@ -135,6 +143,26 @@ struct dwarf2_loclist_baton
   unsigned char from_dwo;
 };
 
+/* A dynamic property is either expressed as a single location expression
+   or a location list.  If the property is an indirection, pointing to
+   another die, keep track of the targeted type in REFERENCED_TYPE.  */
+
+struct dwarf2_property_baton
+{
+  /* If the property is an indirection, we need to evaluate the location
+     LOCEXPR or LOCLIST in the context of the type REFERENCED_TYPE.
+     If NULL, the location is the actual value of the property.  */
+  struct type *referenced_type;
+  union
+  {
+    /* Location expression.  */
+    struct dwarf2_locexpr_baton locexpr;
+
+    /* Location list to be evaluated in the context of REFERENCED_TYPE.  */
+    struct dwarf2_loclist_baton loclist;
+  };
+};
+
 extern const struct symbol_computed_ops dwarf2_locexpr_funcs;
 extern const struct symbol_computed_ops dwarf2_loclist_funcs;
 
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 152c8d2..ff66cce 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14405,6 +14405,84 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
   return set_die_type (die, type, cu);
 }
 
+/* Parse dwarf attribute if it's a block, reference or constant and put the
+   resulting value of the attribute into struct bound_prop.
+   Returns 1 if ATTR could be resolved into PROP, 0 otherwise.  */
+
+static int
+attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
+		      struct dwarf2_cu *cu, struct dynamic_prop *prop)
+{
+  struct dwarf2_property_baton *baton;
+  struct obstack *obstack = &cu->objfile->objfile_obstack;
+
+  if (attr == NULL || prop == NULL)
+    return 0;
+
+  if (attr_form_is_block (attr))
+    {
+      baton = obstack_alloc (obstack, sizeof (*baton));
+      baton->referenced_type = NULL;
+      baton->locexpr.per_cu = cu->per_cu;
+      baton->locexpr.size = DW_BLOCK (attr)->size;
+      baton->locexpr.data = DW_BLOCK (attr)->data;
+      prop->data.baton = baton;
+      prop->kind = PROP_LOCEXPR;
+      gdb_assert (prop->data.baton != NULL);
+    }
+  else if (attr_form_is_ref (attr))
+    {
+      struct dwarf2_cu *target_cu = cu;
+      struct die_info *target_die;
+      struct attribute *target_attr;
+
+      target_die = follow_die_ref (die, attr, &target_cu);
+      target_attr = dwarf2_attr (target_die, DW_AT_location, target_cu);
+      if (target_attr == NULL)
+	return 0;
+
+      if (attr_form_is_section_offset (target_attr))
+	{
+	  baton = obstack_alloc (obstack, sizeof (*baton));
+	  baton->referenced_type = die_type (target_die, target_cu);
+	  fill_in_loclist_baton (cu, &baton->loclist, target_attr);
+	  prop->data.baton = baton;
+	  prop->kind = PROP_LOCLIST;
+	  gdb_assert (prop->data.baton != NULL);
+	}
+      else if (attr_form_is_block (target_attr))
+	{
+	  baton = obstack_alloc (obstack, sizeof (*baton));
+	  baton->referenced_type = die_type (target_die, target_cu);
+	  baton->locexpr.per_cu = cu->per_cu;
+	  baton->locexpr.size = DW_BLOCK (target_attr)->size;
+	  baton->locexpr.data = DW_BLOCK (target_attr)->data;
+	  prop->data.baton = baton;
+	  prop->kind = PROP_LOCEXPR;
+	  gdb_assert (prop->data.baton != NULL);
+	}
+      else
+	{
+	  dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
+						 "dynamic property");
+	  return 0;
+	}
+    }
+  else if (attr_form_is_constant (attr))
+    {
+      prop->data.const_val = dwarf2_get_attr_constant_value (attr, 0);
+      prop->kind = PROP_CONST;
+    }
+  else
+    {
+      dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
+					     dwarf2_name (die, cu));
+      return 0;
+    }
+
+  return 1;
+}
+
 /* Read the given DW_AT_subrange DIE.  */
 
 static struct type *
@@ -14478,27 +14556,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 	       die->offset.sect_off, objfile_name (cu->objfile));
 
   attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
-  if (attr)
-    {
-      if (attr_form_is_block (attr) || attr_form_is_ref (attr))
-        {
-          /* GCC encodes arrays with unspecified or dynamic length
-             with a DW_FORM_block1 attribute or a reference attribute.
-             FIXME: GDB does not yet know how to handle dynamic
-             arrays properly, treat them as arrays with unspecified
-             length for now.
-
-             FIXME: jimb/2003-09-22: GDB does not really know
-             how to handle arrays of unspecified length
-             either; we just represent them as zero-length
-             arrays.  Choose an appropriate upper bound given
-             the lower bound we've computed above.  */
-          high.data.const_val = low.data.const_val - 1;
-        }
-      else
-        high.data.const_val = dwarf2_get_attr_constant_value (attr, 1);
-    }
-  else
+  if (!attr_to_dynamic_prop (attr, die, cu, &high))
     {
       attr = dwarf2_attr (die, DW_AT_count, cu);
       if (attr)
@@ -14569,12 +14627,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
 
   range_type = create_range_type (NULL, orig_base_type, &low, &high);
 
-  /* Mark arrays with dynamic length at least as an array of unspecified
-     length.  GDB could check the boundary but before it gets implemented at
-     least allow accessing the array elements.  */
-  if (attr && attr_form_is_block (attr))
-    TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
-
   /* Ada expects an empty array on no boundary attributes.  */
   if (attr == NULL && cu->language != language_ada)
     TYPE_HIGH_BOUND_KIND (range_type) = PROP_UNDEFINED;
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 231139b..d510ee6 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -40,6 +40,7 @@
 #include "cp-support.h"
 #include "bcache.h"
 #include "dwarf2loc.h"
+#include "gdbcore.h"
 
 /* Initialize BADNESS constants.  */
 
@@ -853,6 +854,17 @@ create_static_range_type (struct type *result_type, struct type *index_type,
   return result_type;
 }
 
+/* Predicate tests whether BOUNDS are static.  Returns 1 if all bounds values
+   are static, otherwise returns 0.  */
+
+static int
+has_static_range (const struct range_bounds *bounds)
+{
+  return (bounds->low.kind == PROP_CONST
+	  && bounds->high.kind == PROP_CONST);
+}
+
+
 /* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type
    TYPE.  Return 1 if type is a range type, 0 if it is discrete (and
    bounds will fit in LONGEST), or -1 otherwise.  */
@@ -986,27 +998,41 @@ create_array_type_with_stride (struct type *result_type,
 			       struct type *range_type,
 			       unsigned int bit_stride)
 {
-  LONGEST low_bound, high_bound;
-
   if (result_type == NULL)
     result_type = alloc_type_copy (range_type);
 
   TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
   TYPE_TARGET_TYPE (result_type) = element_type;
-  if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
-    low_bound = high_bound = 0;
-  CHECK_TYPEDEF (element_type);
-  /* Be careful when setting the array length.  Ada arrays can be
-     empty arrays with the high_bound being smaller than the low_bound.
-     In such cases, the array length should be zero.  */
-  if (high_bound < low_bound)
-    TYPE_LENGTH (result_type) = 0;
-  else if (bit_stride > 0)
-    TYPE_LENGTH (result_type) =
-      (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
+  if (has_static_range (TYPE_RANGE_DATA (range_type)))
+    {
+      LONGEST low_bound, high_bound;
+
+      if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+	low_bound = high_bound = 0;
+      CHECK_TYPEDEF (element_type);
+      /* Be careful when setting the array length.  Ada arrays can be
+	 empty arrays with the high_bound being smaller than the low_bound.
+	 In such cases, the array length should be zero.  */
+      if (high_bound < low_bound)
+	TYPE_LENGTH (result_type) = 0;
+      else if (bit_stride > 0)
+	TYPE_LENGTH (result_type) =
+	  (bit_stride * (high_bound - low_bound + 1) + 7) / 8;
+      else
+	TYPE_LENGTH (result_type) =
+	  TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+    }
   else
-    TYPE_LENGTH (result_type) =
-      TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
+    {
+      /* This type is dynamic and its length needs to be computed
+         on demand.  In the meantime, avoid leaving the TYPE_LENGTH
+         undefined by setting it to zero.  Although we are not expected
+         to trust TYPE_LENGTH in this case, setting the size to zero
+         allows us to avoid allocating objects of random sizes in case
+         we accidently do.  */
+      TYPE_LENGTH (result_type) = 0;
+    }
+
   TYPE_NFIELDS (result_type) = 1;
   TYPE_FIELDS (result_type) =
     (struct field *) TYPE_ZALLOC (result_type, sizeof (struct field));
@@ -1585,6 +1611,131 @@ stub_noname_complaint (void)
   complaint (&symfile_complaints, _("stub type has NULL name"));
 }
 
+/* See gdbtypes.h.  */
+
+int
+is_dynamic_type (struct type *type)
+{
+  type = check_typedef (type);
+
+  if (TYPE_CODE (type) == TYPE_CODE_REF)
+    type = check_typedef (TYPE_TARGET_TYPE (type));
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+      {
+	const struct type *range_type;
+
+	gdb_assert (TYPE_NFIELDS (type) == 1);
+	range_type = TYPE_INDEX_TYPE (type);
+	if (!has_static_range (TYPE_RANGE_DATA (range_type)))
+	  return 1;
+	else
+	  return is_dynamic_type (TYPE_TARGET_TYPE (type));
+	break;
+      }
+    default:
+      return 0;
+      break;
+    }
+}
+
+/* Resolves dynamic bound values of an array type TYPE to static ones.
+   ADDRESS might be needed to resolve the subrange bounds, it is the location
+   of the associated array.  */
+
+static struct type *
+resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
+{
+  CORE_ADDR value;
+  struct type *elt_type;
+  struct type *range_type;
+  struct type *ary_dim;
+  const struct dynamic_prop *prop;
+  const struct dwarf2_locexpr_baton *baton;
+  struct dynamic_prop low_bound, high_bound;
+
+  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    {
+      struct type *copy = copy_type (type);
+
+      TYPE_TARGET_TYPE (copy)
+	= resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
+
+      return copy;
+    }
+
+  if (TYPE_CODE (type) == TYPE_CODE_REF)
+    {
+      struct type *copy = copy_type (type);
+      CORE_ADDR target_addr = read_memory_typed_address (addr, type);
+
+      TYPE_TARGET_TYPE (copy)
+	= resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), target_addr);
+      return copy;
+    }
+
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+
+  elt_type = type;
+  range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
+
+  prop = &TYPE_RANGE_DATA (range_type)->low;
+  if (dwarf2_evaluate_property (prop, addr, &value))
+    {
+      low_bound.kind = PROP_CONST;
+      low_bound.data.const_val = value;
+    }
+  else
+    {
+      low_bound.kind = PROP_UNDEFINED;
+      low_bound.data.const_val = 0;
+    }
+
+  prop = &TYPE_RANGE_DATA (range_type)->high;
+  if (dwarf2_evaluate_property (prop, addr, &value))
+    {
+      high_bound.kind = PROP_CONST;
+      high_bound.data.const_val = value;
+    }
+  else
+    {
+      high_bound.kind = PROP_UNDEFINED;
+      high_bound.data.const_val = 0;
+    }
+
+  ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
+
+  if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
+    elt_type = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
+  else
+    elt_type = TYPE_TARGET_TYPE (type);
+
+  range_type = create_range_type (NULL,
+				  TYPE_TARGET_TYPE (range_type),
+				  &low_bound, &high_bound);
+  return create_array_type (copy_type (type),
+			    elt_type,
+			    range_type);
+}
+
+/* See gdbtypes.h  */
+
+struct type *
+resolve_dynamic_type (struct type *type, CORE_ADDR addr)
+{
+  struct type *real_type = check_typedef (type);
+  struct type *resolved_type;
+
+  if (!is_dynamic_type (real_type))
+    return type;
+
+  resolved_type = resolve_dynamic_bounds (type, addr);
+
+  return resolved_type;
+}
+
 /* Find the real type of TYPE.  This function returns the real type,
    after removing all layers of typedefs, and completing opaque or stub
    types.  Completion changes the TYPE argument, but stripping of
@@ -1760,45 +1911,6 @@ check_typedef (struct type *type)
 	{
 	  /* Nothing we can do.  */
 	}
-      else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
-	       && TYPE_NFIELDS (type) == 1
-	       && (TYPE_CODE (range_type = TYPE_INDEX_TYPE (type))
-		   == TYPE_CODE_RANGE))
-	{
-	  /* Now recompute the length of the array type, based on its
-	     number of elements and the target type's length.
-	     Watch out for Ada null Ada arrays where the high bound
-	     is smaller than the low bound.  */
-	  const LONGEST low_bound = TYPE_LOW_BOUND (range_type);
-	  const LONGEST high_bound = TYPE_HIGH_BOUND (range_type);
-	  ULONGEST len;
-
-	  if (high_bound < low_bound)
-	    len = 0;
-	  else
-	    {
-	      /* For now, we conservatively take the array length to be 0
-		 if its length exceeds UINT_MAX.  The code below assumes
-		 that for x < 0, (ULONGEST) x == -x + ULONGEST_MAX + 1,
-		 which is technically not guaranteed by C, but is usually true
-		 (because it would be true if x were unsigned with its
-		 high-order bit on).  It uses the fact that
-		 high_bound-low_bound is always representable in
-		 ULONGEST and that if high_bound-low_bound+1 overflows,
-		 it overflows to 0.  We must change these tests if we 
-		 decide to increase the representation of TYPE_LENGTH
-		 from unsigned int to ULONGEST.  */
-	      ULONGEST ulow = low_bound, uhigh = high_bound;
-	      ULONGEST tlen = TYPE_LENGTH (target_type);
-
-	      len = tlen * (uhigh - ulow + 1);
-	      if (tlen == 0 || (len / tlen - 1 + ulow) != uhigh 
-		  || len > UINT_MAX)
-		len = 0;
-	    }
-	  TYPE_LENGTH (type) = len;
-	  TYPE_TARGET_STUB (type) = 0;
-	}
       else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
 	{
 	  TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index e91ab97..97411d1 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1,3 +1,4 @@
+
 /* Internal type definitions for GDB.
 
    Copyright (C) 1992-2014 Free Software Foundation, Inc.
@@ -1682,6 +1683,15 @@ extern void get_unsigned_type_max (struct type *, ULONGEST *);
 
 extern void get_signed_type_minmax (struct type *, LONGEST *, LONGEST *);
 
+/* * Resolve all dynamic values of a type e.g. array bounds to static values.
+   ADDR specifies the location of the variable the type is bound to.
+   If TYPE has no dynamic properties return TYPE; otherwise a new type with
+   static properties is returned.  */
+extern struct type *resolve_dynamic_type (struct type *type, CORE_ADDR addr);
+
+/* * Predicate if the type has dynamic values, which are not resolved yet.  */
+extern int is_dynamic_type (struct type *type);
+
 extern struct type *check_typedef (struct type *);
 
 #define CHECK_TYPEDEF(TYPE)			\
diff --git a/gdb/valops.c b/gdb/valops.c
index 1fa188f..46e2639 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -900,7 +900,10 @@ value_one (struct type *type)
   return val;
 }
 
-/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.  */
+/* Helper function for value_at, value_at_lazy, and value_at_lazy_stack.
+   The type of the created value may differ from the passed type TYPE.
+   Make sure to retrieve the returned values's new type after this call
+   e.g. in case the type is a variable length array.  */
 
 static struct value *
 get_value_at (struct type *type, CORE_ADDR addr, int lazy)
@@ -925,7 +928,10 @@ get_value_at (struct type *type, CORE_ADDR addr, int lazy)
    value_at_lazy instead.  value_at_lazy simply records the address of
    the data and sets the lazy-evaluation-required flag.  The lazy flag
    is tested in the value_contents macro, which is used if and when
-   the contents are actually required.
+   the contents are actually required.  The type of the created value
+   may differ from the passed type TYPE.  Make sure to retrieve the
+   returned values's new type after this call e.g. in case the type
+   is a variable length array.
 
    Note: value_at does *NOT* handle embedded offsets; perform such
    adjustments before or after calling it.  */
@@ -936,7 +942,10 @@ value_at (struct type *type, CORE_ADDR addr)
   return get_value_at (type, addr, 0);
 }
 
-/* Return a lazy value with type TYPE located at ADDR (cf. value_at).  */
+/* Return a lazy value with type TYPE located at ADDR (cf. value_at).
+   The type of the created value may differ from the passed type TYPE.
+   Make sure to retrieve the returned values's new type after this call
+   e.g. in case the type is a variable length array.  */
 
 struct value *
 value_at_lazy (struct type *type, CORE_ADDR addr)
diff --git a/gdb/value.c b/gdb/value.c
index 27043ee..9cc5e44 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3319,32 +3319,39 @@ value_from_ulongest (struct type *type, ULONGEST num)
 
 
 /* Create a value representing a pointer of type TYPE to the address
-   ADDR.  */
+   ADDR.  The type of the created value may differ from the passed
+   type TYPE. Make sure to retrieve the returned values's new type
+   after this call e.g. in case of an variable length array.  */
+
 struct value *
 value_from_pointer (struct type *type, CORE_ADDR addr)
 {
-  struct value *val = allocate_value (type);
+  struct type *resolved_type = resolve_dynamic_type (type, addr);
+  struct value *val = allocate_value (resolved_type);
 
-  store_typed_address (value_contents_raw (val), check_typedef (type), addr);
+  store_typed_address (value_contents_raw (val),
+		       check_typedef (resolved_type), addr);
   return val;
 }
 
 
 /* Create a value of type TYPE whose contents come from VALADDR, if it
    is non-null, and whose memory address (in the inferior) is
-   ADDRESS.  */
+   ADDRESS.  The type of the created value may differ from the passed
+   type TYPE.  Make sure to retrieve values new type after this call.  */
 
 struct value *
 value_from_contents_and_address (struct type *type,
 				 const gdb_byte *valaddr,
 				 CORE_ADDR address)
 {
+  struct type *resolved_type = resolve_dynamic_type (type, address);
   struct value *v;
 
   if (valaddr == NULL)
-    v = allocate_value_lazy (type);
+    v = allocate_value_lazy (resolved_type);
   else
-    v = value_from_contents (type, valaddr);
+    v = value_from_contents (resolved_type, valaddr);
   set_value_address (v, address);
   VALUE_LVAL (v) = lval_memory;
   return v;
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [vla v7 pushed] Re: [PATCH v6 00/15] Please have a final look
  2014-04-14  8:34               ` Agovic, Sanimir
@ 2014-04-14 17:13                 ` Joel Brobecker
  2014-04-14 17:13                   ` [PATCH 08/12] vla: evaluate operand of sizeof if its type is a vla Joel Brobecker
                                     ` (12 more replies)
  0 siblings, 13 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:13 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

> Keith, Joel, all, sorry for causing any inconvenience and thanks to
> you both for taking care of the issue on Friday.

No worries - it can happen to anyone.

> The root cause was this code fragment below. It was in my repo and I
> git-amend it accidently as I was playing around with an alternative to
> solve the pointer-to-vla issue.
> 
> @@ -2985,7 +2984,6 @@ evaluate_subexp_with_coercion (struct expression *exp,
>         {
>           (*pos) += 4;
>           val = address_of_variable (var, exp->elts[pc + 1].block);
> -         type = value_type (val);
>           return value_cast (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
>                              val);

OK. That indeed solved the regressions outside of gdb.ada, so thanks
a lot for that. It saved me a ton of time not having to investigate
this issue.

This did not solve, on the other hand, the regressions with gdb.ada,
which turned out to be caused by a discrepancy between is_dynamic_type
which considers references to dynamic arrays as being dynamic, and
resolve_dynamic_bounds, which was handling the case of typedefs OK,
but otherwise expected the type to be an array type via the following
assert (which allowed us to find the bug, btw, so well placed one!):

  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);

So, when you have code like the following (resolve_dynamic_type)...

  if (!is_dynamic_type (real_type))
    return type;

  resolved_type = resolve_dynamic_bounds (type, addr);

... it is possible for a reference to dynamic array to get through
the check and then be passed to resolve_dynamic_bounds.

I ammended your patch as follow, essentially making resolve_dynamic_bounds
handle reference types as well:

| --- a/gdb/gdbtypes.c
| +++ b/gdb/gdbtypes.c
| @@ -40,6 +40,7 @@
|  #include "cp-support.h"
|  #include "bcache.h"
|  #include "dwarf2loc.h"
| +#include "gdbcore.h"
|  
|  /* Initialize BADNESS constants.  */
|  
| @@ -1665,6 +1666,16 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
|        return copy;
|      }
|  
| +  if (TYPE_CODE (type) == TYPE_CODE_REF)
| +    {
| +      struct type *copy = copy_type (type);
| +      CORE_ADDR target_addr = read_memory_typed_address (addr, type);
| +
| +      TYPE_TARGET_TYPE (copy)
| +	= resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), target_addr);
| +      return copy;
| +    }
| +
|    gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
|  
|    elt_type = type;

I re-tested everything after making those changes, and everything
seems to be clean, now, so I pushed your patch series. In the process,
I had to fix a number of little nits, mostly related to the ChangeLog
file and the revision logs. From memory:

  - ChangeLog: The entries, when still part of the commit, were
    not located at the start of the ChangeLog, and the date still
    refered to the 11th. It's easier, IMO, to manipulate commits
    without ChangeLog entries, and to add them at the very last
    minute, when just about to push to the official repo. But
    some tips on how to management have been also shared on the gdb@
    mailing-list as well as on various blogs.

  - Some testsuite/ChangeLog entries were incorrect, missing
    the name of the gdb.[...] subdirectory in the file name,
    of mentioning it as the path to the (nonexistant) ChangeLog
    file.

  - The revision logs had traces of "Conflict:" sections, which
    are automatically added when you do a cherry-pick, I think,
    which results in a conflict that you resolve before commit.
    I removed those.

I think that's about it. Let's hope that we're in the clear now! :)

For the record, patch 01 and 02...

        [PATCH 01/12] type: add c99 variable length array support
        [PATCH 02/12] vla: enable sizeof operator to work with variable

... when individually tested on x86_64-linux, and then I only ran
the testsuite after applying the remaining commits. But I did test
each one of them in sequence last Friday, so I didn't see a reason
to do it again.

> 
> In addition I refactored the code for handling the sizeof operator to
> match Keith latest fix for PR c++/16675 (245a5f0) in:
> 
>   #02 vla: enable sizeof operator to work with variable length arrays
> 
> I used Jans diffgdb script to compare two runs (pre-/post vla) of 'make
> check' and now the patch series is free of regression as it should be.
> 
> You will find the latest patch series at:
> 
>   https://github.com/intel-gdb/vla/tree/vla-c99


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 10/12] test: evaluate pointers to C99 vla correctly.
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (8 preceding siblings ...)
  2014-04-14 17:14                   ` [PATCH 12/12] test: add mi vla test Joel Brobecker
@ 2014-04-14 17:14                   ` Joel Brobecker
  2014-04-14 17:14                   ` [PATCH 11/12] test: basic c99 vla tests for C primitives Joel Brobecker
                                     ` (2 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

gdb/testsuite/ChangeLog:

	* gdb.base/vla-ptr.c: New file.
	* gdb.base/vla-ptr.exp: New file.
---
 gdb/testsuite/ChangeLog            |  5 ++++
 gdb/testsuite/gdb.base/vla-ptr.c   | 58 ++++++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/vla-ptr.exp | 41 +++++++++++++++++++++++++++
 3 files changed, 104 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/vla-ptr.c
 create mode 100644 gdb/testsuite/gdb.base/vla-ptr.exp

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 2882a74..83071a2 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* gdb.base/vla-ptr.c: New file.
+	* gdb.base/vla-ptr.exp: New file.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* gdb.dwarf2/count.exp: New file.
 
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
diff --git a/gdb/testsuite/gdb.base/vla-ptr.c b/gdb/testsuite/gdb.base/vla-ptr.c
new file mode 100644
index 0000000..54d04a6
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-ptr.c
@@ -0,0 +1,58 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 5
+
+void
+foo (int n, int vla_ptr[n])
+{
+  return;         /* foo_bp */
+}
+
+void
+bar (int *vla_ptr)
+{
+  return;         /* bar_bp */
+}
+
+void
+vla_func (int n)
+{
+  int vla[n];
+  typedef int typedef_vla[n];
+  typedef_vla td_vla;
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      vla[i] = 2+i;
+      td_vla[i] = 4+i;
+    }
+
+  foo(n, vla);
+  bar(vla);
+
+  return;         /* vla_func_bp */
+}
+
+int
+main (void)
+{
+  vla_func(SIZE);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/vla-ptr.exp b/gdb/testsuite/gdb.base/vla-ptr.exp
new file mode 100644
index 0000000..56c9d5b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-ptr.exp
@@ -0,0 +1,41 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+set sizeof_int [get_sizeof "int" 4]
+
+# Check that VLA passed to function (pointer) points to the first element.
+gdb_breakpoint [gdb_get_line_number "foo_bp"]
+gdb_continue_to_breakpoint "foo_bp"
+gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (foo)"
+gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (foo)"
+
+gdb_breakpoint [gdb_get_line_number "bar_bp"]
+gdb_continue_to_breakpoint "bar_bp"
+gdb_test "print vla_ptr" "\\\(int \\\*\\\) $hex" "print vla_ptr (bar)"
+gdb_test "print *vla_ptr" " = 2" "print *vla_ptr (bar)"
+
+gdb_breakpoint [gdb_get_line_number "vla_func_bp"]
+gdb_continue_to_breakpoint "vla_func_bp"
+gdb_test "print td_vla" " = \\\{4, 5, 6, 7, 8\\\}" "print td_vla"
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 12/12] test: add mi vla test
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (7 preceding siblings ...)
  2014-04-14 17:13                   ` [PATCH 03/12] vla: enable sizeof operator for indirection Joel Brobecker
@ 2014-04-14 17:14                   ` Joel Brobecker
  2014-04-14 17:14                   ` [PATCH 10/12] test: evaluate pointers to C99 vla correctly Joel Brobecker
                                     ` (3 subsequent siblings)
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

testsuite/ChangeLog:

	* gdb.mi/mi-vla-c99.exp: New file.
	* gdb.mi/vla.c: New file.
---
 gdb/testsuite/ChangeLog             |  5 +++
 gdb/testsuite/gdb.mi/mi-vla-c99.exp | 82 +++++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.mi/vla.c          | 37 +++++++++++++++++
 3 files changed, 124 insertions(+)
 create mode 100644 gdb/testsuite/gdb.mi/mi-vla-c99.exp
 create mode 100644 gdb/testsuite/gdb.mi/vla.c

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 765ff65..0a106ac 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* gdb.mi/mi-vla-c99.exp: New file.
+	* gdb.mi/vla.c: New file.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* gdb.base/vla-datatypes.c: New file.
 	* gdb.base/vla-datatypes.exp: New file.
 
diff --git a/gdb/testsuite/gdb.mi/mi-vla-c99.exp b/gdb/testsuite/gdb.mi/mi-vla-c99.exp
new file mode 100644
index 0000000..618e8ab
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/mi-vla-c99.exp
@@ -0,0 +1,82 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# Contributed by Intel Corp. <keven.boell@intel.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Verify that, using the MI, we can evaluate a simple C Variable Length
+# Array (VLA).
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+standard_testfile vla.c
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" \
+                  "${binfile}" executable {debug}] != "" } {
+     untested mi-vla-basics.exp
+     return -1
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+set bp_lineno [gdb_get_line_number "vla-filled"]
+
+mi_create_breakpoint "-t vla.c:$bp_lineno" 1 "del" "func" \
+             ".*vla.c" $bp_lineno $hex \
+             "insert breakpoint at line $bp_lineno after vla is filled"
+mi_run_cmd
+mi_expect_stop "breakpoint-hit" "func" "\{name=\"n\",value=\"5\"\}" \
+               ".*vla.c" "$bp_lineno" { "" "disp=\"del\"" } \
+               "run to breakpoint at line $bp_lineno"
+
+mi_gdb_test "500-data-evaluate-expression vla" \
+    "500\\^done,value=\"\\{0, 1, 2, 3, 4\\}\"" "evaluate complete vla"
+
+mi_gdb_test "501-data-evaluate-expression vla\[0\]" \
+    "501\\^done,value=\"0\"" "evaluate vla\[0\]"
+
+mi_gdb_test "502-data-evaluate-expression vla\[2\]" \
+    "502\\^done,value=\"2\"" "evaluate vla\[2\]"
+
+mi_gdb_test "503-data-evaluate-expression vla\[4\]" \
+    "503\\^done,value=\"4\"" "evaluate vla\[4\]"
+
+mi_create_varobj_checked vla vla "int \\\[5\\\]" \
+                                 "create local variable vla"
+
+mi_gdb_test "504-var-info-type vla" \
+    "504\\^done,type=\"int \\\[5\\\]\"" \
+    "info type variable vla"
+
+mi_gdb_test "505-var-show-format vla" \
+    "505\\^done,format=\"natural\"" \
+    "show format variable vla"
+
+mi_gdb_test "506-var-evaluate-expression vla" \
+    "506\\^done,value=\"\\\[5\\\]\"" \
+    "eval variable vla"
+
+mi_list_array_varobj_children "vla" "5" "int" \
+    "get children of vla"
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/vla.c b/gdb/testsuite/gdb.mi/vla.c
new file mode 100644
index 0000000..a26244b
--- /dev/null
+++ b/gdb/testsuite/gdb.mi/vla.c
@@ -0,0 +1,37 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Contributed by Intel Corp. <keven.boell@intel.com>
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+func (int n)
+{
+  int vla[n], i;
+
+  for (i = 0; i < n; i++)
+    vla[i] = i;
+
+  return n;                 /* vla-filled */
+}
+
+int
+main (void)
+{
+  func (5);
+
+  return 0;
+}
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 09/12] test: cover subranges with present DW_AT_count attribute
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (10 preceding siblings ...)
  2014-04-14 17:14                   ` [PATCH 11/12] test: basic c99 vla tests for C primitives Joel Brobecker
@ 2014-04-14 17:14                   ` Joel Brobecker
  2014-04-14 17:36                   ` [vla v7 pushed] Re: [PATCH v6 00/15] Please have a final look Agovic, Sanimir
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

The dwarf attribute DW_AT_count specifies the elements of a subrange.
This test covers subranges with present count but absent upper bound
attribute, both with static and dynamic attribute values.

testsuite/ChangeLog:

	* gdb.dwarf2/count.exp: New file.
---
 gdb/testsuite/ChangeLog            |   4 ++
 gdb/testsuite/gdb.dwarf2/count.exp | 125 +++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+)
 create mode 100644 gdb/testsuite/gdb.dwarf2/count.exp

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 7d0bd2e..2882a74 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* gdb.dwarf2/count.exp: New file.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* gdb.base/vla-sideeffect.c: New file.
 	* gdb.base/vla-sideeffect.exp: New file.
 
diff --git a/gdb/testsuite/gdb.dwarf2/count.exp b/gdb/testsuite/gdb.dwarf2/count.exp
new file mode 100644
index 0000000..d52fa62
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/count.exp
@@ -0,0 +1,125 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Tests to cover DW_AT_count attribute in subranges.
+
+load_lib dwarf.exp
+
+# Only run on targets which support dwarf and gas.
+if { ![dwarf2_support] } {
+    return 0
+}
+
+standard_testfile main.c count.S
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    cu {} {
+	compile_unit {{language @DW_LANG_C99}} {
+	    declare_labels char_label array_label array_label2 static_array_label
+
+	    char_label: base_type {
+		{name char}
+		{encoding @DW_ATE_signed}
+		{byte_size 1 DW_FORM_sdata}
+	    }
+
+	    array_label: array_type {
+		{type :$char_label}
+	    } {
+		subrange_type {
+		    {count {DW_OP_lit5} SPECIAL_expr}
+		    {type :$char_label}
+		}
+	    }
+
+	    array_label2: array_type {
+		{type :$char_label}
+	    } {
+		subrange_type {
+		    {count {DW_OP_lit1} SPECIAL_expr}
+		    {type :$char_label}
+		}
+	    }
+
+	    static_array_label: array_type {
+		{type :$char_label}
+	    } {
+		subrange_type {
+		    {count 5 DW_FORM_sdata}
+		    {type :$char_label}
+		}
+	    }
+
+	    DW_TAG_variable {
+		{name array2}
+		{type :$array_label2}
+		{const_value 65 DW_FORM_udata}
+	    }
+
+	    DW_TAG_variable {
+		{name array}
+		{type :$array_label}
+		{const_value hello DW_FORM_block1}
+	    }
+
+	    DW_TAG_variable {
+		{name static_array}
+		{type :$static_array_label}
+		{const_value world DW_FORM_block1}
+	    }
+	}
+    }
+}
+
+if { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
+	  object {nodebug}] != "" } {
+    return -1
+}
+
+if { [gdb_compile $asm_file ${binfile}2.o object {nodebug}] != "" } {
+    return -1
+}
+
+if { [gdb_compile [list ${binfile}1.o ${binfile}2.o] \
+	  "${binfile}" executable {}] != "" } {
+    return -1
+}
+
+global GDBFLAGS
+set saved_gdbflags $GDBFLAGS
+set GDBFLAGS [concat $GDBFLAGS " -readnow"]
+clean_restart ${testfile}
+set GDBFLAGS $saved_gdbflags
+
+if ![runto_main] {
+    perror "couldn't run to main"
+    return -1
+}
+
+gdb_test "ptype array" "type = char \\\[5\\\]" "ptype array"
+gdb_test "whatis array" "type = char \\\[5\\\]" "whatis array"
+gdb_test "print array" " = \"hello\"" "print array"
+gdb_test "print sizeof array" " = 5" "print sizeof array"
+
+gdb_test "ptype array2" "type = char \\\[1\\\]" "ptype array"
+gdb_test "whatis array2" "type = char \\\[1\\\]" "whatis array"
+gdb_test "print array2" " = \"A\"" "print array"
+gdb_test "print sizeof array2" " = 1" "print sizeof array"
+
+gdb_test "ptype static_array" "type = char \\\[5\\\]" "ptype static_array"
+gdb_test "whatis static_array" "type = char \\\[5\\\]" "whatis static_array"
+gdb_test "print static_array" " = \"world\"" "print static_array"
+gdb_test "print sizeof static_array" " = 5" "print sizeof static_array"
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 11/12] test: basic c99 vla tests for C primitives
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (9 preceding siblings ...)
  2014-04-14 17:14                   ` [PATCH 10/12] test: evaluate pointers to C99 vla correctly Joel Brobecker
@ 2014-04-14 17:14                   ` Joel Brobecker
  2014-04-14 17:14                   ` [PATCH 09/12] test: cover subranges with present DW_AT_count attribute Joel Brobecker
  2014-04-14 17:36                   ` [vla v7 pushed] Re: [PATCH v6 00/15] Please have a final look Agovic, Sanimir
  12 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-14 17:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

From: Sanimir Agovic <sanimir.agovic@intel.com>

gdb/testsuite/ChangeLog:

	* gdb.base/vla-datatypes.c: New file.
	* gdb.base/vla-datatypes.exp: New file.
---
 gdb/testsuite/ChangeLog                  |   5 ++
 gdb/testsuite/gdb.base/vla-datatypes.c   |  86 +++++++++++++++++++
 gdb/testsuite/gdb.base/vla-datatypes.exp | 139 +++++++++++++++++++++++++++++++
 3 files changed, 230 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/vla-datatypes.c
 create mode 100644 gdb/testsuite/gdb.base/vla-datatypes.exp

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 83071a2..765ff65 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
 
+	* gdb.base/vla-datatypes.c: New file.
+	* gdb.base/vla-datatypes.exp: New file.
+
+2014-04-14  Sanimir Agovic  <sanimir.agovic@intel.com>
+
 	* gdb.base/vla-ptr.c: New file.
 	* gdb.base/vla-ptr.exp: New file.
 
diff --git a/gdb/testsuite/gdb.base/vla-datatypes.c b/gdb/testsuite/gdb.base/vla-datatypes.c
new file mode 100644
index 0000000..51e342e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-datatypes.c
@@ -0,0 +1,86 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#define SIZE 5
+
+struct foo
+{
+  int a;
+};
+
+typedef struct bar
+{
+  int x;
+  struct foo y;
+} BAR;
+
+void
+vla_factory (int n)
+{
+  int             int_vla[n];
+  unsigned int    unsigned_int_vla[n];
+  double          double_vla[n];
+  float           float_vla[n];
+  long            long_vla[n];
+  unsigned long   unsigned_long_vla[n];
+  char            char_vla[n];
+  short           short_vla[n];
+  unsigned short  unsigned_short_vla[n];
+  unsigned char   unsigned_char_vla[n];
+  struct foo      foo_vla[n];
+  BAR             bar_vla[n];
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      int_vla[i] = i*2;
+      unsigned_int_vla[i] = i*2;
+      double_vla[i] = i/2.0;
+      float_vla[i] = i/2.0f;
+      long_vla[i] = i*2;
+      unsigned_long_vla[i] = i*2;
+      char_vla[i] = 'A';
+      short_vla[i] = i*2;
+      unsigned_short_vla[i] = i*2;
+      unsigned_char_vla[i] = 'A';
+      foo_vla[i].a = i*2;
+      bar_vla[i].x = i*2;
+      bar_vla[i].y.a = i*2;
+    }
+
+  size_t int_size        = sizeof(int_vla);     /* vlas_filled */
+  size_t uint_size       = sizeof(unsigned_int_vla);
+  size_t double_size     = sizeof(double_vla);
+  size_t float_size      = sizeof(float_vla);
+  size_t long_size       = sizeof(long_vla);
+  size_t char_size       = sizeof(char_vla);
+  size_t short_size      = sizeof(short_vla);
+  size_t ushort_size     = sizeof(unsigned_short_vla);
+  size_t uchar_size      = sizeof(unsigned_char_vla);
+  size_t foo_size        = sizeof(foo_vla);
+  size_t bar_size        = sizeof(bar_vla);
+
+  return;                                 /* break_end_of_vla_factory */
+}
+
+int
+main (void)
+{
+  vla_factory(SIZE);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/vla-datatypes.exp b/gdb/testsuite/gdb.base/vla-datatypes.exp
new file mode 100644
index 0000000..8247658
--- /dev/null
+++ b/gdb/testsuite/gdb.base/vla-datatypes.exp
@@ -0,0 +1,139 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "vlas_filled"]
+gdb_continue_to_breakpoint "vlas_filled"
+
+# Check the values of VLA's.
+gdb_test "print int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print int_vla"
+gdb_test "print unsigned_int_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print unsigned_int_vla"
+gdb_test "print double_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
+         "print double_vla"
+gdb_test "print float_vla" " = \\\{0, 0.5, 1, 1.5, 2\\\}" \
+         "print float_vla"
+gdb_test "print long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print long_vla"
+gdb_test "print unsigned_long_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print unsigned_long_vla"
+gdb_test "print char_vla" " = \"AAAAA\"" \
+         "print char_vla"
+gdb_test "print short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print short_vla"
+gdb_test "print unsigned_short_vla" " = \\\{0, 2, 4, 6, 8\\\}" \
+         "print unsigned_short_vla"
+gdb_test "print unsigned_char_vla" " = \"AAAAA\"" \
+         "print unsigned_char_vla"
+gdb_test "print foo_vla" \
+         "\\\{\\\{a = 0\\\}, \\\{a = 2\\\}, \\\{a = 4\\\}, \\\{a = 6\\\}, \\\{a = 8\\\}\\\}" \
+         "print foo_vla"
+gdb_test "print bar_vla" \
+         "\\\{\\\{x = 0, y = \\\{a = 0\\\}\\\}, \\\{x = 2, y = \\\{a = 2\\\}\\\}, \\\{x = 4, y = \\\{a = 4\\\}\\\}, \\\{x = 6, y = \\\{a = 6\\\}\\\}, \\\{x = 8, y = \\\{a = 8\\\}\\\}\\\}" \
+         "print bar_vla"
+
+# Check whatis of VLA's.
+gdb_test "whatis int_vla" "type = int \\\[5\\\]" "whatis int_vla"
+gdb_test "whatis unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
+         "whatis unsigned_int_vla"
+gdb_test "whatis double_vla" "type = double \\\[5\\\]" "whatis double_vla"
+gdb_test "whatis float_vla" "type = float \\\[5\\\]" "whatis float_vla"
+gdb_test "whatis long_vla" "type = long( int)? \\\[5\\\]" "whatis long_vla"
+gdb_test "whatis unsigned_long_vla" \
+         "type = (long unsigned int|unsigned long) \\\[5\\\]" \
+         "whatis unsigned_long_vla"
+gdb_test "whatis char_vla" "type = char \\\[5\\\]" "whatis char_vla"
+gdb_test "whatis short_vla" "type = short( int)? \\\[5\\\]" \
+         "whatis short_vla"
+gdb_test "whatis unsigned_short_vla" \
+         "type = (short unsigned int|unsigned short) \\\[5\\\]" \
+         "whatis unsigned_short_vla"
+gdb_test "whatis unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
+         "whatis unsigned_char_vla"
+gdb_test "whatis foo_vla" "type = struct foo \\\[5\\\]" "whatis foo_vla"
+gdb_test "whatis bar_vla" "type = BAR \\\[5\\\]" "whatis bar_vla"
+
+# Check ptype of VLA's.
+gdb_test "ptype int_vla" "type = int \\\[5\\\]" "ptype int_vla"
+gdb_test "ptype unsigned_int_vla" "type = unsigned int \\\[5\\\]" \
+         "ptype unsigned_int_vla"
+gdb_test "ptype double_vla" "type = double \\\[5\\\]" "ptype double_vla"
+gdb_test "ptype float_vla" "type = float \\\[5\\\]" "ptype float_vla"
+gdb_test "ptype long_vla" "type = long( int)? \\\[5\\\]" "ptype long_vla"
+gdb_test "ptype unsigned_long_vla" "type = unsigned long \\\[5\\\]" \
+         "ptype unsigned_long_vla"
+gdb_test "ptype char_vla" "type = char \\\[5\\\]" "ptype char_vla"
+gdb_test "ptype short_vla" "type = short( int)? \\\[5\\\]" \
+         "ptype short_vla"
+gdb_test "ptype unsigned_short_vla" "type = unsigned short \\\[5\\\]" \
+         "ptype unsigned_short_vla"
+gdb_test "ptype unsigned_char_vla" "type = unsigned char \\\[5\\\]" \
+         "ptype unsigned_char_vla"
+gdb_test "ptype foo_vla" "type = struct foo {\r\n\\s+int a;\r\n} \\\[5\\\]" \
+         "ptype foo_vla"
+gdb_test "ptype bar_vla" \
+         "type = struct bar {\r\n\\s+int x;\r\n\\s+struct foo y;\r\n} \\\[5\\\]" \
+         "ptype bar_vla"
+
+# Check the size of the VLA's.
+gdb_breakpoint [gdb_get_line_number "break_end_of_vla_factory"]
+gdb_continue_to_breakpoint "break_end_of_vla_factory"
+gdb_test "print int_size == sizeof(int_vla)" " = 1" "size of int_vla"
+gdb_test "print uint_size == sizeof(unsigned_int_vla)" " = 1" \
+         "size of unsigned_int_vla"
+gdb_test "print double_size == sizeof(double_vla)" " = 1" \
+         "size of double_vla"
+gdb_test "print float_size == sizeof(float_vla)" " = 1" \
+         "size of float_vla"
+gdb_test "print long_size == sizeof(long_vla)" " = 1" \
+         "size of long_vla"
+gdb_test "print char_size == sizeof(char_vla)" " = 1" \
+         "size of char_vla"
+gdb_test "print short_size == sizeof(short_vla)" " = 1" \
+         "size of short_vla"
+gdb_test "print ushort_size == sizeof(unsigned_short_vla)" " = 1" \
+         "size of unsigned_short_vla"
+gdb_test "print uchar_size == sizeof(unsigned_char_vla)" " = 1" \
+         "size of unsigned_char_vla"
+gdb_test "print foo_size == sizeof(foo_vla)" " = 1" "size of foo_vla"
+gdb_test "print bar_size == sizeof(bar_vla)" " = 1" "size of bar_vla"
+
+# Check side effects for sizeof argument.
+set sizeof_int [get_sizeof "int" 4]
+gdb_test_no_output  "set variable int_vla\[0\] = 42" \
+                    "set variable int_vla\[0\] = 42"
+
+gdb_test "print sizeof (++int_vla\[0\])" " = ${sizeof_int}" \
+         "print sizeof (++int_vla\[0\])"
+gdb_test "print int_vla\[0\]" " = 42" \
+         "print int_vla\[0\] - sizeof no side effects"
+
+gdb_test "ptype ++int_vla\[0\]" "type = int" "ptype ++int_vla\[0\]"
+gdb_test "print int_vla\[0\]" " = 42" \
+         "print int_vla\[0\] - ptype no side effects"
+
+gdb_test "whatis ++int_vla\[0\]" "type = int" "whatis ++int_vla\[0\]"
+gdb_test "print int_vla\[0\]" " = 42" \
+         "print int_vla\[0\] - whatis no side effects"
-- 
1.8.3.2

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [vla v7 pushed] Re: [PATCH v6 00/15] Please have a final look
  2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
                                     ` (11 preceding siblings ...)
  2014-04-14 17:14                   ` [PATCH 09/12] test: cover subranges with present DW_AT_count attribute Joel Brobecker
@ 2014-04-14 17:36                   ` Agovic, Sanimir
  12 siblings, 0 replies; 46+ messages in thread
From: Agovic, Sanimir @ 2014-04-14 17:36 UTC (permalink / raw)
  To: 'Joel Brobecker', gdb-patches

> I ammended your patch as follow, essentially making resolve_dynamic_bounds
> handle reference types as well:
> 
Many thanks to you Joel.

 -Sanimir

Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH 01/12] type: add c99 variable length array support
  2014-04-14 17:13                   ` [PATCH 01/12] type: add c99 variable length array support Joel Brobecker
@ 2014-04-18 19:06                     ` Joel Brobecker
  0 siblings, 0 replies; 46+ messages in thread
From: Joel Brobecker @ 2014-04-18 19:06 UTC (permalink / raw)
  To: gdb-patches; +Cc: Sanimir Agovic

Hi Sanimir, (and dwarf2* experts!)

Just looking through the code again, I found:

> +/* Evaluates a dwarf expression and stores the result in VAL, expecting
> +   that the dwarf expression only produces a single CORE_ADDR.  ADDR is a
> +   context (location of a variable) and might be needed to evaluate the
> +   location expression.
> +   Returns 1 on success, 0 otherwise.   */
> +
> +static int
> +dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
> +			   CORE_ADDR addr, CORE_ADDR *valp)

The "addr" parameter is unused in this case, and I am hoping that
this would be normal. Re-reading location expressions, I don't see
a lot of cases that could happen, and none of them see to require
an address to start with). What do you think?

The reason why I ended up looking at this code is because the current
interface for resolving bounds needs an address. When you work from
a value, there could be no address (Eg. if the value is inside a
register, or its an lval_computed value). Currently, the interface
works works with types (resolve_dynamic_type(type+addr)), but it
would also be convenient to have a resolve_dynamic_value(value).

If we can remove that address, then a number of simplifications
can be made.  I'll take care of all required updates, but I was
wondering what your thoughts on this were...

Thanks!

> +{
> +  struct dwarf_expr_context *ctx;
> +  struct dwarf_expr_baton baton;
> +  struct objfile *objfile;
> +  struct cleanup *cleanup;
> +
> +  if (dlbaton == NULL || dlbaton->size == 0)
> +    return 0;
> +
> +  ctx = new_dwarf_expr_context ();
> +  cleanup = make_cleanup_free_dwarf_expr_context (ctx);
> +
> +  baton.frame = get_selected_frame (NULL);
> +  baton.per_cu = dlbaton->per_cu;
> +
> +  objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
> +
> +  ctx->gdbarch = get_objfile_arch (objfile);
> +  ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
> +  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
> +  ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
> +  ctx->funcs = &dwarf_expr_ctx_funcs;
> +  ctx->baton = &baton;
> +
> +  dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size);
> +
> +  switch (ctx->location)
> +    {
> +    case DWARF_VALUE_REGISTER:
> +    case DWARF_VALUE_MEMORY:
> +    case DWARF_VALUE_STACK:
> +      *valp = dwarf_expr_fetch_address (ctx, 0);
> +      if (ctx->location == DWARF_VALUE_REGISTER)
> +	*valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
> +      do_cleanups (cleanup);
> +      return 1;
> +    case DWARF_VALUE_LITERAL:
> +      *valp = extract_signed_integer (ctx->data, ctx->len,
> +				      gdbarch_byte_order (ctx->gdbarch));
> +      do_cleanups (cleanup);
> +      return 1;
> +      /* Unsupported dwarf values.  */
> +    case DWARF_VALUE_OPTIMIZED_OUT:
> +    case DWARF_VALUE_IMPLICIT_POINTER:
> +      break;
> +    }
> +
> +  do_cleanups (cleanup);
> +  return 0;

-- 
Joel

^ permalink raw reply	[flat|nested] 46+ messages in thread

* RE: [PATCH v6 00/15] Please have a final look
  2014-04-10 14:46   ` Joel Brobecker
@ 2014-04-22 15:33     ` Agovic, Sanimir
  2014-04-22 16:58       ` Eli Zaretskii
  0 siblings, 1 reply; 46+ messages in thread
From: Agovic, Sanimir @ 2014-04-22 15:33 UTC (permalink / raw)
  To: 'Joel Brobecker', 'Eli Zaretskii'; +Cc: gdb-patches, tromey

> I forgot - once the patch series is in, we will need a NEWS entry.
Is this NEWS entry OK?


    news: mention support for C99 variable length arrays

        * NEWS: Mention support for C99 variable length arrays.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 120b70b..b2fb9fa 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@
+2014-04-22  Sanimir Agovic  <sanimir.agovic@intel.com>
+
+       * NEWS: Mention support for C99 variable length arrays.
+
 2014-04-22  Nick Clifton  <nickc@redhat.com>

        * NEWS: Mention that ARM sim now supports tracing.
diff --git a/gdb/NEWS b/gdb/NEWS
index b72d64d..40d79a8 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -2,7 +2,10 @@
             (Organized release by release)

 *** Changes since GDB 7.7
- 
+
+* GDB supports printing and modifying of variable length automatic arrays
+  as specified in ISO C99.
+
 * The ARM simulator now supports instruction level tracing
   with or without disassembly.
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v6 00/15] Please have a final look
  2014-04-22 15:33     ` Agovic, Sanimir
@ 2014-04-22 16:58       ` Eli Zaretskii
  0 siblings, 0 replies; 46+ messages in thread
From: Eli Zaretskii @ 2014-04-22 16:58 UTC (permalink / raw)
  To: Agovic, Sanimir; +Cc: brobecker, gdb-patches, tromey

> From: "Agovic, Sanimir" <sanimir.agovic@intel.com>
> CC: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>,
> 	"tromey@redhat.com" <tromey@redhat.com>
> Date: Tue, 22 Apr 2014 15:32:21 +0000
> 
> > I forgot - once the patch series is in, we will need a NEWS entry.
> Is this NEWS entry OK?
> 
> 
>     news: mention support for C99 variable length arrays
> 
>         * NEWS: Mention support for C99 variable length arrays.
> 
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 120b70b..b2fb9fa 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,7 @@
> +2014-04-22  Sanimir Agovic  <sanimir.agovic@intel.com>
> +
> +       * NEWS: Mention support for C99 variable length arrays.
> +
>  2014-04-22  Nick Clifton  <nickc@redhat.com>
> 
>         * NEWS: Mention that ARM sim now supports tracing.
> diff --git a/gdb/NEWS b/gdb/NEWS
> index b72d64d..40d79a8 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -2,7 +2,10 @@
>              (Organized release by release)
> 
>  *** Changes since GDB 7.7
> - 
> +
> +* GDB supports printing and modifying of variable length automatic arrays
> +  as specified in ISO C99.
> +

Yes, it's OK.

Thanks.

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2014-04-22 16:58 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-10 12:42 [PATCH v6 00/15] Please have a final look Sanimir Agovic
2014-04-10 12:42 ` [PATCH v6 01/15] refactoring: rename create_range_type to create_static_range_type Sanimir Agovic
2014-04-10 12:43 ` [PATCH v6 02/15] vla: introduce new bound type abstraction adapt uses Sanimir Agovic
2014-04-10 12:44 ` [PATCH v6 04/15] vla: enable sizeof operator to work with variable length arrays Sanimir Agovic
2014-04-10 12:44 ` [PATCH v6 03/15] type: add c99 variable length array support Sanimir Agovic
2014-04-10 14:21   ` Joel Brobecker
2014-04-10 12:45 ` [PATCH v6 05/15] vla: enable sizeof operator for indirection Sanimir Agovic
2014-04-10 12:46 ` [PATCH v6 06/15] vla: update type from newly created value Sanimir Agovic
2014-04-10 12:47 ` [PATCH v6 07/15] vla: print "variable length" for unresolved dynamic bounds Sanimir Agovic
2014-04-10 12:48 ` [PATCH v6 09/15] vla: resolve dynamic bounds if value contents is a constant byte-sequence Sanimir Agovic
2014-04-10 14:22   ` Joel Brobecker
2014-04-10 12:48 ` [PATCH v6 08/15] vla: support for DW_AT_count Sanimir Agovic
2014-04-10 12:49 ` [PATCH v6 11/15] test: cover subranges with present DW_AT_count attribute Sanimir Agovic
2014-04-10 12:49 ` [PATCH v6 10/15] vla: evaluate operand of sizeof if its type is a vla Sanimir Agovic
2014-04-10 14:31   ` Joel Brobecker
2014-04-10 12:50 ` [PATCH v6 12/15] test: multi-dimensional c99 vla Sanimir Agovic
2014-04-10 12:51 ` [PATCH v6 13/15] test: evaluate pointers to C99 vla correctly Sanimir Agovic
2014-04-10 12:52 ` [PATCH v6 14/15] test: basic c99 vla tests for C primitives Sanimir Agovic
2014-04-10 12:53 ` [PATCH v6 15/15] test: add mi vla test Sanimir Agovic
2014-04-10 14:39 ` [PATCH v6 00/15] Please have a final look Joel Brobecker
2014-04-10 14:46   ` Joel Brobecker
2014-04-22 15:33     ` Agovic, Sanimir
2014-04-22 16:58       ` Eli Zaretskii
2014-04-11 12:50   ` Agovic, Sanimir
2014-04-11 20:03     ` Keith Seitz
2014-04-11 20:27       ` Joel Brobecker
2014-04-11 20:33         ` Keith Seitz
2014-04-11 21:13           ` Joel Brobecker
2014-04-11 21:19             ` Keith Seitz
2014-04-11 22:33             ` Joel Brobecker
2014-04-14  8:34               ` Agovic, Sanimir
2014-04-14 17:13                 ` [vla v7 pushed] " Joel Brobecker
2014-04-14 17:13                   ` [PATCH 08/12] vla: evaluate operand of sizeof if its type is a vla Joel Brobecker
2014-04-14 17:13                   ` [PATCH 01/12] type: add c99 variable length array support Joel Brobecker
2014-04-18 19:06                     ` Joel Brobecker
2014-04-14 17:13                   ` [PATCH 07/12] vla: resolve dynamic bounds if value contents is a constant byte-sequence Joel Brobecker
2014-04-14 17:13                   ` [PATCH 02/12] vla: enable sizeof operator to work with variable length arrays Joel Brobecker
2014-04-14 17:13                   ` [PATCH 04/12] vla: update type from newly created value Joel Brobecker
2014-04-14 17:13                   ` [PATCH 05/12] vla: print "variable length" for unresolved dynamic bounds Joel Brobecker
2014-04-14 17:13                   ` [PATCH 06/12] vla: support for DW_AT_count Joel Brobecker
2014-04-14 17:13                   ` [PATCH 03/12] vla: enable sizeof operator for indirection Joel Brobecker
2014-04-14 17:14                   ` [PATCH 12/12] test: add mi vla test Joel Brobecker
2014-04-14 17:14                   ` [PATCH 10/12] test: evaluate pointers to C99 vla correctly Joel Brobecker
2014-04-14 17:14                   ` [PATCH 11/12] test: basic c99 vla tests for C primitives Joel Brobecker
2014-04-14 17:14                   ` [PATCH 09/12] test: cover subranges with present DW_AT_count attribute Joel Brobecker
2014-04-14 17:36                   ` [vla v7 pushed] Re: [PATCH v6 00/15] Please have a final look Agovic, Sanimir

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).