llvm / llvm/llvm-project

Supposedly no-op trivial_abi attribute changes the result of __is_trivially_relocatable

Open
#222,294 2 comments 0 reactions 0 assignees View on GitHub
clang:frontend
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

The [docs](https://clang.llvm.org/docs/AttributeReference.html#trivial-abi) say that the trivial ABI attribute has no effect when there is a field that not itself trivial:

> Attribute `trivial_abi` has no effect in the following cases:
>
> * […]
> * The class has a non-static data member whose type is non-trivial for the purposes of calls, which includes[…]

Therefore this program should compile, I believe:

```c++
// Non-trivial
struct Foo {
~Foo();
};

// Non-trivial because it has a non-trivial field.
struct S1 {
Foo f;
};
static_assert(!__is_trivially_relocatable(S1));

// Ditto; the attribute should be a no-op.
struct [[clang::trivial_abi]] S2 {
Foo f;
};
static_assert(!__is_trivially_relocatable(S2));
```

([Compiler explorer](https://godbolt.org/z/KEeEM88rv))

However it doesn't work; although clang acknowledges with a warning that the attribute can't be used, it still changes the outcome of `__is_trivially_relocatable`:

```
:13:10: warning: 'trivial_abi' cannot be applied to 'S2' [-Wignored-attributes]
13 | struct [[clang::trivial_abi]] S2 {
| ^
:13:10: note: 'trivial_abi' is disallowed on 'S2' because it has a field of a non-trivial class type
:16:16: warning: builtin __is_trivially_relocatable is deprecated; use __builtin_is_cpp_trivially_relocatable instead [-Wdeprecated-builtins]
16 | static_assert(!__is_trivially_relocatable(S2));
| ^
:16:15: error: static assertion failed due to requirement '!__is_trivially_relocatable(S2)'
16 | static_assert(!__is_trivially_relocatable(S2));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

This [doesn't happen](https://godbolt.org/z/6Te1jvo5M) if you instead use `__builtin_is_cpp_trivially_relocatable`, but the attribute should be a no-op in both cases according to the docs.

Contributor guide

Open the contributing guide

Research direction

Start with the reduced C++ reproducer and compare the results of __is_trivially_relocatable and __builtin_is_cpp_trivially_relocatable when [[clang::trivial_abi]] is ignored. Trace the handling of the trivial_abi attribute and the deprecated builtin, then verify that the ignored attribute produces the same result as its absence and that the reproducer's static assertions pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.