llvm / llvm/llvm-project

[Clang] Suppressing -Wc2y-extensions does not work as expected

Open
#189,645 7 comments 0 reactions 0 assignees View on GitHub
c2y clang:diagnostics confirmed quality-of-implementation
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

I have difficulty suppressing `-Wc2y-extensions` when using `__COUNTER__` to generate unique C++ identifiers.

[I minimized this reproducer from Catch2:](https://godbolt.org/z/Thq77b9WG)
```cpp
#if defined(REAL_SUPPRESS)
#define SUPPRESS_WARNING _Pragma( "clang diagnostic ignored \"-Wc2y-extensions\"" )
#else
#define SUPPRESS_WARNING
#endif

#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line
#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) \
INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )

#define INTERNAL_CATCH_UNIQUE_NAME( name ) \
SUPPRESS_WARNING \
INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )

#define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \
static void TestName(); \
static void TestName()

#define INTERNAL_CATCH_TESTCASE( ... ) \
INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )

#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )

TEST_CASE() {}
```

Surprisingly, when preprocessing the input I can see the diagnostic pragma there before the identifier:
```
$ clang++-23 -Wc2y-extensions foo.cpp -E -fkeep-system-includes -DREAL_SUPPRESS
# 1 "foo.cpp"
# 1 "" 1
# 1 "" 1
# 1 "" 2
# 1 "foo.cpp" 2
foo.cpp:27:1: warning: '__COUNTER__' is a C2y extension [-Wc2y-extensions]
27 | TEST_CASE() {}
| ^
foo.cpp:24:26: note: expanded from macro 'TEST_CASE'
24 | #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )
| ^
foo.cpp:22:31: note: expanded from macro 'INTERNAL_CATCH_TESTCASE'
22 | INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( CATCH2_INTERNAL_TEST_ ), __VA_ARGS__ )
| ^
foo.cpp:14:44: note: expanded from macro 'INTERNAL_CATCH_UNIQUE_NAME'
14 | INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )
| ^
# 27 "foo.cpp"
static void
# 27 "foo.cpp"
#pragma clang diagnostic ignored "-Wc2y-extensions"
# 27 "foo.cpp"
CATCH2_INTERNAL_TEST_0(); static void
# 27 "foo.cpp"
#pragma clang diagnostic ignored "-Wc2y-extensions"
# 27 "foo.cpp"
CATCH2_INTERNAL_TEST_0() {}
1 warning generated.
```

Notice the suppression pragma above the `CATCH2_INTERNAL_TEST_0` identifier.

Since adding more lines with `TEST_CASE(){}` doesn't trigger more warnings with `-DREAL_SUPPRESS`, but does without it, we can see that the actual diagnostic suppression pragma works, but I guess that for some reason Clang issues the first warning before the actual `__COUNTER__` usage.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.