Skip to content

[clang] Fix gnu::init_priority attribute handling for reserved values #121577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ Attribute Changes in Clang
``__attribute__((model("large")))`` on non-TLS globals in x86-64 compilations.
This forces the global to be considered small or large in regards to the
x86-64 code model, regardless of the code model specified for the compilation.
- Clang now emits a warning ``-Wreserved-init-priority`` instead of a hard error
when ``__attribute__((init_priority(n)))`` is used with values of n in the
reserved range [0, 100]. The warning will be treated as an error by default.

- There is a new ``format_matches`` attribute to complement the existing
``format`` attribute. ``format_matches`` allows the compiler to verify that
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -3335,6 +3335,9 @@ def err_attribute_argument_out_of_range : Error<
def err_init_priority_object_attr : Error<
"can only use 'init_priority' attribute on file-scope definitions "
"of objects of class type">;
def warn_init_priority_reserved : Warning<
"requested 'init_priority' %0 is reserved for internal use">,
InGroup<DiagGroup<"init-priority-reserved">>, DefaultError;
def err_attribute_argument_out_of_bounds : Error<
"%0 attribute parameter %1 is out of bounds">;
def err_attribute_only_once_per_parameter : Error<
Expand Down
14 changes: 8 additions & 6 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3644,16 +3644,18 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}

// Only perform the priority check if the attribute is outside of a system
// header. Values <= 100 are reserved for the implementation, and libc++
// benefits from being able to specify values in that range.
if ((prioritynum < 101 || prioritynum > 65535) &&
!S.getSourceManager().isInSystemHeader(AL.getLoc())) {
if (prioritynum > 65535) {
S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
<< E->getSourceRange() << AL << 101 << 65535;
<< E->getSourceRange() << AL << 0 << 65535;
AL.setInvalid();
return;
}

// Values <= 100 are reserved for the implementation, and libc++
// benefits from being able to specify values in that range.
if (prioritynum < 101)
S.Diag(AL.getLoc(), diag::warn_init_priority_reserved)
<< E->getSourceRange() << prioritynum;
D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
}

Expand Down
30 changes: 19 additions & 11 deletions clang/test/SemaCXX/init-priority-attr.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -verify %s
// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -DSYSTEM -verify %s
// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -DNOERROR -Wno-error=init-priority-reserved -verify %s
// RUN: %clang_cc1 -triple=s390x-none-zos -fsyntax-only -verify=unknown %s
// RUN: %clang_cc1 -triple=s390x-none-zos -fsyntax-only -DSYSTEM -verify=unknown-system %s

Expand All @@ -24,32 +25,39 @@ extern Two goo;
extern Two coo[];
extern Two koo[];

// unknown-system-no-diagnostics

Two foo __attribute__((init_priority(101))) ( 5, 6 );
// unknown-system-no-diagnostics
// unknown-warning@-2 {{unknown attribute 'init_priority' ignored}}
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}

Two loo __attribute__((init_priority(65535))) ( 5, 6 );
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}

Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{'init_priority' attribute takes one argument}}
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}

Two coo[2] __attribute__((init_priority(100)));
#if !defined(SYSTEM)
// expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
// unknown-warning@-3 {{unknown attribute 'init_priority' ignored}}
#endif
#if !defined(NOERROR)
// expected-error@-3 {{requested 'init_priority' 100 is reserved for internal use}}
#else // defined(NOERROR)
// expected-warning@-5 {{requested 'init_priority' 100 is reserved for internal use}}
#endif // !defined(NOERROR)
// unknown-warning@-7 {{unknown attribute 'init_priority' ignored}}
#endif // !defined(SYSTEM)

Two boo[2] __attribute__((init_priority(65536)));
#if !defined(SYSTEM)
// expected-error@-2 {{'init_priority' attribute requires integer constant between 101 and 65535 inclusive}}
// unknown-warning@-3 {{unknown attribute 'init_priority' ignored}}
#endif
Two zoo[2] __attribute__((init_priority(-1))); // expected-error {{'init_priority' attribute requires integer constant between 0 and 65535 inclusive}}
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}

Two boo[2] __attribute__((init_priority(65536))); // expected-error {{'init_priority' attribute requires integer constant between 0 and 65535 inclusive}}
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}

Two koo[4] __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}}
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}

Two func() __attribute__((init_priority(1001))); // expected-error {{'init_priority' attribute only applies to variables}}
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}


int i __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
// unknown-warning@-1 {{unknown attribute 'init_priority' ignored}}

Expand Down