• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nasa / trick / 19947348625

04 Dec 2025 11:30PM UTC coverage: 55.71% (-0.1%) from 55.811%
19947348625

Pull #1996

github

web-flow
Merge 139250256 into 36743883e
Pull Request #1996: Add vs support for stl vector, deque, and array containers of supported data types

39 of 141 new or added lines in 6 files covered. (27.66%)

139 existing lines in 6 files now uncovered.

12493 of 22425 relevant lines covered (55.71%)

307664.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

44.54
/trick_source/sim_services/MemoryManager/MemoryManager_ref_dim.cpp
1
#include <stdio.h>
2
#include <sys/types.h>
3
#include <string.h>
4
#include <sstream>
5
#include <array>
6
#include <algorithm>
7
#include <regex>
8

9
#include "trick/MemoryManager.hh"
10
#include "trick/vval.h"
11
#include "trick/attributes.h"
12
#include "trick/reference.h"
13
#include "trick/parameter_types.h"
14

15
/*
16
 Updates R, a reference to an arrayed object, to a reference to the indexed sub-element of that arrayed object.
17
*/
18
int Trick::MemoryManager::ref_dim( REF2* R, V_DATA* V) {
23,026✔
19

20
    int jj;
21
    int item_size;
22
    int index_value = vval_int(V);
23,026✔
23

24
    if (R->ref_type != REF_ADDRESS) {
23,026✔
25
        emitError("Attempt to index into a non-address reference is bogus in ref_dim.") ;
×
26
        return (1);
×
27
    }
28

29
    // Special handling for STL vectors, deques, and arrays - use the generated accessor function that
30
    // calls [] operator for element access
31
    if (R->attr->type == TRICK_STL &&
23,026✔
32
        (R->attr->stl_type == TRICK_STL_VECTOR ||
1✔
NEW
33
         R->attr->stl_type == TRICK_STL_DEQUE ||
×
NEW
34
         R->attr->stl_type == TRICK_STL_ARRAY) &&
×
35
        R->num_index == 0) {
1✔
36
        // Use the generated accessor functions to get vector/ deque/ array size and element address
37
        // These functions are generated by ICG and know the actual vector/ deque/ array type
38

39
        if (R->attr->get_stl_size == NULL || R->attr->get_stl_element == NULL) {
1✔
NEW
40
            emitError("STL vector accessor functions are NULL in ref_dim.");
×
NEW
41
            return (TRICK_PARAMETER_ARRAY_SIZE);
×
42
        }
43

44
        // Currently supported STL element types
45
        static constexpr std::array<TRICK_TYPE, 14> supported_stl_elem_types = {
46
            TRICK_STRING,
47
            //TRICK_CHARACTER,
48
            //TRICK_UNSIGNED_CHARACTER,
49
            TRICK_ENUMERATED,
50
            TRICK_SHORT,
51
            TRICK_UNSIGNED_SHORT,
52
            TRICK_INTEGER,
53
            TRICK_UNSIGNED_INTEGER,
54
            TRICK_LONG,
55
            TRICK_UNSIGNED_LONG,
56
            TRICK_FLOAT,
57
            TRICK_DOUBLE,
58
            TRICK_LONG_LONG,
59
            TRICK_UNSIGNED_LONG_LONG,
60
            TRICK_BOOLEAN,
61
            TRICK_STRUCTURED
62
        };
63

64
        // Check if element type is supported
65
        if (std::find(supported_stl_elem_types.begin(), 
1✔
66
                      supported_stl_elem_types.end(), 
67
                      R->attr->stl_elem_type) == supported_stl_elem_types.end()) {
2✔
NEW
68
            emitError("Unsupported STL element type in ref_dim.");
×
NEW
69
            return (TRICK_PARAMETER_ARRAY_SIZE);
×
70
        }
71

72
        // Get the number of elements using the type-safe accessor function
73
        size_t num_elements = R->attr->get_stl_size(R->address);
1✔
74

75
        // Check bounds
76
        if (index_value < 0 || (size_t)index_value >= num_elements) {
1✔
NEW
77
            if (debug_level > 1) {
×
NEW
78
                std::stringstream message;
×
NEW
79
                message << index_value << " is out of bounds for STL vector/ deque/ array " << R->reference
×
NEW
80
                        << " (size=" << num_elements << ").";
×
NEW
81
                emitError(message.str());
×
82
            }
NEW
83
            return (TRICK_PARAMETER_ARRAY_SIZE);
×
84
        }
85

86
        // Get the address of the indexed element using the type-safe accessor function
87
        R->address = R->attr->get_stl_element(R->address, index_value);
1✔
88

89
        // For structured types, ref_name will handle the attribute lookup dynamically
90
        // For enumerated types, we need to update attr to point to the enum attributes
91
        // For primitive types, DO NOT increment num_index because primitive attributes have num_index=0
92
        // and incrementing would cause a mismatch in ref_assignment (remaining_dimensions would be negative)
93
        if (R->attr->stl_elem_type == TRICK_ENUMERATED && R->attr->stl_elem_type_name != NULL) {
1✔
94
            // Increment num_index first
NEW
95
            R->num_index++;
×
96
            // Look up the enum attributes using the element type name
NEW
97
            ENUMERATION_MAP::iterator enum_pos = enumeration_map.find(R->attr->stl_elem_type_name);
×
NEW
98
            if (enum_pos != enumeration_map.end()) {
×
99
                // Create a temporary attribute structure for the enum element
100
                static ATTRIBUTES temp_enum_attr;
NEW
101
                memset(&temp_enum_attr, 0, sizeof(ATTRIBUTES));
×
NEW
102
                temp_enum_attr.type = TRICK_ENUMERATED;
×
NEW
103
                temp_enum_attr.type_name = R->attr->stl_elem_type_name;
×
NEW
104
                temp_enum_attr.attr = enum_pos->second; // Point to ENUM_ATTR array
×
105
                // Get actual enum size using generated io_src_sizeof function
NEW
106
                size_t enum_size = io_src_sizeof_user_type(R->attr->stl_elem_type_name);
×
NEW
107
                temp_enum_attr.size = (enum_size > 0) ? enum_size : sizeof(int); // Fall back to sizeof(int) if not found
×
NEW
108
                temp_enum_attr.num_index = R->num_index; // Match the incremented indexing level
×
NEW
109
                temp_enum_attr.units = (char*)"1"; // Default units for enums
×
NEW
110
                temp_enum_attr.io = R->attr->io; // Preserve io flags from container
×
NEW
111
                R->attr = &temp_enum_attr;
×
112
            }
113
        }
114
        // For primitive types, the variable server and other code handle STL types
115
        // by checking stl_elem_type when type == TRICK_STL
116

117
        return (TRICK_NO_ERROR);
1✔
118
    }
119

120
    R->num_index_left--;
23,025✔
121
    if (R->num_index_left < 0) {
23,025✔
122
        /* if we have too many dimensions, flag an error */
123
        emitError("Too many dimensions in ref_dim.\n") ;
×
124
        return (TRICK_PARAMETER_ARRAY_SIZE);
×
125
    }
126

127
    /*Calculate the size of the items in this array. */
128
    item_size =  R->attr->size;
23,025✔
129
    for (jj = (R->attr->num_index - 1); jj > R->num_index; jj--) {
24,398✔
130
        if (R->attr->index[jj].size > 0) {
1,373✔
131
            item_size *= R->attr->index[jj].size;
635✔
132
        } else {
133
            item_size = sizeof(void *);
738✔
134
            R->pointer_present = 1 ;
738✔
135
        }
136
    }
137

138
    /* if current dimension is a constrained ... */
139
    if (R->attr->index[R->num_index].size != 0) {
23,025✔
140

141
        /* for constrained dimensions, we can check the validity of the index value */
142
        if (index_value >= R->attr->index[R->num_index].size || index_value < 0) {
22,913✔
143
            /* print out of bounds error message if MM debug_level is greater than 1 */
144
            if (debug_level > 1) {
3✔
145
                emitError("Memory Manager ERROR: Array index out of bounds.") ;
×
146
            }
147
            return (TRICK_PARAMETER_ARRAY_SIZE);
3✔
148
        }
149

150
    } else {
151

152
        /* for unconstrained dimensions, we can check that the index value is non-negative
153
           and that it is less than the size of the array */
154
        if (index_value >= (get_size(*(void**)(R->address))) || index_value < 0) {
112✔
155

156
            if (index_value >= 0 && get_size(*(void**)(R->address)) == 0) {
×
157
                // Special case (do nothing here):
158
                //   For regular pointers as an equivalent to ->
159
                //   For array pointers that are not yet allocated
160
                // If a pointer is not allocated regardless of regular pointer or array pointer, an error message will be emitted below
161
                //   However, if the pointer is already assigned to a valid address, the error message will NOT be emitted below
162
            } else {
163
                /* print out of bounds error message if MM debug_level is greater than 1 */
164
                if (debug_level > 1) {
×
165
                    std::stringstream message;
×
166
                    message << index_value << " is out of bounds for " << R->reference << " (size=" << get_size(*(void**)(R->address)) << ").";
×
167
                    emitError(message.str());
×
168
                }
169
                return (TRICK_PARAMETER_ARRAY_SIZE);
×
170
            }
171
        }
172

173
        R->pointer_present = 1 ;
112✔
174
        if ( R->create_add_path ) {
112✔
175
            ADDRESS_NODE * address_node ;
176

177
            address_node = new ADDRESS_NODE ;
112✔
178
            address_node->operator_ = AO_DEREFERENCE ;
112✔
179
            address_node->operand.address = NULL ;
112✔
180
            DLL_AddTail(address_node , R->address_path) ;
112✔
181
        }
182

183
        // Dereference the pointer.
184
        R->address = *(void**)R->address;
112✔
185
        if ( R->address == NULL) {
112✔
186
            std::stringstream message;
×
187
            message << "Reference (" << R->reference << ") address is NULL in ref_dim.";
×
188
            emitError(message.str());
×
189
            return(TRICK_PARAMETER_ADDRESS_NULL) ;
×
190
        }
191

192
        // Get allocation information for the address
193
        ALLOC_INFO *alloc_info = get_alloc_info_of(R->address);
112✔
194

195
        // Skip if allocation name is NULL
196
        if (alloc_info != NULL && alloc_info->name != NULL) {
112✔
197
            // Get the reference name from the address that R points if exists and contains & at front
198
            // Otherwise, the pointer is not assigned to anything else rather itself is allocated
199
            std::string ref_name = ref_name_from_address(R->address);
×
200
            if (!ref_name.empty() && ref_name.front() == '&') {
×
201
                ref_name = ref_name.substr(1);
×
202

203
                // Get the reference attributes for what the pointer points to
204
                REF2 *ref2 = ref_attributes((char*)ref_name.c_str());
×
205

206
                // Check if the reference that the pointer points to is valid. Return error if not.
207
                if (ref2 == NULL) {
×
208
                    std::stringstream message;
×
209
                    message << "Reference (" << R->reference << ") is not allocated in ref_dim.";
×
210
                    emitError(message.str());
×
211
                    return(TRICK_PARAMETER_ADDRESS_NULL);
×
212
                }
213

214
                // Only check bounds if ref2 is array-ed
215
                if (ref2->num_index > 0) {
×
216
                    // Check if the pointer points to a static array or a dynamic array and if array index is out of bounds
217
                    if (ref2->attr && ref2->attr->index[ref2->attr->num_index-1].size != 0) { // Static array case
×
218
                        // Check if the index is out of bounds if the pointer points to a static array
219
                        if (index_value >= ref2->attr->index[ref2->attr->num_index-1].size || index_value < 0) {
×
220
                            /* print out of bounds error message if MM debug_level is greater than 1 */
221
                            if (debug_level > 1) {
×
222
                                emitError("Memory Manager ERROR: Array index out of bounds.") ;
×
223
                            }
224
                            free(ref2);
×
225
                            return (TRICK_PARAMETER_ARRAY_SIZE);
×
226
                        }
227
                    } else { // Dynamic array case
228
                        // Check if the index is out of bounds if the pointer points to a dynamic array
229
                        if (index_value >= (get_size(*(void**)(R->address)))) {
×
230
                            /* print out of bounds error message if MM debug_level is greater than 1 */
231
                            if (debug_level > 1) {
×
232
                                std::stringstream message;
×
233
                                message << index_value << " is out of bounds for " << R->reference << " (size=" << get_size(*(void**)(R->address)) << ").";
×
234
                                emitError(message.str());
×
235
                            }
236
                            free(ref2);
×
237
                            return (TRICK_PARAMETER_ARRAY_SIZE);
×
238
                        }
239
                    }
240
                }
241
            } // if (!ref_name.empty() && ref_name.front() == '&') {
242
        } // if (alloc_info->name != NULL) {
243
    } // if (R->attr->index[R->num_index].size != 0) {
244

245
    if ( R->create_add_path ) {
23,022✔
246

247
        ADDRESS_NODE * address_node ;
248

249
        if ( index_value > 0 ) {
9,798✔
250
            address_node = (ADDRESS_NODE *)DLL_GetAt(DLL_GetTailPosition(R->address_path), R->address_path) ;
9,191✔
251
            switch ( address_node->operator_ ) {
9,191✔
252
                case AO_ADDRESS:
9,079✔
253
                    address_node->operand.address = (void *)((char *)address_node->operand.address +  index_value * item_size) ;
9,079✔
254
                    break ;
9,079✔
255
                case AO_DEREFERENCE:
112✔
256
                    address_node = new ADDRESS_NODE ;
112✔
257
                    address_node->operator_ = AO_OFFSET ;
112✔
258
                    address_node->operand.offset = index_value * item_size ;
112✔
259
                    DLL_AddTail(address_node , R->address_path) ;
112✔
260
                    break ;
112✔
261
                case AO_OFFSET:
×
262
                    address_node->operand.offset += index_value * item_size ;
×
263
                    break ;
×
264
            }
265
        }
266
    }
267

268
    R->address =  (void*)((char*)R->address + index_value * item_size);
23,022✔
269
    R->num_index++;
23,022✔
270

271
    return (TRICK_NO_ERROR);
23,022✔
272
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc