[lldb] Fix type conversion in the Scalar getters
Summary:
The Scalar class claims to follow the C type conversion rules. This is
true for the Promote function, but it is not true for the implicit
conversions done in the getter methods.
These functions had a subtle bug: when extending the type, they used the
signedness of the *target* type in order to determine whether to do
sign-extension or zero-extension. This is not how things work in C,
which uses the signedness of the *source* type. I.e., C does
(sign-)extension before it does signed->unsigned conversion, and not the
other way around.
This means that: (unsigned long)(int)-1
is equal to (unsigned long)0xffffffffffffffff
and not (unsigned long)0x00000000ffffffff
Unsurprisingly, we have accumulated code which depended on this
inconsistent behavior. It mainly manifested itself as code calling
"ULongLong/SLongLong" as a way to get the value of the Scalar object in
a primitive type that is "large enough". Previously, the ULongLong
conversion did not do sign-extension, but now it does.
This patch makes the Scalar getters consistent with the declared
semantics, and fixes the couple of call sites that were using it
incorrectly.
Reviewers: teemperor, JDevlieghere
Subscribers: lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D82772
This commit is contained in:
@@ -1203,6 +1203,7 @@ uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
|
||||
if (ResolveValue(scalar)) {
|
||||
if (success)
|
||||
*success = true;
|
||||
scalar.MakeUnsigned();
|
||||
return scalar.ULongLong(fail_value);
|
||||
}
|
||||
// fallthrough, otherwise...
|
||||
@@ -1220,6 +1221,7 @@ int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
|
||||
if (ResolveValue(scalar)) {
|
||||
if (success)
|
||||
*success = true;
|
||||
scalar.MakeSigned();
|
||||
return scalar.SLongLong(fail_value);
|
||||
}
|
||||
// fallthrough, otherwise...
|
||||
|
||||
Reference in New Issue
Block a user