mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[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:
@@ -147,7 +147,7 @@ public:
|
||||
return std::string(ss.GetString());
|
||||
}
|
||||
|
||||
bool AssignToMatchType(lldb_private::Scalar &scalar, uint64_t u64value,
|
||||
bool AssignToMatchType(lldb_private::Scalar &scalar, llvm::APInt value,
|
||||
Type *type) {
|
||||
size_t type_size = m_target_data.getTypeStoreSize(type);
|
||||
|
||||
@@ -157,7 +157,7 @@ public:
|
||||
if (type_size != 1)
|
||||
type_size = PowerOf2Ceil(type_size);
|
||||
|
||||
scalar = llvm::APInt(type_size*8, u64value);
|
||||
scalar = value.zextOrTrunc(type_size * 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -171,8 +171,7 @@ public:
|
||||
if (!ResolveConstantValue(value_apint, constant))
|
||||
return false;
|
||||
|
||||
return AssignToMatchType(scalar, value_apint.getLimitedValue(),
|
||||
value->getType());
|
||||
return AssignToMatchType(scalar, value_apint, value->getType());
|
||||
}
|
||||
|
||||
lldb::addr_t process_address = ResolveValue(value, module);
|
||||
@@ -190,13 +189,14 @@ public:
|
||||
lldb::offset_t offset = 0;
|
||||
if (value_size <= 8) {
|
||||
uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
|
||||
return AssignToMatchType(scalar, u64value, value->getType());
|
||||
return AssignToMatchType(scalar, llvm::APInt(64, u64value),
|
||||
value->getType());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AssignValue(const Value *value, lldb_private::Scalar &scalar,
|
||||
bool AssignValue(const Value *value, lldb_private::Scalar scalar,
|
||||
Module &module) {
|
||||
lldb::addr_t process_address = ResolveValue(value, module);
|
||||
|
||||
@@ -205,7 +205,9 @@ public:
|
||||
|
||||
lldb_private::Scalar cast_scalar;
|
||||
|
||||
if (!AssignToMatchType(cast_scalar, scalar.ULongLong(), value->getType()))
|
||||
scalar.MakeUnsigned();
|
||||
if (!AssignToMatchType(cast_scalar, scalar.UInt128(llvm::APInt()),
|
||||
value->getType()))
|
||||
return false;
|
||||
|
||||
size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType());
|
||||
|
||||
Reference in New Issue
Block a user