diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3edf480665ba1..5e19dbea66084 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -712,6 +712,8 @@ Miscellaneous Clang Crashes Fixed `Issue 64564 `_ - Fixed a crash when an ObjC ivar has an invalid type. See (`#68001 `_) +- Fixed a crash in C when redefined struct is another nested redefinition. + `Issue 41302 `_ Target Specific Changes ----------------------- diff --git a/clang/lib/Sema/IdentifierResolver.cpp b/clang/lib/Sema/IdentifierResolver.cpp index 98a6f3b45089b..2213c3c837243 100644 --- a/clang/lib/Sema/IdentifierResolver.cpp +++ b/clang/lib/Sema/IdentifierResolver.cpp @@ -109,7 +109,9 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S, return false; if (Ctx->isFunctionOrMethod() || (S && S->isFunctionPrototypeScope())) { // Ignore the scopes associated within transparent declaration contexts. - while (S->getEntity() && S->getEntity()->isTransparentContext()) + while (S->getEntity() && + (S->getEntity()->isTransparentContext() || + (!LangOpt.CPlusPlus && isa(S->getEntity())))) S = S->getParent(); if (S->isDeclScope(D)) diff --git a/clang/test/Sema/nested-redef.c b/clang/test/Sema/nested-redef.c index bbc4859367704..adc57ff4e04ab 100644 --- a/clang/test/Sema/nested-redef.c +++ b/clang/test/Sema/nested-redef.c @@ -19,4 +19,16 @@ void f2(void) { struct U u; } +void f3(void) { + struct G { // expected-note{{previous definition is here}} + struct G {}; // expected-error{{nested redefinition of 'G'}} + }; +} + +void f4(void) { + struct G { // expected-note 2{{previous definition is here}} + struct G {}; // expected-error{{nested redefinition of 'G'}} + }; + struct G {}; // expected-error{{redefinition of 'G'}} +} diff --git a/clang/test/SemaObjC/ivar-lookup.m b/clang/test/SemaObjC/ivar-lookup.m index 898ffac99692c..d88299e58e0f5 100644 --- a/clang/test/SemaObjC/ivar-lookup.m +++ b/clang/test/SemaObjC/ivar-lookup.m @@ -95,11 +95,11 @@ - (int) test union U { __typeof(myStatus) __in; // fails. }; - struct S { + struct S { // expected-note{{previous definition is here}} __typeof(myStatus) __in; // fails. struct S1 { // expected-warning {{declaration does not declare anything}} __typeof(myStatus) __in; // fails. - struct S { // expected-warning {{declaration does not declare anything}} + struct S { // expected-error {{nested redefinition of 'S'}} __typeof(myStatus) __in; // fails. }; };