[Sema] Fix crash in __builtin_dump_struct with -Werror -Wformat-pedantic (#212377)

`DiagnosticErrorTrap::hasErrorOccurred()` treats warnings promoted to
errors by `-Werror` as real errors, causing `BuiltinDumpStructGenerator`
to bail out before building the `PseudoObjectExpr` wrapper. CodeGen then
encounters the untransformed `CallExpr` with a placeholder builtin type
and hits `llvm_unreachable` in `CodeGenTypes::ConvertType`.
Use `hasUnrecoverableErrorOccurred()` instead, which ignores `-Werror`
promoted warnings and only bails on genuine compilation errors.

Fixes #211943
This commit is contained in:
Krisitan Erik Olsen 2026-07-30 21:19:01 -07:00 committed by GitHub
parent 08bfd2e3fd
commit 1ddfb94fa6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 3 deletions

View file

@ -370,6 +370,8 @@ features cannot lower the translation-unit ABI level;
- Fixed a crash when classifying a call to a builtin with dependent arguments,
such as when the call is used as an `auto` non-type template argument.
- Fixed a crash in ``__builtin_dump_struct`` when ``-Werror`` promotes
format warnings to errors. (#GH211943)
#### Bug Fixes to Attribute Support

View file

@ -541,9 +541,9 @@ struct BuiltinDumpStructGenerator {
S.popCodeSynthesisContext();
if (!RealCall.isInvalid())
Actions.push_back(RealCall.get());
// Bail out if we've hit any errors, even if we managed to build the
// call. We don't want to produce more than one error.
return RealCall.isInvalid() || ErrorTracker.hasErrorOccurred();
// Bail out if we've hit any unrecoverable errors, even if we managed
// to build the call.
return RealCall.isInvalid() || ErrorTracker.hasUnrecoverableErrorOccurred();
}
Expr *getIndentString(unsigned Depth) {

View file

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -Wformat-pedantic -Werror -emit-llvm -o /dev/null -verify %s
int printflike(const char *__restrict__ x, ...) __attribute__((__format__(__printf__, 1, 2)));
struct Foo {
int *x;
};
void test() {
__builtin_dump_struct(&(struct Foo){0}, printflike); // expected-error {{taking the address of a temporary object of type 'struct Foo'}} \
// expected-error {{format specifies type 'void *' but the argument has type 'int *'}} \
// expected-note {{in call to printing function}}
}