Skip to content

Commit 25909b8

Browse files
jeffreytan81jeffreytan81
and
jeffreytan81
authored
Fix pointer to reference type (#113596)
We have got customer reporting "v &obj" and "p &obj" reporting different results. Turns out it only happens for obj that is itself a reference type which "v &obj" reports the address of the reference itself instead of the target object the reference points to. This diverged from C++ semantics. This PR fixes this issue by returning the address of the dereferenced object if it is reference type. A new test is added which fails before. Co-authored-by: jeffreytan81 <[email protected]>
1 parent 455f71d commit 25909b8

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

lldb/source/Core/ValueObject.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,6 +2911,15 @@ ValueObjectSP ValueObject::AddressOf(Status &error) {
29112911

29122912
AddressType address_type = eAddressTypeInvalid;
29132913
const bool scalar_is_load_address = false;
2914+
2915+
// For reference type we need to get the address of the object that
2916+
// it refers to.
2917+
if (GetCompilerType().IsReferenceType()) {
2918+
ValueObjectSP deref_obj = Dereference(error);
2919+
if (error.Fail() || !deref_obj)
2920+
return ValueObjectSP();
2921+
return deref_obj->AddressOf(error);
2922+
}
29142923
addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
29152924
error.Clear();
29162925
if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {

lldb/test/API/lang/cpp/dereferencing_references/TestCPPDereferencingReferences.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,24 @@ def test(self):
2525
# Typedef to a reference should dereference to the underlying type.
2626
td_val = self.expect_var_path("td_to_ref_type", type="td_int_ref")
2727
self.assertEqual(td_val.Dereference().GetType().GetName(), "int")
28+
29+
def test_take_address_of_reference(self):
30+
"""Tests taking address of lvalue/rvalue references in lldb works correctly."""
31+
self.build()
32+
lldbutil.run_to_source_breakpoint(
33+
self, "// break here", lldb.SBFileSpec("main.cpp")
34+
)
35+
36+
plref_val_from_code = self.expect_var_path("pl_ref", type="TTT *")
37+
plref_val_from_expr_path = self.expect_var_path("&l_ref", type="TTT *")
38+
self.assertEqual(
39+
plref_val_from_code.GetValueAsAddress(),
40+
plref_val_from_expr_path.GetValueAsAddress(),
41+
)
42+
43+
prref_val_from_code = self.expect_var_path("pr_ref", type="TTT *")
44+
prref_val_from_expr_path = self.expect_var_path("&r_ref", type="TTT *")
45+
self.assertEqual(
46+
prref_val_from_code.GetValueAsAddress(),
47+
prref_val_from_expr_path.GetValueAsAddress(),
48+
)

lldb/test/API/lang/cpp/dereferencing_references/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ int main() {
99
// typedef of a reference
1010
td_int_ref td_to_ref_type = i;
1111

12+
TTT *pl_ref = &l_ref;
13+
TTT *pr_ref = &r_ref;
1214
return l_ref; // break here
1315
}

0 commit comments

Comments
 (0)