Skip to content
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

fix: make PYBIND11_WARNING_POP actually pop clang diagnostics #5448

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

J-M0
Copy link

@J-M0 J-M0 commented Nov 24, 2024

Description

PYBIND11_WARNING_POP is defined for clang as PYBIND11_PRAGMA(clang diagnostic push), meaning ignored diagnostics don't actually get reset.

Suggested changelog entry:

``PYBIND11_WARNING_POP`` was incorrectly defined as ``PYBIND11_PRAGMA(clang diagnostic push)``

@rwgk
Copy link
Collaborator

rwgk commented Nov 24, 2024

Oh wow, thanks for catching this! I'm amazed how long that oversight survived.

Could you please help fixing up the C++20 failures?

From a quick search, I think this should work as a fix:

__VA_OPT__(,) __VA_ARGS__

I think you can use #if defined(PYBIND11_CPP20) (that is true for C++20 or higher).

@J-M0 J-M0 force-pushed the fix-clang-pop branch 3 times, most recently from d6d7c7a to 47b8c14 Compare November 29, 2024 03:42
@J-M0 J-M0 requested a review from henryiii as a code owner November 29, 2024 03:42
@J-M0
Copy link
Author

J-M0 commented Nov 29, 2024

I'm not sure if this is the right solution, but it's the best result I've gotten so far

@J-M0
Copy link
Author

J-M0 commented Nov 29, 2024

To expand a little more, until C++20, the standard required that at least one value be given for the ... in a variadic macro. GCC and clang both support calling a variadic macro with zero variadic arguments as an extension. The problem here is twofold:

  1. On C++20 and up, clang still wrongly flags empty __VA_ARGS__ as an extension.
    Clang wrongly warns about empty variadic argument lists for macros llvm/llvm-project#76375

  2. For older C++ versions, -Wno-gnu-zero-variadic-macro-arguments needs to be set before calling a variadic macro with zero variadic arguments. Disabling the warning can't be baked into the macro definition as far as I can tell. There are a lot of places where pybind11 uses empty __VA_ARGS__, so that's why I opted to ignore it globally in CMakeLists.txt. I'm worried though that this doesn't actually fix the problem for downstream pybind11 users.

@rwgk
Copy link
Collaborator

rwgk commented Nov 29, 2024

Oh sorry, what I had in mind is changing the C++ code to conditionally use the C++20 feature. (No cmake changes.)

I'll give it a try.

… rwgk why it does not work).

This is the beginning of the error message:

```
         D:\a\pybind11\pybind11\tests\test_smart_ptr.cpp(285,1): error C2143: syntax error: missing ')' before ',' [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
         D:\a\pybind11\pybind11\tests\test_smart_ptr.cpp(285,1): error C2059: syntax error: ')' [D:\a\pybind11\pybind11\build\tests\pybind11_tests.vcxproj]
```
…nts")` in test_smart_ptr.cpp

This is the error message:

```
/__w/pybind11/pybind11/tests/test_smart_ptr.cpp:287:51: error: must specify at least one argument for '...' parameter of variadic macro [-Werror,-Wgnu-zero-variadic-macro-arguments]
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>)
                                                  ^
/__w/pybind11/pybind11/include/pybind11/cast.h:885:13: note: macro 'PYBIND11_DECLARE_HOLDER_TYPE' defined here
            ^
```
…rguments")` in test_embed/test_interpreter.cpp
…uments")` near the top of pybind11/pybind11.h; 2. Change `PYBIND11_DECLARE_HOLDER_TYPE` macro to side-step the only remaining clang warning-as-error (this is still needed even for clang 18).

Alternatively the warning suppression could be moved into pybind11/cast.h, but this commit limits the warning suppression to smaller scope within include/pybind11.
@rwgk
Copy link
Collaborator

rwgk commented Nov 30, 2024

My idea that __VA_OPT__(,) __VA_ARGS__ could help only made the problem worse. However, while going down that rabbit hole I discovered that

  • the warnings related to the PYBIND11_OVERRIDE family of macros disappear with clang 14 or newer,

  • but the same warning is still generated for PYBIND11_DECLARE_HOLDER_TYPE even with clang18.

To get around both problems, I believe it's a useful compromise to

  • add a sticky (i.e. no push/pop) warning suppression in pybind11/pybind11.h for clang < 14 only, and

  • make a small change to the PYBIND11_DECLARE_HOLDER_TYPE macro in pybind11/cast.h to side-step the same warning there.

@J-M0
Copy link
Author

J-M0 commented Nov 30, 2024

Yeah I ran into those same problems too, but I see I didn't articulate that well. I did try to ignore the warning globally by adding it to PYBIND11_NAMESPACE_BEGIN() but that still had errors since the warning got popped.

So how do we want to go from here? Squash this PR down to two commits?

@rwgk
Copy link
Collaborator

rwgk commented Nov 30, 2024

Yeah I ran into those same problems too, but I see I didn't articulate that well. I did try to ignore the warning globally by adding it to PYBIND11_NAMESPACE_BEGIN() but that still had errors since the warning got popped.

So how do we want to go from here? Squash this PR down to two commits?

We always use Squash and merge.

While working on a PR, I find it very useful to never force push, and to leave a comment with each commit to explain the next step. That way it's easy for others to follow the progress, and also easier to backtrack.

I posted a review request in a chat room where other maintainers hang out. I'll wait a few days to see if anyone sends feedback.

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.

2 participants