[C] Fix crash-on-invalid due to infinite recursion (#140925)
There are two related issues being fixed in this patch. Both issues relate to use of an invalid structure which contains a member that we error recover such that the field has the same type as the structure. In both cases, we would hit an infinite loop while analyzing the fields because the type of the field matches the type of the record. Fixes #140887
This commit is contained in:
@@ -273,6 +273,8 @@ C23 Feature Support
|
||||
be completed).
|
||||
- Fixed a failed assertion with an invalid parameter to the ``#embed``
|
||||
directive. Fixes #GH126940.
|
||||
- Fixed a crash when a declaration of a ``constexpr`` variable with an invalid
|
||||
type. Fixes #GH140887
|
||||
|
||||
C11 Feature Support
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -8681,7 +8681,8 @@ static bool CheckC23ConstexprVarType(Sema &SemaRef, SourceLocation VarLoc,
|
||||
|
||||
if (CanonT->isRecordType()) {
|
||||
const RecordDecl *RD = CanonT->getAsRecordDecl();
|
||||
if (llvm::any_of(RD->fields(), [&SemaRef, VarLoc](const FieldDecl *F) {
|
||||
if (!RD->isInvalidDecl() &&
|
||||
llvm::any_of(RD->fields(), [&SemaRef, VarLoc](const FieldDecl *F) {
|
||||
return CheckC23ConstexprVarType(SemaRef, VarLoc, F->getType());
|
||||
}))
|
||||
return true;
|
||||
|
||||
@@ -6618,7 +6618,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
|
||||
// initializer present. However, we only do this for structure types, not
|
||||
// union types, because an unitialized field in a union is generally
|
||||
// reasonable, especially in C where unions can be used for type punning.
|
||||
if (!Initializer && !Rec->isUnion()) {
|
||||
if (!Initializer && !Rec->isUnion() && !Rec->isInvalidDecl()) {
|
||||
if (const FieldDecl *FD = getConstField(Rec)) {
|
||||
unsigned DiagID = diag::warn_default_init_const_field_unsafe;
|
||||
if (Var->getStorageDuration() == SD_Static ||
|
||||
|
||||
12
clang/test/Sema/c2y-invalid-constexpr.c
Normal file
12
clang/test/Sema/c2y-invalid-constexpr.c
Normal file
@@ -0,0 +1,12 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c23 %s
|
||||
|
||||
// This was previously causing a stack overflow when checking the valid
|
||||
// declaration of an invalid type. Ensure we issue reasonable diagnostics
|
||||
// instead of crashing.
|
||||
struct GH140887 { // expected-note {{definition of 'struct GH140887' is not complete until the closing '}'}}
|
||||
GH140887(); // expected-error {{must use 'struct' tag to refer to type 'GH140887'}} \
|
||||
expected-error {{expected member name or ';' after declaration specifiers}} \
|
||||
expected-error {{field has incomplete type 'struct GH140887'}}
|
||||
};
|
||||
constexpr struct GH140887 a; // expected-error {{constexpr variable 'a' must be initialized by a constant expression}}
|
||||
|
||||
11
clang/test/Sema/warn-default-const-init-crash.c
Normal file
11
clang/test/Sema/warn-default-const-init-crash.c
Normal file
@@ -0,0 +1,11 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
// This invalid code was causing a stack overflow, check that we issue
|
||||
// reasonable diagnostics and not crash.
|
||||
struct GH140887 { // expected-note {{definition of 'struct GH140887' is not complete until the closing '}'}}
|
||||
struct GH140887 s; // expected-error {{field has incomplete type 'struct GH140887'}}
|
||||
};
|
||||
|
||||
void gh140887() {
|
||||
struct GH140887 s;
|
||||
}
|
||||
Reference in New Issue
Block a user