llvm / llvm/llvm-project

[clang] _Pragma() in macro interfering with macro return type

Open
#169,494 1 comment 1 reaction 0 assignees View on GitHub
clang:frontend confirmed regression:22
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.