Author: laijx
Date: 2012-02-16 05:30:54 -0500 (Thu, 16 Feb 2012)
New Revision: 3874

Modified:
   trunk/osprey/wgen/wgen_dst.cxx
   trunk/osprey/wgen/wgen_expr.cxx
   trunk/osprey/wgen/wgen_expr.h
   trunk/osprey/wgen/wgen_spin_symbol.cxx
Log:
This patch is used to support GCC extension - variable length array in
struct (VLA/VLS). There are 3 major kinds of changes in the patch:
1. Set the static TY size of VLA/VLS from 0 to -1.
2. Change all component offset in wgen_expr.cxx from WN_OFFSET to WN*.
For constant offset, the operator of WN* is INTCONST. For variable
offset, it's an integer expression.
2. Wrap WN_CreateIload/WN_CreateIIStore/WN_CreateLdid/WN_CreateStid
for variable offset. If the offset is constant, the offset will be
attached onto the WN directly. Otherwise, an ADD node will be
generated for the address used by the load/store.

So far there are still several limitation on this patch:
1. don't support the copy between variable length object.
2. don't support passing the variable length object by parameter or
return value. 

Fix bug 933.
Fix bug 933.

Code Review by Gautam. Thanks.



Modified: trunk/osprey/wgen/wgen_dst.cxx
===================================================================
--- trunk/osprey/wgen/wgen_dst.cxx      2012-02-15 08:40:23 UTC (rev 3873)
+++ trunk/osprey/wgen/wgen_dst.cxx      2012-02-16 10:30:54 UTC (rev 3874)
@@ -836,12 +836,12 @@
     }
     else {
           if (gs_tree_code(type_size) != GS_INTEGER_CST) {
-            if (gs_tree_code(type_size) == GS_ARRAY_TYPE)
-              Fail_FmtAssertion ("Encountered VLA at line %d", lineno);
-            else
-              Fail_FmtAssertion ("VLA at line %d not currently implemented", 
-               lineno);
-            tsize = 0;
+            if (gs_tree_code(type_size) == GS_ARRAY_TYPE) {
+              tsize = 0;
+            }
+            else {
+              tsize = -1;
+            }
           }
           else
             tsize = gs_get_integer_value(type_size) / BITSPERBYTE;
@@ -1737,12 +1737,13 @@
    }
    else {
                if (gs_tree_code(type_size) != GS_INTEGER_CST) {
-                       if (gs_tree_code(type_tree) == GS_ARRAY_TYPE)
-                               DevWarn ("Encountered VLA at line %d", lineno);
-                       else
-                               Fail_FmtAssertion ("VLA at line %d not 
currently implemented", lineno);
+                       if (gs_tree_code(type_tree) == GS_ARRAY_TYPE) {
+                               tsize = 0;
+                       }
+                       else {
+                               tsize = -1;
+                       }
                        variable_size = TRUE;
-                       tsize = 0;
                }
                else
                        tsize = gs_get_integer_value(type_size) / BITSPERBYTE;

Modified: trunk/osprey/wgen/wgen_expr.cxx
===================================================================
--- trunk/osprey/wgen/wgen_expr.cxx     2012-02-15 08:40:23 UTC (rev 3873)
+++ trunk/osprey/wgen/wgen_expr.cxx     2012-02-16 10:30:54 UTC (rev 3874)
@@ -637,7 +637,7 @@
 
 static WN *WGEN_Expand_Ptr_To_Member_Func_Call_Expr (gs_t exp,
             TY_IDX nop_ty_idx, TYPE_ID rtype, TYPE_ID desc,
-            WN_OFFSET offset = 0, UINT field_id = 0);
+            WN* offset = NULL, UINT field_id = 0);
 
 // The words in 'buf' are in target order. Convert them to host order
 // in place. 'buf' is a two word array.
@@ -887,6 +887,146 @@
 } /* WGEN_Set_ST_Addr_Saved */
 
 
