- improved rec_find_compound_ent_value(): handle missing [0] access
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 18 Sep 2008 20:08:47 +0000 (20:08 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 18 Sep 2008 20:08:47 +0000 (20:08 +0000)
- improved rec_get_accessed_path(): checks bounds before building the compound graph path

[r22093]

ir/opt/ldstopt.c

index 2be8c52..b608dac 100644 (file)
@@ -408,12 +408,47 @@ ptr_arith:
                }
                idx = 0;
                for (ent = field;;) {
+                       unsigned size;
+                       tarval   *sz, *tv_index, *tlower, *tupper;
+                       long     index;
+                       ir_node  *bound;
+
                        tp = get_entity_type(ent);
                        if (! is_Array_type(tp))
                                break;
                        ent = get_array_element_entity(tp);
+                       size = get_type_size_bytes(get_entity_type(ent));
+                       sz   = new_tarval_from_long(size, mode);
+
+                       tv_index = tarval_div(tv, sz);
+                       tv       = tarval_mod(tv, sz);
+
+                       if (tv_index == tarval_bad || tv == tarval_bad)
+                               return NULL;
+
+                       assert(get_array_n_dimensions(tp) == 1 && "multiarrays not implemented");
+                       bound  = get_array_lower_bound(tp, 0);
+                       tlower = computed_value(bound);
+                       bound  = get_array_upper_bound(tp, 0);
+                       tupper = computed_value(bound);
+
+                       if (tlower == tarval_bad || tupper == tarval_bad)
+                               return NULL;
+
+                       if (tarval_cmp(tv_index, tlower) & pn_Cmp_Lt)
+                               return NULL;
+                       if (tarval_cmp(tupper, tv_index) & pn_Cmp_Lt)
+                               return NULL;
+
+                       /* ok, bounds check finished */
+                       index = get_tarval_long(tv_index);
                        ++idx;
                }
+               if (! tarval_is_null(tv)) {
+                       /* access to some struct/union member */
+                       return NULL;
+               }
+
                /* should be at least ONE array */
                if (idx == 0)
                        return NULL;
@@ -427,9 +462,8 @@ ptr_arith:
 
                for (ent = field;;) {
                        unsigned size;
-                       tarval   *sz, *tv_index, *tlower, *tupper;
+                       tarval   *sz, *tv_index;
                        long     index;
-                       ir_node  *bound;
 
                        tp = get_entity_type(ent);
                        if (! is_Array_type(tp))
@@ -446,21 +480,7 @@ ptr_arith:
                        if (tv_index == tarval_bad || tv == tarval_bad)
                                return NULL;
 
-                       assert(get_array_n_dimensions(tp) == 1 && "multiarrays not implemented");
-                       bound  = get_array_lower_bound(tp, 0);
-                       tlower = computed_value(bound);
-                       bound  = get_array_upper_bound(tp, 0);
-                       tupper = computed_value(bound);
-
-                       if (tlower == tarval_bad || tupper == tarval_bad)
-                               return NULL;
-
-                       if (tarval_cmp(tv_index, tlower) & pn_Cmp_Lt)
-                               return NULL;
-                       if (tarval_cmp(tupper, tv_index) & pn_Cmp_Lt)
-                               return NULL;
-
-                       /* ok, bounds check finished */
+                       /* bounds already checked above */
                        index = get_tarval_long(tv_index);
                        set_compound_graph_path_array_index(res, pos, index);
                        ++pos;
@@ -501,23 +521,45 @@ static ir_node *rec_find_compound_ent_value(ir_node *ptr, path_entry *next) {
        ir_initializer_t *initializer;
        tarval           *tv;
        ir_type          *tp;
+       unsigned         n;
 
-       entry.next      = next;
-
+       entry.next = next;
        if (is_SymConst(ptr)) {
                /* found the root */
-               ent = get_SymConst_entity(ptr);
+               ent         = get_SymConst_entity(ptr);
                initializer = get_entity_initializer(ent);
-               for (p = next; p != NULL; p = p->next) {
-                       unsigned n;
-
+               for (p = next; p != NULL;) {
                        if (initializer->kind != IR_INITIALIZER_COMPOUND)
                                return NULL;
+                       n  = get_initializer_compound_n_entries(initializer);
+                       tp = get_entity_type(ent);
 
-                       n = get_initializer_compound_n_entries(initializer);
+                       if (is_Array_type(tp)) {
+                               ent = get_array_element_entity(tp);
+                               if (ent != p->ent) {
+                                       /* a missing [0] */
+                                       if (0 >= n)
+                                               return NULL;
+                                       initializer = get_initializer_compound_value(initializer, 0);
+                                       continue;
+                               }
+                       }
                        if (p->index >= n)
                                return NULL;
                        initializer = get_initializer_compound_value(initializer, p->index);
+
+                       ent = p->ent;
+                       p   = p->next;
+               }
+               tp = get_entity_type(ent);
+               while (is_Array_type(tp)) {
+                       ent = get_array_element_entity(tp);
+                       tp = get_entity_type(ent);
+                       /* a missing [0] */
+                       n  = get_initializer_compound_n_entries(initializer);
+                       if (0 >= n)
+                               return NULL;
+                       initializer = get_initializer_compound_value(initializer, 0);
                }
 
                switch (initializer->kind) {