llvm / llvm/llvm-project

Constant folding may turn the address of a stub into the address of its imported function

Open
#210,426 2 comments 0 reactions 0 assignees View on GitHub
clang:frontend constant-folding extension:microsoft miscompilation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

For the following C code:

```c
#include
__declspec(dllimport) void abort(void);
typedef void (*P)(void);
P p1 = abort;
const P p2 = abort;
int main() {
printf("p1\t%p\n", (void *)p1);
printf("p2\t%p\n", (void *)p2);
P p3 = *(const volatile P *)&p2;
printf("p3\t%p\n", (void *)p3);
printf("abort\t%p\n", (void *)abort);
}
```

A possible output is ([CE](https://godbolt.org/z/TcdxbP6bK)):

```
p1 00007FF7D81E3208
p2 00007FFCEE93CAA0
p3 00007FF7D81E3208
abort 00007FFCEE93CAA0
```

The object `p2` holds the same value as `p1` - that is, the address of the stub. However, when the value of the expression `p2` is printed, it is folded into the expression `abort`, which at block scope represents the address of the imported function. In other words, the expression `abort` evaluates to different values at file scope and block scope, but constant folding seemingly does not take that into account. In this case, it behaves like a macro substitution.

From the assembly, we can see that in the call to `printf`, the expression `p2` resolves to the entry `[__imp_abort]` (the imported function) instead of the symbol `abort` (the stub). This is an instance of miscompilation, although a minor one, since code does not usually depend on the address identity of a function.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the C example from the issue and inspecting the generated assembly around the printf calls, especially the differing handling of p2, p3, and abort. Trace the constant-folding path for imported functions and file-scope versus block-scope expressions. Done means p2 retains the address stored in the object rather than folding to the imported function address, with a regression test for the example.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.