+/* to support VLA in structure in which the field offset isn't
+ * constant, a WN is generated to represent the offset.
+ * for normal structs, the WN is INTCONST and value if the offset.
+ * for VLA in structs, the WN is an INT expression.
+ */
+static WN*
+WGEN_Expand_Field_Offset(gs_t arg1) {
+  Is_True(gs_tree_code(arg1) == GS_FIELD_DECL,
+          ("WGEN_Expand_Field_Offset: arg1 is not field decl"));
+  WN* ofst = WGEN_Expand_Expr(gs_decl_field_offset(arg1));
+  WN* bit_ofst = WGEN_Expand_Expr(gs_decl_field_bit_offset(arg1));
+  TYPE_ID rtype = WN_rtype(ofst);
+  if (WN_operator(ofst) == OPR_INTCONST &&
+      WN_operator(bit_ofst) == OPR_INTCONST) {
+    INT64 ofst_value = (BITSPERBYTE * WN_const_val(ofst) + 
WN_const_val(bit_ofst))
+                       / BITSPERBYTE;
+    ofst = (ofst_value == 0) ? NULL : WN_Intconst(rtype, ofst_value);
+  }
+  else {
+    ofst = WN_Div(rtype,
+                  WN_Add(rtype,
+                         WN_Mpy(rtype, 
+                                ofst,
+                                WN_Intconst(rtype, BITSPERBYTE)),
+                         bit_ofst),
+                  WN_Intconst(rtype, BITSPERBYTE));
+  }
+  return ofst;
+}
+
+/* create a new address expression for given ST and offset
+ * if ofst is NULL or intconst, return LDA.
+ * otherwise, generate a add expression for the address.
+ */
+static WN*
+WGEN_Compose_Address(ST* st, WN* ofst, TY_IDX hl_ty, UINT32 field_id) {
+  if (ofst == NULL || WN_operator(ofst) == OPR_INTCONST) {
+    INT64 ofst_value = (ofst == NULL) ? 0 : WN_const_val(ofst);
+    return WN_CreateLda(OPR_LDA, Pointer_Mtype, MTYPE_V,
+                        ST_ofst(st) + ofst_value, Make_Pointer_Type(hl_ty), 
st, field_id);
+  }
+  else {
+    WN* lda = WN_CreateLda(OPR_LDA, Pointer_Mtype, MTYPE_V,
+                           ST_ofst(st), Make_Pointer_Type(hl_ty), st, 
field_id);
+    return WN_Binary(OPR_ADD, Pointer_Mtype, lda, ofst);  // TODO: use ILDA 
instrad
+  }
+}
+
+/* compose a new offset expression
+ * if given ofst1 and ofst2 are constants, generate a new INTCONST WN
+ * otherwise, generate a ADD expression
+ */
+static WN*
+WGEN_Compose_Offset(WN* ofst1, WN* ofst2) {
+  if (ofst1 == NULL)
+    return ofst2;
+  if (ofst2 == NULL)
+    return ofst1;
+  TYPE_ID rtype = WN_rtype(ofst1);
+  if (WN_operator(ofst1) == OPR_INTCONST && WN_operator(ofst2) == OPR_INTCONST)
+    return WN_Intconst(rtype, WN_const_val(ofst1) + WN_const_val(ofst2));
+  else
+    return WN_Add(rtype, ofst1, ofst2);
+}
+
+/* crate a Iload/Istore with constant or variable offset
+ * if given offset is constant, the value is on the Iload/Istore node.
+ * other, a new address is generated using OPR_ADD and used in Iload/Istore.
+ */
+static WN*
+WGEN_CreateIload(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
+                   WN* offset, TY_IDX ty,
+                   TY_IDX load_addr_ty, WN *addr, UINT field_id) {
+  INT64 ofst_value = 0;
+  if (offset == NULL || WN_operator(offset) == OPR_INTCONST) {
+    ofst_value = (offset == NULL) ? 0 : WN_const_val(offset);
+  }
+  else {
+    addr = WN_Binary(OPR_ADD, Pointer_Mtype, addr, offset);  // TODO: use ILDA 
instrad
+  }
+  return WN_CreateIload(opr, rtype, desc,
+                        ofst_value, ty,
+                        load_addr_ty, addr, field_id);
+}
+
+static WN*
+WGEN_CreateIstore(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
+                    WN* offset, TY_IDX ty, WN *value, WN *addr,
+                    UINT field_id) {
+  INT64 ofst_value = 0;
+  if (offset == NULL || WN_operator(offset) == OPR_INTCONST) {
+    ofst_value = (offset == NULL) ? 0 : WN_const_val(offset);
+    FmtAssert(desc != MTYPE_M || TY_size(TY_pointed(ty)) != -1,
+              ("WGEN_CreateIstore: TODO: store variable length object"));
+  }
+  else {
+    addr = WN_Binary(OPR_ADD, Pointer_Mtype, addr, offset);  // TODO: use ILDA 
instrad
+  }
+  return WN_CreateIstore(opr, rtype, desc,
+                         ofst_value, ty, value, addr,
+                         field_id);
+}
+
+/* create a LDID/STID with constant or variable offset
+ * if given offset is constant, the LDID/STID with constant offset is generated
+ * other, a new address is generated using OPR_LDA and OPR_ADD and the final 
returned
+ * WN is Iload/Istore
+ */
+static WN*
+WGEN_CreateLdid(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
+                  WN* offset, ST* st, TY_IDX ty, UINT field_id) {
+  if (offset == NULL || WN_operator(offset) == OPR_INTCONST) {
+    INT64 ofst_value = (offset == NULL) ? 0 : WN_const_val(offset);
+    return WN_CreateLdid(opr, rtype, desc,
+                         ST_ofst(st) + ofst_value, st, ty, field_id);
+  }
+  else {
+    // variable offset should only appear in VLA/VLS but we never generate
+    // LDID for VLA/VLS
+    Is_True(FALSE, ("WGEN_CreateLdid: offset is not constant for LDID."));
+    return NULL;
+  }
+}
+
+static WN*
+WGEN_CreateStid(OPERATOR opr, TYPE_ID rtype, TYPE_ID desc,
+                  WN* offset, ST* st, TY_IDX ty, WN *value, UINT field_id) {
+  if (offset == NULL || WN_operator(offset) == OPR_INTCONST) {
+    INT64 ofst_value = (offset == NULL) ? 0 : WN_const_val(offset);
+    return WN_CreateStid(opr, rtype, desc,
+                         ST_ofst(st) + ofst_value, st, ty, value, field_id);
+  }
+  else {
+    // variable offset should only appear in VLA/VLS but we never generate
+    // STID for VLA/VLS
+    Is_True(FALSE, ("WGEN_CreateStid: offset is not constant for STID."));
+    return NULL;
+  }
+}
+
 typedef struct wgen_save_expr_t {
   gs_t  exp;
   ST   *st;
@@ -909,7 +1049,7 @@
                bool need_result,
                TY_IDX nop_ty_idx,
                TY_IDX component_ty_idx,
-               INT64 component_offset,
+               WN* component_offset,
                UINT16 field_id)
 {
   INT32     i;
@@ -987,7 +1127,7 @@
   else {
     TYPE_ID desc  = TY_mtype(component_ty_idx);
     TYPE_ID rtype = Widen_Mtype(desc);
-    wn = WN_CreateLdid(OPR_LDID, rtype, desc, component_offset, st,
+    wn = WGEN_CreateLdid(OPR_LDID, rtype, desc, component_offset, st,
                     field_id? ty_idx : component_ty_idx, field_id);  
   }
   return wn;
@@ -1049,7 +1189,6 @@
   return WN_Ldid(ret_mtype, 0, res_st, ty_idx);
 }
 
-
 /* process the tree doing array indicing and return the WN that performs
  * the address computation; ty_idx returns the high-level array type if it
  * is a DECL node, and the element type if it is an ARRAY_REF node.
@@ -1058,7 +1197,7 @@
 WGEN_Array_Expr(gs_t exp, 
               TY_IDX *ty_idx, 
               TY_IDX component_ty_idx,
-              INT64 component_offset,
+              WN* component_offset,
               UINT32 field_id)
 {
   WN *wn;
@@ -1076,9 +1215,7 @@
 #endif
     Is_True(! gs_decl_bit_field(arg1),
            ("WGEN_Array_Expr: address arithmetic cannot use bitfield 
addresses"));
-    INT64 ofst = (BITSPERBYTE * 
gs_get_integer_value(gs_decl_field_offset(arg1)) +
-                               
gs_get_integer_value(gs_decl_field_bit_offset(arg1)))
-                             / BITSPERBYTE;
+    WN* ofst = WGEN_Expand_Field_Offset(arg1);
 #ifdef KEY
     // Refer GCC 4.0.2: gcc.c-torture/compile/struct-non-lval-3.c
     // We only handle this case so far:
@@ -1092,13 +1229,15 @@
       arg0 = lhs;
     }
 #endif
-    
+
+    ofst = WGEN_Compose_Offset(ofst, component_offset);    
+
 #ifdef KEY // bug 9725: If the field is an array of struct, it is considered
            // a single field.
-    return WGEN_Array_Expr(arg0, ty_idx, ty_idx0, ofst + component_offset,
+    return WGEN_Array_Expr(arg0, ty_idx, ty_idx0, ofst,
                          DECL_FIELD_ID(arg1));
 #else
-    return WGEN_Array_Expr(arg0, ty_idx, ty_idx0, ofst + component_offset,
+    return WGEN_Array_Expr(arg0, ty_idx, ty_idx0, ofst,
                          field_id + DECL_FIELD_ID(arg1));
 #endif
   }
@@ -1116,15 +1255,6 @@
           ) {
     ST *st = Get_ST (exp);
     ST *base_st = ST_base (st);
-    // for VLAs the instead of using the ST use its base st
-    // also for the time being do not support VLAs within structs
-    if (st != base_st) {
-      FmtAssert (component_ty_idx == 0,
-                 ("Variable Length Arrays within struct not currently 
implemented"));
-      wn = WN_Ldid (Pointer_Mtype, 0, base_st, ST_type (base_st));
-    }
-    else
-      wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
     if (component_ty_idx == 0)
       *ty_idx = ST_type(st);
     else {
@@ -1134,16 +1264,29 @@
     }
     Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
            ("WGEN_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
+    // for VLAs the instead of using the ST use its base st
+    // also for the time being do not support VLAs within structs
+    if (st != base_st) {
+      DevWarn ("Encountered VLA at line %d", lineno);
+      Is_True(ST_ofst(st) == 0, ("TODO: ST_ofst is not 0"));
+      wn = WN_Ldid (Pointer_Mtype, 0, base_st, Make_Pointer_Type(*ty_idx));
+      if (component_offset != NULL) { // TODO: use ILDA instead
+        wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn, component_offset);
+      }
+    }
+    else {
+      wn = WGEN_Compose_Address(st, component_offset, ST_type(st), field_id);
+    }
     return wn;
   }
   else if (code == GS_CONSTRUCTOR) {
     ST *st = WGEN_Generate_Temp_For_Initialized_Aggregate (exp, "");
-    wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
     if (component_ty_idx == 0)
       *ty_idx = ST_type(st);
     else *ty_idx = component_ty_idx;
     Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
            ("WGEN_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
+    wn = WGEN_Compose_Address(st, component_offset, ST_type(st), field_id);
     return wn;
   }
   else if (code == GS_STRING_CST) {
@@ -1161,9 +1304,8 @@
       if (node_align < TY_align(component_ty_idx))
        Set_TY_align(*ty_idx, node_align);//pick more stringent align
     }
-    if (component_offset != 0) { // TODO: use ILDA instead
-      WN *wn0 = WN_Intconst(MTYPE_I4, component_offset);
-      wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn, wn0);
+    if (component_offset != NULL) { // TODO: use ILDA instead
+      wn = WN_Binary(OPR_ADD, Pointer_Mtype, wn, component_offset);
     }
     return wn;
   }
@@ -1175,7 +1317,6 @@
     ST *st = WN_st (WN_kid1 (wn));
     WN_Delete (WN_kid1 (wn));
     WN_Delete (wn);
-    wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
     if (component_ty_idx == 0)
       *ty_idx = ST_type(st);
     else {
@@ -1185,6 +1326,7 @@
     }
     Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
            ("WGEN_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
+    wn = WGEN_Compose_Address(st, component_offset, ST_type(st), field_id);
     return wn;
   }
   else if (code == GS_ARRAY_REF) { // recursive call
@@ -1276,7 +1418,6 @@
     Is_True(WN_operator(wn) == OPR_LDID,
            ("WGEN_Array_Expr: OPR_LDID not found"));
     ST *st = WN_st(wn);
-    wn = WN_Lda (Pointer_Mtype, ST_ofst(st)+component_offset, st, field_id);
     if (component_ty_idx == 0)
       *ty_idx = ST_type(st);
     else {
@@ -1286,6 +1427,7 @@
     }
     Is_True(TY_kind(*ty_idx) == KIND_ARRAY,
            ("WGEN_Array_Expr: ARRAY_REF base not of type KIND_ARRAY"));
+    wn = WGEN_Compose_Address(st, component_offset, ST_type(st), field_id);
     return wn;
   }
 #endif /* KEY */
@@ -1374,7 +1516,7 @@
                       WN* lhs_retval,
                       bool need_result,
                       TY_IDX component_ty_idx, 
-                      INT64 component_offset,
+                      WN* component_offset,
                       UINT32 field_id,
                       bool is_bit_field,
                       WN *rhs_wn,
@@ -1405,7 +1547,6 @@
   switch (code) {
   case GS_COMPONENT_REF:
     {
-      INT64 ofst;
       TY_IDX ty_idx0;
 
       gs_t arg0 = gs_tree_operand(lhs, 0);
@@ -1420,11 +1561,14 @@
       else ty_idx0 = component_ty_idx;
       if (gs_decl_bit_field(arg1)) 
         is_bit_field = TRUE;
-      if (! is_bit_field)
-        ofst = (BITSPERBYTE * gs_get_integer_value(gs_decl_field_offset(arg1)) 
+
-                             
gs_get_integer_value(gs_decl_field_bit_offset(arg1)))
-                           / BITSPERBYTE;
-      else ofst = 0;
+      WN* ofst;
+      if (! is_bit_field) {
+        ofst = WGEN_Expand_Field_Offset(arg1);
+        ofst = WGEN_Compose_Offset(ofst, component_offset);
+      }
+      else {
+        ofst = component_offset;
+      }
 #ifdef KEY    // bug 10422: check if the field is volatile, arg1 is FIELD_DECL
       if (gs_tree_this_volatile(arg1)) {
        Set_TY_is_volatile(ty_idx0);
@@ -1440,7 +1584,7 @@
                  ("WGEN_Lhs_Of_Modify_Expr: DECL_FIELD_ID used but not set"));
 #endif
       wn = WGEN_Lhs_Of_Modify_Expr(assign_code, arg0, NULL, need_result, 
ty_idx0, 
-                                 ofst+component_offset,
+                                 ofst,
                                  field_id + DECL_FIELD_ID(arg1), is_bit_field, 
                                  rhs_wn, rhs_preg_num, is_realpart,
                                  is_imagpart);
@@ -1568,16 +1712,16 @@
                               rhs_wn,
                               WN_Unary(OPR_IMAGPART,
                                        Mtype_complex_to_real (rtype),
-                                       WN_CreateLdid(OPR_LDID, rtype, desc,
-                                                     ST_ofst(st) + 
component_offset,
+                                       WGEN_CreateLdid(OPR_LDID, rtype, desc,
+                                                     component_offset,
                                                      st, hi_ty_idx, 
field_id)));
          else
          if (is_imagpart)
            rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
                               WN_Unary(OPR_REALPART,
                                        Mtype_complex_to_real (rtype),
-                                       WN_CreateLdid(OPR_LDID, rtype, desc,
-                                                     ST_ofst(st) + 
component_offset,
+                                       WGEN_CreateLdid(OPR_LDID, rtype, desc,
+                                                     component_offset,
                                                      st, hi_ty_idx, field_id)),
                               rhs_wn);
         }
@@ -1595,8 +1739,8 @@
 
         if (assign_code == GS_PREINCREMENT_EXPR ||
            assign_code == GS_PREDECREMENT_EXPR) {
-          wn = WN_CreateLdid (OPR_LDID, rtype, desc, 
-                             ST_ofst(st) + component_offset,
+          wn = WGEN_CreateLdid (OPR_LDID, rtype, desc, 
+                             component_offset,
                              st, hi_ty_idx, field_id);
           rhs_wn = WN_Binary(Operator_From_Tree [assign_code].opr,
                             rtype, wn, rhs_wn);
@@ -1604,8 +1748,8 @@
         }
         else if (assign_code == GS_POSTINCREMENT_EXPR ||
                 assign_code == GS_POSTDECREMENT_EXPR) {
-          result_wn = WN_CreateLdid (OPR_LDID, rtype, desc, 
-                                    ST_ofst(st) + component_offset,
+          result_wn = WGEN_CreateLdid (OPR_LDID, rtype, desc, 
+                                    component_offset,
                                     st, hi_ty_idx, field_id);
         }
         else result_wn = rhs_wn;
@@ -1646,15 +1790,24 @@
        if (volt) 
          Set_TY_is_volatile(hi_ty_idx);
 #endif
-        wn = WN_Stid (desc, ST_ofst(st) + component_offset + lhs_preg_num, st,
-                     hi_ty_idx, rhs_wn, field_id);
+        if (ST_base(st) != st) {
+          ST* base_st = ST_base(st);
+          Is_True(ST_ofst(st) == 0, ("TODO: ST_ofst is not 0"));
+          WN* addr = WN_Ldid(Pointer_Mtype, 0, base_st, ST_type(base_st));
+          wn = WGEN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset,
+                                   ST_type(base_st), rhs_wn, addr, field_id);
+        }
+        else {
+          wn = WGEN_CreateStid (OPR_STID, MTYPE_V, desc, component_offset, st,
+                       hi_ty_idx, rhs_wn, field_id);
+        }
         WGEN_Stmt_Append(wn, Get_Srcpos());
 #if defined(TARG_SL)
         if (need_append) {
           WN *ldid_wn;
           if (! result_in_temp)
-            ldid_wn =  WN_CreateLdid(OPR_LDID, rtype, desc,
-                                     ST_ofst(st) + component_offset, st, 
hi_ty_idx,
+            ldid_wn =  WGEN_CreateLdid(OPR_LDID, rtype, desc,
+                                     component_offset, st, hi_ty_idx,
                                      field_id);
           else
             ldid_wn =  WN_Ldid(rtype, result_preg, result_preg_st, 
desc_ty_idx, 0);
@@ -1665,8 +1818,8 @@
       }
       if (need_result) {
         if (! result_in_temp)
-          wn = WN_CreateLdid(OPR_LDID, rtype, desc, 
-                            ST_ofst(st) + component_offset, st, hi_ty_idx,
+          wn = WGEN_CreateLdid(OPR_LDID, rtype, desc, 
+                            component_offset, st, hi_ty_idx,
                             field_id);
         else wn = WN_Ldid(rtype, result_preg, result_preg_st, desc_ty_idx, 0);
         if (is_realpart)
@@ -1781,7 +1934,7 @@
                               rhs_wn,
                               WN_Unary(OPR_IMAGPART,
                                        Mtype_complex_to_real (rtype),
-                                       WN_CreateIload(OPR_ILOAD, rtype, desc,
+                                       WGEN_CreateIload(OPR_ILOAD, rtype, desc,
                                                       component_offset,
                                                       field_id != 0 ? 
hi_ty_idx : desc_ty_idx,
                                                       
Make_Pointer_Type(hi_ty_idx, FALSE),
@@ -1792,7 +1945,7 @@
            rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
                               WN_Unary(OPR_REALPART,
                                        Mtype_complex_to_real (rtype),
-                                       WN_CreateIload(OPR_ILOAD, rtype, desc,
+                                       WGEN_CreateIload(OPR_ILOAD, rtype, desc,
                                                       component_offset,
                                                       field_id != 0 ? 
hi_ty_idx : desc_ty_idx,
                                                       
Make_Pointer_Type(hi_ty_idx, FALSE),
@@ -1814,7 +1967,7 @@
 
         if (assign_code == GS_PREINCREMENT_EXPR ||
            assign_code == GS_PREDECREMENT_EXPR) {
-          wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
+          wn = WGEN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
                               field_id != 0 ? hi_ty_idx : desc_ty_idx,
                               Make_Pointer_Type(hi_ty_idx, FALSE),
                               WN_COPY_Tree (addr_wn),
@@ -1825,7 +1978,7 @@
         }
         else if (assign_code == GS_POSTINCREMENT_EXPR ||
                 assign_code == GS_POSTDECREMENT_EXPR) {
-         result_wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
+         result_wn = WGEN_CreateIload (OPR_ILOAD, rtype, desc, 
component_offset,
                                      field_id != 0 ? hi_ty_idx : desc_ty_idx,
                                      Make_Pointer_Type(hi_ty_idx, FALSE),
                                      WN_COPY_Tree (addr_wn),
@@ -1903,14 +2056,16 @@
          gs_t type = gs_tree_type(ptr_type);
          FmtAssert(gs_tree_code(ptr_type) == GS_POINTER_TYPE,
            ("WGEN_Lhs_Of_Modify_Expr: INDIRECT_REF opnd0 is not 
POINTER_TYPE"));
-         FmtAssert(component_offset == 0,
+         FmtAssert(component_offset == NULL ||
+                    (WN_operator(component_offset) == OPR_INTCONST && 
+                     WN_const_val(component_offset) == 0),
                    ("WGEN_Lhs_Of_Modify_Expr: component_offset nonzero"));
          TY_IDX tidx = Get_TY(ptr_type);
          // Check object has no copy constructor.
          FmtAssert(!WGEN_has_copy_constructor(type),
              ("WGEN_Lhs_Of_Modify_Expr: object needs copy constructor"));
         }
-        wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset, 
+        wn = WGEN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset, 
                             Make_Pointer_Type (hi_ty_idx, FALSE),
                             rhs_wn, addr_wn, field_id);
 #ifdef TARG_SL
@@ -1931,7 +2086,7 @@
         if (need_append) {
           WN *ldid_wn;
           if (! result_in_temp)
-            ldid_wn = WN_CreateIload(OPR_ILOAD, rtype, desc, component_offset,
+            ldid_wn = WGEN_CreateIload(OPR_ILOAD, rtype, desc, 
component_offset,
                                      field_id != 0 ? hi_ty_idx : desc_ty_idx,
                                      Make_Pointer_Type (hi_ty_idx, FALSE),
                                      WN_COPY_Tree (addr_wn),
@@ -1944,7 +2099,7 @@
 #endif
         if (need_result) {
          if (! result_in_temp)
-            wn = WN_CreateIload(OPR_ILOAD, rtype, desc, component_offset,
+            wn = WGEN_CreateIload(OPR_ILOAD, rtype, desc, component_offset,
                                field_id != 0 ? hi_ty_idx : desc_ty_idx,
                                Make_Pointer_Type (hi_ty_idx, FALSE),
                                WN_COPY_Tree (addr_wn),
@@ -1965,7 +2120,7 @@
     {
       TY_IDX elem_ty_idx;
       // generate the WHIRL array node
-      WN *addr_wn = WGEN_Array_Expr(lhs, &elem_ty_idx, 0, 0, 0);
+      WN *addr_wn = WGEN_Array_Expr(lhs, &elem_ty_idx, 0, NULL, 0);
       if (TY_is_volatile(elem_ty_idx))
         volt = TRUE;
       TY_IDX desc_ty_idx = component_ty_idx;
@@ -2017,7 +2172,7 @@
                               rhs_wn,
                               WN_Unary(OPR_IMAGPART,
                                        Mtype_complex_to_real (rtype),
-                                       WN_CreateIload(OPR_ILOAD, rtype, desc,
+                                       WGEN_CreateIload(OPR_ILOAD, rtype, desc,
                                                       component_offset,
                                                       field_id != 0 ? 
elem_ty_idx : desc_ty_idx,
                                                       
Make_Pointer_Type(elem_ty_idx, FALSE),
@@ -2028,7 +2183,7 @@
            rhs_wn = WN_Binary(OPR_COMPLEX, rtype,
                               WN_Unary(OPR_REALPART,
                                        Mtype_complex_to_real (rtype),
-                                       WN_CreateIload(OPR_ILOAD, rtype, desc,
+                                       WGEN_CreateIload(OPR_ILOAD, rtype, desc,
                                                       component_offset,
                                                       field_id != 0 ? 
elem_ty_idx : desc_ty_idx,
                                                       
Make_Pointer_Type(elem_ty_idx, FALSE),
@@ -2050,7 +2205,7 @@
 
         if (assign_code == GS_PREINCREMENT_EXPR ||
             assign_code == GS_PREDECREMENT_EXPR) {
-          wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
+          wn = WGEN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
                                field_id != 0 ? elem_ty_idx : desc_ty_idx,
                                Make_Pointer_Type(elem_ty_idx, FALSE),
                                WN_COPY_Tree (addr_wn),
@@ -2061,7 +2216,7 @@
         }
         else if (assign_code == GS_POSTINCREMENT_EXPR ||
                 assign_code == GS_POSTDECREMENT_EXPR) {
-          result_wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
+          result_wn = WGEN_CreateIload (OPR_ILOAD, rtype, desc, 
component_offset,
                                      field_id != 0 ? elem_ty_idx : desc_ty_idx,
                                      Make_Pointer_Type(elem_ty_idx, FALSE),
                                      WN_COPY_Tree (addr_wn),
@@ -2106,7 +2261,7 @@
         wn = NULL;
       }
       else {
-        wn = WN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset, 
+        wn = WGEN_CreateIstore(OPR_ISTORE, MTYPE_V, desc, component_offset, 
                             Make_Pointer_Type(elem_ty_idx, FALSE), rhs_wn,
                             addr_wn, field_id);
         WGEN_Stmt_Append(wn, Get_Srcpos());
@@ -2114,7 +2269,7 @@
         if (need_append) {
           WN *iload;
           if (!result_in_temp)
-            iload = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
+            iload = WGEN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
                                       field_id != 0 ? elem_ty_idx : 
desc_ty_idx,
                                       Make_Pointer_Type (elem_ty_idx, FALSE),
                                       WN_COPY_Tree (addr_wn),
@@ -2126,7 +2281,7 @@
 #endif
         if (need_result) {
           if (! result_in_temp)
-           wn = WN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
+           wn = WGEN_CreateIload (OPR_ILOAD, rtype, desc, component_offset,
                                 field_id != 0 ? elem_ty_idx : desc_ty_idx,
                                  Make_Pointer_Type (elem_ty_idx, FALSE),
                                 WN_COPY_Tree (addr_wn),
@@ -2202,20 +2357,25 @@
       TYPE_ID desc = is_bit_field ? MTYPE_BS : TY_mtype(desc_ty_idx);
       if (desc == MTYPE_UNKNOWN)
        desc = WN_rtype(rhs_wn); // is a scalar
+
+      Is_True(component_offset == NULL || WN_operator(component_offset) == 
OPR_INTCONST,
+              ("WGEN_Lhs_Of_Modify_Expr: GS_COMPOUND_LITERAL_EXPR: offset is 
not constant"));
+      INT64 ofst_value = (component_offset == NULL) ? 0 : 
WN_const_val(component_offset);
+
 #ifdef KEY // bug 14372
-      wn = WN_Stid (desc, ST_ofst(copy) + component_offset, copy,
+      wn = WN_Stid (desc, ST_ofst(copy) + ofst_value, copy,
                    hi_ty_idx, rhs_wn, field_id);
 #else
       if (desc_ty_idx == 0)
         desc_ty_idx = MTYPE_TO_TY_array[desc];
 
-      wn = WN_Stid (desc, ST_ofst(copy) + component_offset, copy,
+      wn = WN_Stid (desc, ST_ofst(copy) + ofst_value, copy,
                    desc_ty_idx, rhs_wn, field_id);
 #endif
       WGEN_Stmt_Append(wn, Get_Srcpos());
       if (need_result) // bug 10548
         wn = WN_CreateLdid(OPR_LDID, desc, desc,
-                           ST_ofst(copy) + component_offset, copy,
+                           ST_ofst(copy) + ofst_value, copy,
                            ST_type(copy));
       else
         wn = NULL;
@@ -6059,7 +6219,7 @@
                  bool need_result,
                  TY_IDX nop_ty_idx,
                  TY_IDX component_ty_idx,
-                 INT64 component_offset,
+                 WN* component_offset,
                  UINT32 field_id ,
                  bool is_bit_field,
                  bool is_aggr_init_via_ctor,
@@ -6533,10 +6693,31 @@
 
        Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
                ("WGEN_Expand_Expr: field id for bit-field exceeds limit"));
-       wn = WN_CreateLdid (OPR_LDID, rtype,
-                           is_bit_field ? MTYPE_BS : desc,
-                           ST_ofst(st)+component_offset+xtra_BE_ofst+preg_num, 
st,
-                           field_id != 0 ? hi_ty_idx : ty_idx, field_id);
+        WN* load_ofst = NULL;
+        if (xtra_BE_ofst + preg_num != 0)
+          load_ofst = WGEN_Compose_Offset(component_offset,
+                                          WN_Intconst(Pointer_Mtype, 
xtra_BE_ofst));
+        else
+          load_ofst = component_offset;
+        if (ST_base(st) != st) {
+          ST* base_st = ST_base(st);
+          Is_True(ST_ofst(st) == 0, ("TODO: ST_ofst is not 0"));
+          WN* load_addr = WN_Ldid(Pointer_Mtype, 0, base_st, ST_type(base_st));
+          TY_IDX load_ty = field_id != 0 ? hi_ty_idx : ty_idx;
+          wn = WGEN_CreateIload(OPR_ILOAD, rtype,
+                              is_bit_field ? MTYPE_BS : desc,
+                              load_ofst,
+                              load_ty,
+                              ST_type(base_st),
+                              load_addr,
+                              field_id);
+        }
+        else {
+         wn = WGEN_CreateLdid (OPR_LDID, rtype,
+                             is_bit_field ? MTYPE_BS : desc,
+                             load_ofst, st,
+                             field_id != 0 ? hi_ty_idx : ty_idx, field_id);
+        }
        if (cvtl_size != 0)
          wn = WN_CreateCvtl(OPR_CVTL, rtype, MTYPE_V, cvtl_size, wn);
       }
@@ -6597,9 +6778,9 @@
          if (ST_assigned_to_dedicated_preg (st))
            Set_TY_is_volatile (ty_idx);
        }
-       wn = WN_CreateLdid (OPR_LDID, rtype,
+       wn = WGEN_CreateLdid (OPR_LDID, rtype,
                            is_bit_field ? MTYPE_BS : desc, 
-                           ST_ofst(st)+component_offset, st,
+                           component_offset, st,
                            field_id != 0 ? hi_ty_idx : ty_idx, field_id);
        if (cvtl_size != 0)
          wn = WN_CreateCvtl(OPR_CVTL, rtype, MTYPE_V, cvtl_size, wn);
@@ -6874,7 +7055,6 @@
 
     case GS_COMPONENT_REF:
       {
-       INT64 ofst;
        arg0 = gs_tree_operand (exp, 0);
        arg1 = gs_tree_operand (exp, 1);
        // If this is an indirect of a nop_expr, we may need to fix the
@@ -6907,11 +7087,14 @@
          }
         }
 
-       if (! is_bit_field)
-         ofst = (BITSPERBYTE * 
gs_get_integer_value(gs_decl_field_offset(arg1)) +
-                               
gs_get_integer_value(gs_decl_field_bit_offset(arg1)))
-                             / BITSPERBYTE;
-       else ofst = 0;
+        WN* ofst = NULL;
+       if (! is_bit_field) {
+          ofst = WGEN_Expand_Field_Offset(arg1);
+          ofst = WGEN_Compose_Offset(ofst, component_offset);
+        }
+       else {
+          ofst = component_offset;
+        }
 #ifdef KEY
        FmtAssert (DECL_FIELD_ID(arg1) != 0,
                    ("WGEN_Expand_Expr: DECL_FIELD_ID used but not set"));
@@ -6926,11 +7109,11 @@
          // WGEN_Call_Returns_Ptr_To_Member_Func(arg0)) is TRUE.  Bug 6022.
          TYPE_ID desc = TY_mtype(Get_TY(gs_tree_type(field0)));
          wn = WGEN_Expand_Ptr_To_Member_Func_Call_Expr (arg0, nop_ty_idx,
-                 Pointer_Mtype, desc, component_offset,
+                 Pointer_Mtype, desc, ofst,
                  field_id + DECL_FIELD_ID(arg1));
        } else
 #endif
-        wn = WGEN_Expand_Expr (arg0, TRUE, nop_ty_idx, ty_idx, 
ofst+component_offset,
+        wn = WGEN_Expand_Expr (arg0, TRUE, nop_ty_idx, ty_idx, ofst,
                              field_id + DECL_FIELD_ID(arg1), is_bit_field);
 
 #ifdef KEY
@@ -6947,15 +7130,26 @@
          TYPE_ID rtype = Widen_Mtype(TY_mtype(ty_idx));
          TYPE_ID desc = TY_mtype(ty_idx);
          if (WN_operator(wn) == OPR_ILOAD) {
-            wn = WN_CreateIload(OPR_ILOAD, rtype, desc,
-                               WN_offset(wn) + ofst + component_offset, ty_idx,
+            WN* iload_ofst = NULL;
+            if (WN_offset(wn) != 0) {
+              iload_ofst = WGEN_Compose_Offset(ofst,
+                                               WN_Intconst(Pointer_Mtype, 
WN_offset(wn)));
+            }
+            else {
+              iload_ofst = ofst;
+            }
+            wn = WGEN_CreateIload(OPR_ILOAD, rtype, desc,
+                               iload_ofst, ty_idx,
                                WN_load_addr_ty(wn), WN_kid0(wn),
                                WN_field_id(wn)+field_id + DECL_FIELD_ID(arg1));
          } 
          else if (WN_operator(wn) == OPR_LDID) {
            WN_set_rtype(wn, rtype);
            WN_set_desc(wn, desc);
-           WN_offset(wn) = WN_offset(wn)+ofst+component_offset;
+            Is_True(ofst == NULL || WN_operator(ofst) == OPR_INTCONST,
+                    ("WGEN_Expand_Expr: ofst is not constant for LDID"));
+            INT64 ofst_value = (ofst == NULL) ? 0 : WN_const_val(ofst);
+           WN_offset(wn) = WN_offset(wn) + ofst_value;
            WN_set_field_id(wn, WN_field_id(wn)+field_id + DECL_FIELD_ID(arg1));
          } 
        } 
@@ -6978,7 +7172,8 @@
          wn = WN_Stid (MTYPE_M, 0, temp, temp_ty_idx, wn);
          WGEN_Stmt_Append (wn, Get_Srcpos());
          // Load correct field from temp symbol
-         wn = WN_Ldid (TY_mtype (ty_idx), ofst + component_offset,
+          TYPE_ID rtype= Mtype_comparison(TY_mtype (ty_idx));
+         wn = WGEN_CreateLdid (OPR_LDID, rtype, TY_mtype (ty_idx), ofst,
                        temp, temp_ty_idx, field_id + DECL_FIELD_ID(arg1));
        }
 #endif
@@ -7061,7 +7256,10 @@
            if (TCON_ty (tcon) == MTYPE_STRING &&
                 TY_size (Be_Type_Tbl (desc)) == 1) {
              mUINT32 len = Targ_String_Length (tcon);
-             mUINT64 offset = component_offset + xtra_BE_ofst + WN_offset 
(wn0);
+              Is_True(component_offset == NULL || 
WN_operator(component_offset) == OPR_INTCONST,
+                      ("WGEN_Expand_Expr: component_offset is not constant"));
+              INT64 offset_value = (component_offset == NULL) ? 0 : 
WN_const_val(component_offset);
+             mUINT64 offset = offset_value + xtra_BE_ofst + WN_offset (wn0);
              if (offset <= len    &&
                  desc == MTYPE_U1 &&
                  (rtype == MTYPE_U4 || rtype == MTYPE_U8)) {
@@ -7082,13 +7280,20 @@
            }
          }
          // NOTE: In GNU4, this may be a REFERENCE_REF_P.
-         if (need_result)
-           wn = WN_CreateIload(OPR_ILOAD, rtype,
+         if (need_result) {
+            WN* iload_ofst = NULL;
+            if (xtra_BE_ofst != 0)
+              iload_ofst = WGEN_Compose_Offset(component_offset,
+                                               WN_Intconst(Pointer_Mtype, 
xtra_BE_ofst));
+            else
+              iload_ofst = component_offset;
+           wn = WGEN_CreateIload(OPR_ILOAD, rtype,
                                is_bit_field ? MTYPE_BS : desc, 
-                               component_offset+xtra_BE_ofst,
+                               iload_ofst,
                                field_id != 0 ? hi_ty_idx : ty_idx, 
                                Make_Pointer_Type (hi_ty_idx, FALSE),
                                wn0, field_id);
+          }
          else
          if (WN_has_side_effects (wn0))
            wn = wn0;
@@ -8032,7 +8237,7 @@
          break;
 #endif
        wn  = WGEN_Lhs_Of_Modify_Expr(code, gs_tree_operand (exp, 0), 
call_return_val, need_result, 
-                                    0, 0, 0, FALSE, wn1, 0, FALSE, FALSE);
+                                    0, NULL, 0, FALSE, wn1, 0, FALSE, FALSE);
       }
       break;
 
@@ -8131,7 +8336,7 @@
        UINT xtra_BE_ofst = 0;  // only needed for big-endian target
        TY_IDX elem_ty_idx;
        // generate the WHIRL array node
-        wn0 = WGEN_Array_Expr(exp, &elem_ty_idx, 0, 0, 0);
+        wn0 = WGEN_Array_Expr(exp, &elem_ty_idx, 0, NULL, 0);
 
        // generate the iload node
        TY_IDX hi_ty_idx = Get_TY (gs_tree_type(exp));
@@ -8175,9 +8380,15 @@
 
        Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
                ("WGEN_Expand_Expr: field id for bit-field exceeds limit"));
-       wn = WN_CreateIload(OPR_ILOAD, rtype,
+        WN* iload_ofst = NULL;
+        if (xtra_BE_ofst != 0)
+          iload_ofst = WGEN_Compose_Offset(component_offset,
+                                           WN_Intconst(Pointer_Mtype, 
xtra_BE_ofst));
+        else
+          iload_ofst = component_offset;
+       wn = WGEN_CreateIload(OPR_ILOAD, rtype,
                            is_bit_field ? MTYPE_BS : desc, 
-                           component_offset+xtra_BE_ofst,
+                           iload_ofst,
                            field_id != 0 ? hi_ty_idx : ty_idx,
                            Make_Pointer_Type(elem_ty_idx, FALSE),
                            wn0, field_id);
@@ -10078,6 +10289,8 @@
          if (arg_mtype == MTYPE_M) {
            arg_mtype = WN_rtype(arg_wn);
          }
+          FmtAssert(arg_mtype != MTYPE_M || TY_size(WN_ty(arg_wn)) != -1,
+                    ("WGEN_Expand_Expr: TODO: pass variable length object"));
           arg_wn = WN_CreateParm (Mtype_comparison (arg_mtype), arg_wn,
                                  arg_ty_idx, WN_PARM_BY_VALUE);
           WN_kid (call_wn, i++) = arg_wn;
@@ -10242,9 +10455,15 @@
             Is_True(! is_bit_field || field_id <= MAX_FIELD_ID,
                     ("WGEN_Expand_Expr: field id for bit-field exceeds 
limit"));
  
-           wn1 = WN_CreateLdid(OPR_LDID, rtype,
+            WN* ldid_ofst = NULL;
+            if (xtra_BE_ofst != 0)
+              ldid_ofst = WGEN_Compose_Offset(component_offset,
+                                               WN_Intconst(Pointer_Mtype, 
xtra_BE_ofst));
+            else
+              ldid_ofst = component_offset;
+           wn1 = WGEN_CreateLdid(OPR_LDID, rtype,
                                is_bit_field ? MTYPE_BS : desc,
-                               ST_ofst(ret_st)+component_offset+xtra_BE_ofst, 
+                               ldid_ofst, 
                                ret_st,
                                (field_id != 0 && component_ty_idx != 0) ?
                                Get_TY (gs_tree_type(exp)) : ty_idx,
@@ -10958,7 +11177,7 @@
 static WN*
 WGEN_Expand_Ptr_To_Member_Func_Call_Expr (gs_t exp, TY_IDX nop_ty_idx,
                                         TYPE_ID rtype, TYPE_ID desc,
-                                        WN_OFFSET offset, UINT field_id)
+                                        WN* offset, UINT field_id)
 {
   TY_IDX exp_ty_idx = Get_TY(gs_tree_type(exp));
   WN *wn;
@@ -10969,7 +11188,7 @@
   WN *target_wn = WN_Lda(Pointer_Mtype, ST_ofst(st), st);
   WGEN_Expand_Expr(exp, TRUE, nop_ty_idx, exp_ty_idx, 0, 0, FALSE, FALSE,
                  target_wn);
-  wn = WN_CreateLdid(OPR_LDID, rtype, desc, ST_ofst(st) + offset,
+  wn = WGEN_CreateLdid(OPR_LDID, rtype, desc, offset,
                     st, exp_ty_idx, field_id);
   return wn;
 }

Modified: trunk/osprey/wgen/wgen_expr.h
===================================================================
--- trunk/osprey/wgen/wgen_expr.h       2012-02-15 08:40:23 UTC (rev 3873)
+++ trunk/osprey/wgen/wgen_expr.h       2012-02-16 10:30:54 UTC (rev 3874)
@@ -68,7 +68,7 @@
                             bool need_result = TRUE,
                             TY_IDX nop_ty_idx = 0,
                             TY_IDX component_ty_idx = 0,
-                            INT64 component_offset = 0,
+                            WN* component_offset = NULL,
                             UINT32 field_id = 0,
                             bool is_bit_field = FALSE,
                             bool is_aggr_init_via_ctor = FALSE
@@ -90,7 +90,7 @@
                                    WN* lhs_retval,
                                    bool need_result,
                                    TY_IDX component_ty_idx,
-                                   INT64 component_offset,
+                                   WN* component_offset,
                                    UINT32 field_id,
                                    bool is_bit_field,
                                    WN *rhs_wn,

Modified: trunk/osprey/wgen/wgen_spin_symbol.cxx
===================================================================
--- trunk/osprey/wgen/wgen_spin_symbol.cxx      2012-02-15 08:40:23 UTC (rev 
3873)
+++ trunk/osprey/wgen/wgen_spin_symbol.cxx      2012-02-16 10:30:54 UTC (rev 
3874)
@@ -434,22 +434,21 @@
        }
        else {
                if (gs_tree_code(type_size) != GS_INTEGER_CST) {
-                       if (gs_tree_code(type_tree) == GS_ARRAY_TYPE)
+                       if (gs_tree_code(type_tree) == GS_ARRAY_TYPE) {
                                DevWarn ("Encountered VLA at line %d", lineno);
-                       else
-#ifndef KEY
-                               Fail_FmtAssertion ("VLA at line %d not 
currently implemented", lineno);
-#else
+                               tsize = 0;
+                       }
+                       else {
                        // bugs 943, 11277, 10506
 #if defined(TARG_SL)
                                ErrMsg(EC_Unimplemented_Feature, 
"variable-length structure",
                                  
Orig_Src_File_Name?Orig_Src_File_Name:Src_File_Name, lineno);
 #else
-                               ErrMsg(EC_Unimplemented_Feature, 
"variable-length structure");
+                               DevWarn ("Encountered variable-length structure 
at line %d", lineno);
+                               tsize = -1;
 #endif
-#endif
+                       }
                        variable_size = TRUE;
-                       tsize = 0;
                }
                else
 #ifdef KEY             // bug 3045
@@ -633,6 +632,21 @@
                     Set_TY_anonymous(ty);
                Set_TY_etype (ty, Get_TY (gs_tree_type(type_tree)));
                Set_TY_align (idx, TY_align(TY_etype(ty)));
+
+               // For GNU VLS (Variable length array in struct),
+               // the size and upper boundary is expression.
+               // If the TYPE_TY_IDX(type_tree) is not set, when
+               // expanding the TY's size, it will fall into a infinite
+               // recursion if the type_tree is referenced in the
+               // size expression. So we set the TYPE_TY_IDX here.
+               if (gs_type_readonly(type_tree))
+                    Set_TY_is_const (idx);
+               if (gs_type_volatile(type_tree))
+                    Set_TY_is_volatile (idx);
+               if (gs_type_restrict(type_tree))
+                    Set_TY_is_restrict (idx);
+               TYPE_TY_IDX(type_tree) = idx;
+
                // assumes 1 dimension
                // nested arrays are treated as arrays of arrays
                ARB_HANDLE arb = New_ARB ();


------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Open64-devel mailing list
Open64-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/open64-devel

Reply via email to