Quuxplusone / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
https://p1144.godbolt.org/z/jf67zx5hq
Other
0 stars 2 forks source link

Deleting the copy constructor makes Clang ignore [[clang::trivial_abi]] #26

Open Quuxplusone opened 9 months ago

Quuxplusone commented 9 months ago

f466f0beda59af1af182deb3cc8c006093d5a169 added a (non-suppressible) error when a [[trivial_abi]] struct's copy/move operations are all deleted. But that doesn't seem well-motivated to me. Whether a struct should be copied is a separate concern from whether it should be passed in registers / callee-destroyed.

https://godbolt.org/z/TPaarh3sa

#define ATTR [[clang::trivial_abi]]
struct ATTR S {
  int i = 42;
  S() { puts("constructed"); }
  S(const S&) { __builtin_unreachable(); }
  ~S() { puts("destroyed"); }
};

int f(S s) { return 0; }

int main() {
  return (f(S()), puts("hello"), 0);
}

This program correctly prints

constructed
destroyed
hello

because f's S parameter is trivial-abi and thus callee-destroy. S's copy constructor is unused, so we'd like to just delete it to avoid accidental calls. But if we do that, then the compiler starts ignoring the [[clang::trivial_abi]] attribute and the behavior of our code changes! https://godbolt.org/z/68cTbr1aM

#define ATTR [[clang::trivial_abi]]
struct ATTR S {
  int i = 42;
  S() { puts("constructed"); }
  S(const S&) = delete;
  ~S() { puts("destroyed"); }
};

int f(S s) { return 0; }

int main() {
  return (f(S()), puts("hello"), 0);
}

This program prints

constructed
hello
destroyed

because the attribute is now being ignored. The compiler does print a warning (if you don't pass -w or -Wno-attributes):

<source>:4:8: warning: 'trivial_abi' cannot be applied to 'S' [-Wignored-attributes]
    4 | struct ATTR S {
      |        ^
<source>:4:8: note: 'trivial_abi' is disallowed on 'S' because its copy constructors and move constructors are all deleted

I don't object to the warning; but it shouldn't ignore the attribute! It should obey the attribute and leave S as trivial-abi / callee-destroy. This would make for a simpler mental model.

https://github.com/llvm/llvm-project/issues/39031 is arguably related.