This: #pragma GCC warning "foo" "bar" #pragma GCC error "foo" "bar" produces: /tmp/t.c:1:21: warning: foo 1 | #pragma GCC warning "foo" "bar" | ^~~~~ /tmp/t.c:2:19: error: foo 2 | #pragma GCC error "foo" "bar" | ^~~~~ It is an oversight in the processing of the pragma arguments. Clang produces this, which is closer to developer expectations: /tmp/t.c:1:13: warning: foobar [-W#pragma-messages] /tmp/t.c:2:13: error: foobar (Another option would be to error out on multiple arguments to the pragma.) This is not a regression, it's a bug that's always been present.
Note, string literal concatenation is implemented in c_parser_string_literal in the C FE and in cp_parser_string_literal in the C++ FE. Pragma processing is during translation phase 4 while string literal concatenation is translation phase 6, plus these pragmas are GCC extension, so we can do whatever we want, but perhaps handling the string literal concatenation and erroring out on other arguments after it wouldn't be a bad idea for GCC 12+. As the pragmas handle just CPP_STRING, it wouldn't have to handle e.g. mixing of the various string literal types etc. Note, currently we diagnose as error #pragma GCC warning "" but we should error just on that form and not e.g. on #pragma GCC warning "" "" "" "foobar"
Also, I'd add that #pragma message "foo " "bar " "baz" already works fine because it is done in the FE and not in libcpp and so it can use pragma_lex under the hood to do this. And, it also has if (pragma_lex (&x) != CPP_EOF) warning (OPT_Wpragmas, "junk at end of %<#pragma pack%>"); message at the end in case one uses #pragma message 4 or #pragma message "foo" 4 etc. I think #pragma GCC {warning,error} can stay where it is, but it would be nice if it behaved the same way.