Skip to content

Move the [[noreturn]] attribute to the front of the declaration #12468

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 4 commits into from
Sep 27, 2023

Conversation

DMaroo
Copy link
Contributor

@DMaroo DMaroo commented Aug 4, 2023

C++17 requires attributes to be placed before the declaration specifiers. GCC 12 (and greater) seem to fail to compile when this syntax is not followed. There are no behavioral changes, only the attribute's position is moved.

Similar issue: jarro2783/cxxopts#353.

  * Needed in C++17

Signed-off-by: Dhruv Maroo <dhruvmaru007@gmail.com>
@xavierleroy
Copy link
Contributor

xavierleroy commented Aug 7, 2023

Thanks for pointing this out. I was not aware that attributes had stronger constraints than the _Noreturn modifier. A quick check with clang-15 -std=c2x suggests that C23 has the same constraints as C++17, i.e. [[noreturn]] static int f(void) is OK but static [[noreturn]] int f(void) is not.

The proposed fix is fine, but I'm concerned that the problem will come back over and over again as we add new "noreturn" functions to the runtime system and compile with pre-C23 compilers. That [[noreturn]] should go first is visually apparent. However, when the attribute is hidden behind macros, it's not visually obvious that CAMLnoret CAMLextern is good and CAMLextern CAMLnoret is bad. But I don't see any other way out of this problem, except going back to using GCC/Clang attribute((noreturn)).

@xavierleroy xavierleroy self-assigned this Aug 7, 2023
@DMaroo
Copy link
Contributor Author

DMaroo commented Aug 7, 2023

Wouldn't updating the CI to use a newer version of the compiler (C23 compliant) prevent any non-compliant changes from being merged? I think it may (?) be safe to assume that this behavior of the [[noreturn]] attribute won't be changing in the future versions of the compilers.

@xavierleroy
Copy link
Contributor

Wouldn't updating the CI to use a newer version of the compiler (C23 compliant) prevent any non-compliant changes from being merged?

Yes, eventually. Right now, C23 is not yet published as a standard, support by GCC and Clang is spotty, and C23 is not their default mode, so it will take some time and some effort to get C23 in CI.

@DMaroo
Copy link
Contributor Author

DMaroo commented Aug 8, 2023

Makes sense.

@xavierleroy
Copy link
Contributor

xavierleroy commented Aug 31, 2023

I'm making slow progress on this issue. It turns out that one of our CI machines runs the latest Ubuntu version, which has clang version 15, which supports a lot of C23, including the [[noreturn]] attribute. However, selecting this C23 preliminary support with -std=c2x or -std=gnu2x sets __STDC_VERSION__ to 202000L, too low for the [[noreturn]] definition of CAMLnoret to be picked. However squared, the following incantation works

CC=clang CFLAGS="-std=gnu2x -U__STDC_VERSION__ -D__STDC_VERSION__=202300L" ./configure

in that it turns C23 features on and pretends to be C23 compliant.

With that I can see the "misplaced attributes" errors, check that this PR fixes a number of them, but leaves out some others, which I could fix easily. (I'll add the fix to this PR soon.) So, it seems to work well as a "C23 readiness" check, and could be integrated in the Jenkins CI at Inria.

…ntinued

Also needed in C 23, meaning it must be applied to source files and internal
header files as well.
@DMaroo
Copy link
Contributor Author

DMaroo commented Sep 1, 2023

Ah okay. It's weird that one needs to manually set __STDC_VERSION__ to get C23 features. Anyways, thank you for adding the remaining fixes.

@xavierleroy
Copy link
Contributor

We need to do something here, since #12235 introduced an incompatibility with C++17 and the upcoming C23: either we revert #12235 or move forward and merge this PR. I move to merge this PR, and try to have it tested by Jenkins CI as outlined above. If it doesn't work it will always be possible to revert both this PR and #12235.

@gasche
Copy link
Member

gasche commented Sep 27, 2023

Your plan (merge here + improve CI) sounds excellent to me. Is there something that would help besides this bystander opinion?

(Note: it would be nice to have a comment on the CAMLnoret definition that it needs to be placed at the beginning of the declaration.)

@xavierleroy
Copy link
Contributor

(Note: it would be nice to have a comment on the CAMLnoret definition that it needs to be placed at the beginning of the declaration.)

Good idea! See 8c02bd9. Time to merge!

@xavierleroy xavierleroy merged commit 1dbc010 into ocaml:trunk Sep 27, 2023
@xavierleroy
Copy link
Contributor

We're out of luck: clang 17 refuses to un-define __STDC_VERSION__ ...

In file included from <built-in>:385:
<command line>:1:8: error: undefining builtin macro [-Werror,-Wbuiltin-macro-redefined]
    1 | #undef __STDC_VERSION__

Checkmate! I give up on trying to test C23 conformance before C23 is officially released. Too bad...

sadiqj pushed a commit to sadiqj/ocaml that referenced this pull request Oct 8, 2023
…aml#12468)

* Move the `[[noreturn]]` attribute to the front of the declarations in <caml/*.h>
Needed in C++17.

* Move the `[[noreturn]]` attribute to the front of the definitions
Also needed in C 23, meaning that the move must be applied
to source files and internal header files as well.

* Document that `CAMLnoret` must occur first in declarations

Signed-off-by: Dhruv Maroo <dhruvmaru007@gmail.com>
Co-authored-by: Xavier Leroy <xavier.leroy@college-de-france.fr>
@DMaroo DMaroo deleted the fix-noreturn-position branch January 4, 2024 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants