[clang] _Pragma() in macro interfering with macro return type
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
I have a macro that started behaving differently after upgrading to clang-22, it worked previously in CI for:
- GCC - 10, 11, 12, 13, 14, 15
- Clang - 13, 14, 15, 16, 17, 18, 19, 20, 21
Minimal example:
```c
#include
#include
size_t
_cexds__arr_len(const void* arr)
{
// This function is a mock for returning length of dynamic arrays
return (arr) ? 6969 : 0;
}
# define arr$len(arr) \
({ \
_Pragma("GCC diagnostic push"); \
/* NOTE: temporary disable syntax error to support both static array length and \
* arr$(T) */ \
_Pragma("GCC diagnostic ignored \"-Wsizeof-pointer-div\""); \
/* NOLINTBEGIN */ \
__builtin_types_compatible_p( \
typeof(arr), \
typeof(&(arr)[0]) \
) /* check if array or ptr */ \
? _cexds__arr_len(arr) /* some pointer or arr$ */ \
: ( \
sizeof(arr) / sizeof((arr)[0]) /* static array[] */ \
); \
/* NOLINTEND */ \
_Pragma("GCC diagnostic pop"); \
})
int main(int argc, char** argv) {
char* a[] = {"a", "b"};
printf("a is static, arr$len=%zu\n", arr$len(a));
char* a1 = (void*)0xbadcaffe;
printf("a is kinda dynamic, arr$len=%zu\n", arr$len(a1));
return 0;
}
```
Returns:
```
~/code/cex/clang22issues ➜ /home/av/code/emsdk/upstream/bin/clang -ferror-limit=100000 ./clang_test.c
./clang_test.c:32:42: error: argument type 'void' is incomplete
32 | printf("a is static, arr$len=%zu\n", arr$len(a));
| ^
./clang_test.c:12:9: note: expanded from macro 'arr$len'
12 | ({ \
| ^
./clang_test.c:35:49: error: argument type 'void' is incomplete
35 | printf("a is kinda dynamic, arr$len=%zu\n", arr$len(a1));
| ^
./clang_test.c:12:9: note: expanded from macro 'arr$len'
12 | ({ \
| ^
2 errors generated.
```
If you remove `_Pragma("GCC diagnostic pop"); ` in `arr$len()` macro, it compiles and runs properly.
Contributor guide
Research direction
Start with the minimal C reproducer in the issue and run it using the provided clang command, comparing behavior with and without the final _Pragma("GCC diagnostic pop") in arr$len. Trace how _Pragma directives inside the macro affect the reported void argument type, and confirm that the reproducer compiles and runs correctly after the fix.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100