Skip to content

Inferred return value location does not update when changing return type of function #8233

@bdash

Description

@bdash

Version and Platform (required):

  • Binary Ninja Version: 5.4.9744-dev Ultimate, d7f134fd
  • OS: macos 26.5.0
  • CPU Architecture: arm64

Bug Description:
When changing a function of type int64_t GetPoint() __pure to have a return type of struct Point, the return value location remains fixed at __location("x0"), despite Point being too large to fit within x0. Since the return value location was originally inferred by analysis, updating the return type should cause it to be recomputed.

Steps To Reproduce:

  1. Open libtest.dylib from the attached zip file.
  2. Observe that GetPoint looks like so:
DisassemblyHLIL
004002d0    int64_t GetPoint() __pure

004002d0     0  20078652   mov     w0, #0x3039
004002d4     0  41268152   mov     w1, #0x932
004002d8     0  2100a072   movk    w1, #0x1, lsl #0x10  {0x10932}
004002dc     0  c0035fd6   ret     
004002d0    int64_t GetPoint() __pure

004002dc        return 0x3039
  1. Define a type struct Point { uint64_t x, y; };.
  2. Change the return type of GetPoint to Point.
  3. GetPoint updates to look like so. Note the explicit __location("x0") override:
DisassemblyHLIL
004002d0    struct Point GetPoint() __location("x0") __pure

004002d0     0  20078652   mov     w0, #0x3039
004002d4     0  41268152   mov     w1, #0x932
004002d8     0  2100a072   movk    w1, #0x1, lsl #0x10  {0x10932}
004002dc     0  c0035fd6   ret     
004002d0    struct Point GetPoint() __location("x0") __pure

004002dc        return 0x3039
  1. Use Edit Function Properties to change the return value's "source" from Custom to Default. Note that the location column updates to x1:x0 when doing this.
  2. GetPoint has now updated to have the expected HLIL:
DisassemblyHLIL
004002d0    struct Point GetPoint() __pure

004002d0     0  20078652   mov     w0, #0x3039
004002d4     0  41268152   mov     w1, #0x932
004002d8     0  2100a072   movk    w1, #0x1, lsl #0x10  {0x10932}
004002dc     0  c0035fd6   ret     
004002d0    struct Point GetPoint() __pure

004002d0        struct Point result
004002d0        result.x = 0x3039
004002d0        result.y = 0x10932
004002dc        return result

Expected Behavior:
Changing the type in step 4 should be sufficient to update the return value location. It should not be necessary to explicitly reset the return value's "source" to Default since the user never explicitly changed it from Default.

Binary:
libtest.dylib.zip

Created via:

mrowe@quicksilver:~$ cat test.cpp
#include <stdint.h>

struct Point {
    uint64_t x;
    uint64_t y;
};

Point GetPoint()
{
    return { 12345, 67890 };
}

mrowe@quicksilver:~$ cc -Os -shared -o libtest.dylib test.cpp
mrowe@quicksilver:~$

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions