@@ -148,16 +148,72 @@ def test(self):
148
148
149
149
# Test some other cases of the Cast API. We allow casts from one struct type
150
150
# to another, which is a little weird, but we don't support casting from a
151
- # smaller type to a larger as we often wouldn't know how to get the extra data:
152
- val_f = target .EvaluateExpression ("f" )
153
- bad_cast = val_s .Cast (val_f .GetType ())
154
- self .assertFailure (bad_cast .GetError (),
155
- "Can only cast to a type that is equal to or smaller than the orignal type." )
156
- weird_cast = val_f .Cast (val_s .GetType ())
157
- self .assertSuccess (weird_cast .GetError (),
158
- "Can cast from a larger to a smaller" )
159
- self .assertEqual (weird_cast .GetChildMemberWithName ("a" ).GetValueAsSigned (0 ), 33 ,
160
- "Got the right value" )
151
+ # smaller type to a larger when the underlying data is not in the inferior,
152
+ # since then we have no way to fetch the out-of-bounds values.
153
+ # For an expression that references a variable, or a FindVariable result,
154
+ # or an SBValue made from an address and a type, we can get back to the target,
155
+ # so those will work. Make sure they do and get the right extra values as well.
156
+
157
+ # We're casting everything to the type of "f", so get that first:
158
+ f_var = frame0 .FindVariable ("f" )
159
+ self .assertSuccess (f_var .error , "Got f" )
160
+ bigger_type = f_var .GetType ()
161
+
162
+ # First try a value that we got from FindVariable
163
+ container = frame0 .FindVariable ("my_container" )
164
+ self .assertSuccess (container .error , "Found my_container" )
165
+ fv_small = container .GetValueForExpressionPath (".data.small" )
166
+ self .assertSuccess (fv_small .error , "Found small in my_container" )
167
+ fv_cast = fv_small .Cast (bigger_type )
168
+ self .assertSuccess (fv_cast .error , "Can cast up from FindVariable" )
169
+ child_checks = [
170
+ ValueCheck (name = "a" , value = "33" , type = "int" ),
171
+ ValueCheck (name = "b" , value = "44" , type = "int" ),
172
+ ValueCheck (name = "c" , value = "55" , type = "int" ),
173
+ ]
174
+ cast_check = ValueCheck (type = bigger_type .name , children = child_checks )
175
+
176
+ # Now try one we made with expr. This one should fail, because expr
177
+ # stores the "canonical value" in host memory, and doesn't know how
178
+ # to augment that from the live address.
179
+ expr_cont = frame0 .EvaluateExpression ("my_container" )
180
+ self .assertSuccess (expr_cont .error , "Got my_container by expr" )
181
+ expr_small = expr_cont .GetValueForExpressionPath (".data.small" )
182
+ self .assertSuccess (expr_small .error , "Got small by expr" )
183
+ expr_cast = expr_small .Cast (bigger_type )
184
+ self .assertFailure (expr_cast .error , msg = "Cannot cast expr result" )
185
+
186
+ # Now try one we made with CreateValueFromAddress. That will succeed
187
+ # because this directly tracks the inferior memory.
188
+ small_addr = fv_small .addr
189
+ self .assertTrue (small_addr .IsValid ())
190
+ small_type = fv_small .GetType ()
191
+ vfa_small = target .CreateValueFromAddress (
192
+ "small_from_addr" , small_addr , small_type
193
+ )
194
+ self .assertSuccess (vfa_small .error , "Made small from address" )
195
+ vfa_cast = vfa_small .Cast (bigger_type )
196
+ self .assertSuccess (vfa_cast .error , "Made a cast from vfa_small" )
197
+ cast_check .check_value (self , vfa_cast , "Cast of ValueFromAddress succeeds" )
198
+
199
+ # Next try ValueObject created from data. They should fail as there's no
200
+ # way to grow the data:
201
+ data_small = target .CreateValueFromData (
202
+ "small_from_data" , fv_small .data , fv_small .type
203
+ )
204
+ self .assertSuccess (data_small .error , "Made a valid object from data" )
205
+ data_cast = data_small .Cast (bigger_type )
206
+ self .assertFailure (data_cast .error , msg = "Cannot cast data backed SBValue" )
207
+
208
+ # Now check casting from a larger type to a smaller, we can always do this,
209
+ # so just test one case:
210
+ weird_cast = f_var .Cast (val_s .GetType ())
211
+ self .assertSuccess (weird_cast .GetError (), "Can cast from a larger to a smaller" )
212
+ self .assertEqual (
213
+ weird_cast .GetChildMemberWithName ("a" ).GetValueAsSigned (0 ),
214
+ 33 ,
215
+ "Got the right value" ,
216
+ )
161
217
162
218
# Check that lldb.value implements truth testing.
163
219
self .assertFalse (lldb .value (frame0 .FindVariable ("bogus" )))
0 commit comments