Clang warning: A attribute only applies to a pointer or reference (B is invalid) [-Wignored-attributes] (warn_attribute_pointer_or_reference_only)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: A attribute only applies to a pointer or reference (B is invalid)
Type Warning
Category Semantic Issue
Internal Id warn_attribute_pointer_or_reference_only
Active by Default Yes
Flags -Wno-attributes (85 elements)
-Wno-ignored-attributes (84 elements)
Internal Message %0 attribute only applies to a pointer or reference (%1 is invalid)
Regular Expression (?:warning|error|fatal error)\: (.*?) attribute only applies to a pointer or reference \((.*?) is invalid\) \[(?:\-Werror,)?\-Wignored\-attributes[^\]]*\]
First Commit 2014-10-02 1b0d24e03abf Initial support for the align_value attribute

Description

The warning is issued by the Clang compiler when an attempt is made to apply an attribute to a variable that is not a pointer or reference type, even though the attribute in question is designed specifically for use with pointers or references. Attributes like these are intended to convey constraints or specify behaviors relevant only to memory addresses, rather than to immediate values or the objects themselves. The compiler generates this warning to alert the user about the incorrect usage of such an attribute, ensuring that attributes are applied appropriately to reflect their intended effects on the code's semantics. This helps in generating optimized and correct machine code. Typically, the attributes affected by this warning are those assuming or asserting characteristics about the alignment or memory-related behaviors of pointer or reference types.  
AI Generated

Example

In the following example, an attempt is made to apply the __attribute__((align_value(16))) attribute to an integer variable named x. The align_value attribute is intended to specify an alignment assumption for pointer or reference types, suggesting how the compiler should align memory addresses for efficient access. However, since x is neither a pointer nor a reference but rather a direct integer type, this usage is not valid according to the attribute's constraints. The compiler subsequently emits a warning message to indicate that the align_value attribute can only be applied to a pointer or reference, highlighting that the current application on a non-pointer/non-reference type (int) is invalid. This example demonstrates the compiler's mechanism to enforce attribute constraints and ensure that they are used according to their intended purpose.  
AI Generated


Flags -xc++ -std=c++17

[Try out in Compiler Explorer]

Source
int main() {
    // __attribute__ applied to a non-pointer/non-reference
    int x __attribute__((align_value(16)));
    return 0;
}
Compiler Output
<source>:3:26: warning: 'align_value' attribute only applies to a pointer or reference ('int' is invalid) [-Wignored-attributes]


Clang Internals (17.0.6)

Git Commit Message

Initial support for the align_value attribute

This adds support for the align_value attribute. This attribute is supported by
Intel's compiler (versions 14.0+), and several of my HPC users have requested
support in Clang. It specifies an alignment assumption on the values to which a
pointer points, and is used by numerical libraries to encourage efficient
generation of vector code.

Of course, we already have an aligned attribute that can specify enhanced
alignment for a type, so why is this additional attribute important? The
problem is that if you want to specify that an input array of T is, say,
64-byte aligned, you could try this:

  typedef double aligned_double attribute((aligned(64)));
  void foo(aligned_double *P) {
    double x = P[0]; // This is fine.
    double y = P[1]; // What alignment did those doubles have again?
  }

the access here to P[1] causes problems. P was specified as a pointer to type
aligned_double, and any object of type aligned_double must be 64-byte aligned.
But if P[0] is 64-byte aligned, then P[1] cannot be, and this access causes
undefined behavior. Getting round this problem requires a lot of awkward
casting and hand-unrolling of loops, all of which is bad.

With the align_value attribute, we can accomplish what we'd like in a well
defined way:

  typedef double *aligned_double_ptr attribute((align_value(64)));
  void foo(aligned_double_ptr P) {
    double x = P[0]; // This is fine.
    double y = P[1]; // This is fine too.
  }

This attribute does not create a new type (and so it not part of the type
system), and so will only "propagate" through templates, auto, etc. by
optimizer deduction after inlining. This seems consistent with Intel's
implementation (thanks to Alexey for confirming the various Intel-compiler
behaviors).

As a final note, I would have chosen to call this aligned_value, not
align_value, for better naming consistency with the aligned attribute, but I
think it would be more useful to users to adopt Intel's name.

llvm-svn: 218910

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/SemaDeclAttr.cpp (line 4322)

void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
  // ...
  if (!T->isDependentType() && !T->isAnyPointerType() && !T->isReferenceType() && !T->isMemberPointerType()) {
    Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only) << &TmpAttr << T << D->getSourceRange();

Triggered in Clang Tests

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

clang/test/Sema/align_value.c

  • clang/test/Sema/align_value.c:26:28: warning: 'align_value' attribute only applies to a pointer or reference ('int' is invalid) [-Wignored-attributes]