llvm / llvm/llvm-project

[Clang] Miscompilation when a variable name overlaps with the Intel-syntax `not` operator

Open
#195,970 8 comments 0 reactions 0 assignees View on GitHub
backend:X86 llvm:mc miscompilation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

I observed that Clang can mishandle C variable names when emitting
Intel-syntax assembly if the symbol names overlap with Intel-syntax operator
tokens such as `not`.

In the example below, the global variable `not` is emitted as a bare identifier
and is misinterpreted as the Intel-syntax unary `not` operator rather than as
a symbol.

Minimal reproducer:

```c
#include

char not[] = {1, 2, 3, 4};

int main(void) {
int cnt;
for (cnt = 0; cnt < 4; ++cnt)
printf("%d\n", not[3 - cnt]);
return 0;
}
```
Command:
```
$ clang-22 -m32 -fno-pie -O1 --save-temps -masm=intel test.c
$ ./a.out
Program terminated with signal: SIGSEGV
```

Relevant emitted assembly:
```
movsx eax, byte ptr [esi + not-1]
```
After assembly, this becomes:
```
movsx eax, BYTE PTR [esi]
```
It appears that the assembler evaluates not-1 as not (-1), which becomes 0,
instead of treating not as the global symbol.

Notes:
* Reproduced with Clang v15~v22.
* The issue is observable with -masm=intel and --save-temps.

Contributor guide

Open the contributing guide

Research direction

Start by running the provided C reproducer with clang-22 using -m32 -fno-pie -O1 --save-temps -masm=intel, then inspect the emitted assembly containing [esi + not-1]. Compare how the Intel-syntax output represents the global symbol not; done means the assembler treats it as a symbol rather than the not operator and the program no longer crashes.

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
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.