Categories:
Using nullptr in boolean context
!nullptr nullptr ? a : b // lldb : OK // lldb-eval : nullptr isn't contextually convertible to bool
Casting nullptr_t to bool
(bool)nullptr // lldb : false // lldb-eval : cast from pointer to smaller 'bool' loses information
Casting enums to floats
> (double)Enum::kOne // lldb : 1.0 // lldb-eval : 4E-324
Taking address of members of invalid class pointers
&((TestStruct*) invalid_ptr)->field) // lldb : OK (an address of type `int *`) // lldb-eval : no-value, no-error
invalid_ptr + offset(field) (which doesn‘t require reading from inaccessible memory). This works in LLDB, but it isn’t implemented in lldb-eval, because of exceptions where offset can't be determined statically, e.g.:field is a reference,field is a virtually inherited field.Array indirection
*array // lldb : <first element> // lldb-eval : indirection requires pointer operand ('int [3]' invalid)
Arrays in boolean context
array ? a : b // lldb : OK // lldb-eval : 'int [3]' is not contextually convertible to 'bool'
Enums as array subscript
array[an_enum] // lldb : OK // lldb-eval : array subscript is not an integer
Member access on class array
struct Foo { int x = 1; }; Foo foo_array[2]; > foo_array->x // lldb : 1 // lldb-eval : member reference type 'TestStruct [2]' is not a pointer; // did you mean to use '.'?
foo_array is contextually converted to pointer to the first element of the array. The final result is the x field of the first element of the array.Using compatible array and pointer types in conditional expression
condition ? array : pointer // lldb : OK // lldb-eval : invalid operands 'int [3]' and 'int *'
Arithmetics with array/enum references
int array[3] = {1, 2, 3}; int (&array_ref)[3] = array; // reference to 'array' > array_ref + 1 // lldb : OK // lldb-eval : invalid operands 'int [3]' and 'int' Enum an_enum = Enum::kOne; Enum& enum_ref = an_enum; > enum_ref - 1 // lldb : 0 // lldb-eval : Assertion failed!
Type::IsArrayType() and Type::IsUnscopedEnum() checks.Subscripting void*
&void_ptr[0] // lldb : error: subscript of pointer to incomplete type 'void' // lldb-eval : OK (an address)
Casting floats to bool
(bool)0.1 // lldb : true // lldb-eval : false
Enumeration comparison
enum Enum : int { A = -1, B } > Enum::A < Enum::B // lldb : true // lldb-eval : false
Compare(kind, lhs.GetUInt64(), rhs.GetUInt64()).namespace std had negative values on Linux)Arithmetic vs. logical shift
-4 >> 1 // lldb : 2 // lldb-eval : 2147483646
Type promotion in shift operation
-1 << 1U // lldb : -2 (int) // lldb-eval : 4294967294 (unsigned int)
Division by zero
> 1 / 0 > 1 % 0 // lldb : <random value> // lldb-eval : 0
Execution was interrupted, reason: Exception 0xc0000094 encountered at address 0x19c1f3b0105. The process has been returned to the state before expression evaluation. This process may take more than 10 seconds!Invalid memory access
> *invalid_ptr > invalid_ptr->field > &(invalid_ptr)->ref_field > &(invalid_ptr)->virtual_field
supposed to interpret, but failed: Interpreter couldn't read from memory. It could also results with “process being returned to the state before evaluation” which can take several seconds.Casting negative floats to unsigned integers
> (unsigned int)-1.5 // lldb : 0 // lldb-eval : 4294967295 > __log2(-1.5) // takes unsigned int // lldb : <random-value> (computes __log2 of a random unsigned int) // lldb-eval : 31 (computes __log2 of 4294967295)
Casting to different pointer type and dereferencing
int x = 2; > (int) *(bool*) &x // lldb : 2 // lldb-eval : 1
Null pointer arithmetic
(char*)0 + char_min // lldb : 0x00000000ffffff80 // lldb-eval : 0xffffffffffffff80
Subtracting ill-formed pointers
(int*)3 - (int*)(5 + __log2(100)) // lldb : -3 // lldb-eval : -2
sizeof(int) is 4, and difference of int* is expected to be a multiple of 4.Type name isn't identifiable without explicit use of struct or class keywords
// Test is class or struct > sizeof(Test) // lldb : 'Test' has unknown type; cast it to its declared type // lldb-eval : 24
Test was struct or class (e.g. there's no problem with union) that was defined globally under no-namespace and contained at least one non-static member.struct or class keyword, e.g. sizeof(struct Test).Similar example is:
> (Test*)ptr // lldb : expression failed to parse, fixed expression suggested: // (struct TestStruct*)0
this isn't compatible with its own type
// Test binary: struct TestStruct { ... }; TestStruct ts; // Using APIs: lldb::SBValue ts1 = frame.FindVariable("ts"); lldb::SBValue ts2 = frame.EvaluateExpression("ts"); > lldb_eval::EvaluateExpression(ts1, "this == (TestStruct*)this", ...); // OK (true) > lldb_eval::EvaluateExpression(ts2, "this == (TestStruct*)this", ...); // comparison of distinct pointer types ('TestStruct *' and 'TestStruct *')
lldb::SBType not working as expected.