llvm / llvm/llvm-project

Clang rejects valid C11 code: invalid operands to binary expression for _Atomic types returned from functions

Open
#179,403 3 comments 0 reactions 0 assignees View on GitHub
c11 clang:frontend confirmed rejects-valid
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

### Description:
Clang fails to compile valid C11 code that compares two _Atomic objects using the != operator when one operand is a function return value. The same comparison works correctly when both operands are variables (not function returns). GCC accepts this code without errors.

### Reproducer:
[Live demo on Godbolt Compiler Explorer](https://godbolt.org/z/o6zPo3Ko5)

```c
#include
#include

int test(atomic_size_t a, atomic_size_t b) {
return a != b;
}

atomic_size_t foo(atomic_size_t a) {
return a;
}

int test_OK(atomic_size_t a, atomic_size_t b) {
atomic_size_t c = foo(a);
return c != b;
}

int test_error(atomic_size_t a, atomic_size_t b) {
return foo(a) != b;
}

```

### Output:

```
:18:19: error: invalid operands to binary expression ('atomic_size_t' (aka '_Atomic(size_t)') and 'atomic_size_t')
18 | return foo(a) != b;
| ~~~~~~ ^ ~
1 error generated.
Compiler returned: 1
```

### Expected Behavior:
The code should compile successfully, as atomic_size_t (aka _Atomic(size_t)) objects should be comparable using the != operator regardless of whether they are variables or function return values. This is consistent with C11 standard section 6.5.9 (Equality operators) which allows comparison of atomic types.

### Environment:

Clang version: 21.1.0 (also reproduced on other version)
Target: riscv32-unknown-unknown-elf (also reproduced on arm and x86)
GCC comparison: GCC 15.2.0 accepts this code

### Additional Context:
This appears to be a semantic analysis issue where Clang fails to properly handle value categories or type decay for atomic types when they are returned from functions. The direct comparison a != b works because both are lvalues of atomic type, but foo(a) != b fails because foo(a) is an rvalue (function return), suggesting Clang is not applying the same type conversion rules for atomic types in this context.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.