Clang note: 'trivial_abi' is disallowed on A because ... (note_cannot_use_trivial_abi_reason)

From emmtrix Wiki
Jump to navigation Jump to search
Text
error: 'trivial_abi' is disallowed on A because
its copy constructors and move constructors are all deleted
it is polymorphic
it has a base of a non-trivial class type
it has a virtual base
it has a __weak field
it has a field of a non-trivial class type

(since 11.0)

Type Note
Category Semantic Issue (since 11.0)
Internal Id note_cannot_use_trivial_abi_reason (since 11.0)
Internal Message 'trivial_abi' is disallowed on %0 because %select{its copy constructors and move constructors are all deleted|it is polymorphic|it has a base of a non-trivial class type|it has a virtual base|it has a __weak field|it has a field of a non-trivial class type}1 (since 11.0)
Regular Expression note\: 'trivial_abi' is disallowed on (.*?) because (?:its copy constructors and move constructors are all deleted|it is polymorphic|it has a base of a non\-trivial class type|it has a virtual base|it has a __weak field|it has a field of a non\-trivial class type)
First Commit 2020-02-28 14f6bfcb52e7 [clang] Implement objc_non_runtime_protocol to remove protocol metadata

Description

The note is issued by the Clang compiler when an attempt is made to apply the [[clang::trivial_abi]] attribute to a type that does not meet the necessary conditions for such an attribute to be valid. The [[clang::trivial_abi]] attribute is designed to optimize the Application Binary Interface (ABI) of trivially copyable types by allowing them to be passed in registers instead of through memory, which can improve the efficiency of function calls. However, certain characteristics of a type can prevent it from being considered trivially copyable in this context. These characteristics include:
  • The type's copy constructors and move constructors are all explicitly deleted. Constructors are essential for creating and copying objects, and if a type has its copy or move constructors deleted, it cannot be trivially copied or moved, negating the benefits of the [[clang::trivial_abi]] attribute.
  • The type is polymorphic, meaning it has one or more virtual functions. Polymorphism introduces a level of complexity that requires runtime type information, which is not compatible with the assumptions made by the [[clang::trivial_abi]] attribute.
  • The type inherits from a base class that is not considered trivial. The presence of non-trivial class types as bases can introduce complexities in copying and object layout that are incompatible with the [[clang::trivial_abi]] attribute.
  • The type has a virtual base class. Virtual base classes introduce additional complexity in the object layout that prevents the type from being trivially copyable.
  • The type contains a field marked with the __weak keyword, indicating a weak reference in Objective-C, which introduces additional runtime behaviors and requirements that are incompatible with a trivial ABI.
  • The type has a non-static data member of a non-trivial class type, which can introduce complexities in copying and destruction that prevent the type from being trivially copyable.

When any of these conditions are met, the Clang compiler issues a note explaining why the [[clang::trivial_abi]] attribute cannot be applied to the type in question. This ensures that developers are aware of the restrictions on the use of this attribute and the reasons behind them.

 
AI Generated

Example

In the following example, a structure named S is declared with the [[clang::trivial_abi]] attribute. This attribute is intended to optimize the Application Binary Interface (ABI) by allowing types to be passed more efficiently. However, the structure S also defines a virtual function, f(), making it polymorphic. Polymorphism is one of the conditions that disallow the use of the [[clang::trivial_abi]] attribute, as it introduces complexity that requires runtime type information, incompatible with the assumptions of the [[clang::trivial_abi]] attribute. Consequently, the Clang compiler issues a warning indicating that the [[clang::trivial_abi]] attribute cannot be applied to S due to its polymorphic nature. This serves as a demonstration of the compiler's checks for attribute applicability based on the characteristics of the type to which it is being applied.  
AI Generated


Flags -xc++

[Try out in Compiler Explorer]

Source
struct [[clang::trivial_abi]] S { virtual void f() {}; }; // polymorphic
Compiler Output
<source>:1:10: warning: 'trivial_abi' cannot be applied to 'S' [-Wignored-attributes]
<source>:1:10: note: 'trivial_abi' is disallowed on 'S' because it is polymorphic


Clang Internals (17.0.6)

Git Commit Message

[clang] Implement objc_non_runtime_protocol to remove protocol metadata

Summary:
Motivated by the new objc_direct attribute, this change adds a new
attribute that remotes metadata from Protocols that the programmer knows
isn't going to be used at runtime. We simply have the frontend skip
generating any protocol metadata entries (e.g. OBJC_CLASS_NAME,
_OBJC_$_PROTOCOL_INSTANCE_METHDOS, _OBJC_PROTOCOL, etc) for a protocol
marked with `__attribute__((objc_non_runtime_protocol))`.

There are a few APIs used to retrieve a protocol at runtime.
`@protocol(SomeProtocol)` will now error out of the requested protocol
is marked with attribute. `objc_getProtocol` will return `NULL` which
is consistent with the behavior of a non-existing protocol.

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D75574

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaDeclCXX.cpp (line 10303)

void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) {
  auto PrintDiagAndRemoveAttr = [&](unsigned N) {
    // No diagnostics if this is a template instantiation.
    if (!isTemplateInstantiation(RD.getTemplateSpecializationKind())) {
      // ...
      Diag(RD.getAttr<TrivialABIAttr>()->getLocation(), diag::note_cannot_use_trivial_abi_reason) << &RD << N;

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/SemaCXX/attr-trivial-abi.cpp

  • clang/test/SemaCXX/attr-trivial-abi.cpp:28:23: note: 'trivial_abi' is disallowed on 'S3' because it is polymorphic
  • clang/test/SemaCXX/attr-trivial-abi.cpp:35:18: note: 'trivial_abi' is disallowed on 'S3_2' because it is polymorphic
  • clang/test/SemaCXX/attr-trivial-abi.cpp:38:23: note: 'trivial_abi' is disallowed on 'S3_3' because it has a field of a non-trivial class type
  • clang/test/SemaCXX/attr-trivial-abi.cpp:53:23: note: 'trivial_abi' is disallowed on 'S3_4' because it has a field of a non-trivial class type
  • clang/test/SemaCXX/attr-trivial-abi.cpp:64:23: note: 'trivial_abi' is disallowed on 'S5' because it has a virtual base
  • clang/test/SemaCXX/attr-trivial-abi.cpp:117:23: note: 'trivial_abi' is disallowed on 'CopyMoveDeleted' because its copy constructors and move constructors are all deleted
  • clang/test/SemaCXX/attr-trivial-abi.cpp:127:23: note: 'trivial_abi' is disallowed on 'S18' because its copy constructors and move constructors are all deleted
  • clang/test/SemaCXX/attr-trivial-abi.cpp:152:23: note: 'trivial_abi' is disallowed on 'S19' because its copy constructors and move constructors are all deleted