shafik created this revision. shafik added reviewers: aaron.ballman, cor3ntin. Herald added a project: All. shafik requested review of this revision.
In C++ we are not allowed to use designated initializers to initialize fields out of order. In some cases when diagnosing this we are crashing because we are not indexing correctly and therefore going out of bounds. This fixes: https://github.com/llvm/llvm-project/issues/63605 https://reviews.llvm.org/D154675 Files: clang/lib/Sema/SemaInit.cpp clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp Index: clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp +++ clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp @@ -63,7 +63,7 @@ .x = 1, // override-note {{previous}} .x = 1, // override-error {{overrides prior initialization}} override-note {{previous}} .y = 1, // override-note {{previous}} - .y = 1, // override-error {{overrides prior initialization}} + .y = 1, // override-error {{overrides prior initialization}} // reorder-note {{previous initialization for field 'y' is here}} .x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}} .x = 1, // override-error {{overrides prior initialization}} }; @@ -177,3 +177,22 @@ h({.a = 1}); } } + +namespace GH63605 { +struct { + unsigned : 2; + unsigned a : 6; + unsigned : 1; + unsigned b : 6; + unsigned : 2; + unsigned c : 6; + unsigned d : 1; + unsigned e : 2; +} data = { + .e = 1, // reorder-note {{previous initialization for field 'e' is here}} + .d = 1, // reorder-error {{field 'e' will be initialized after field 'd'}} // reorder-note {{previous initialization for field 'd' is here}} + .c = 1, // reorder-error {{field 'd' will be initialized after field 'c'}} // reorder-note {{previous initialization for field 'c' is here}} + .b = 1, // reorder-error {{field 'c' will be initialized after field 'b'}} // reorder-note {{previous initialization for field 'e' is here}} + .a = 1, // reorder-error {{field 'e' will be initialized after field 'a'}} +}; +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -2844,7 +2844,7 @@ SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered) << KnownField << PrevField << DIE->getSourceRange(); - unsigned OldIndex = NumBases + PrevField->getFieldIndex(); + unsigned OldIndex = NumBases + StructuredIndex - 1; if (StructuredList && OldIndex <= StructuredList->getNumInits()) { if (Expr *PrevInit = StructuredList->getInit(OldIndex)) { SemaRef.Diag(PrevInit->getBeginLoc(),
Index: clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp +++ clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp @@ -63,7 +63,7 @@ .x = 1, // override-note {{previous}} .x = 1, // override-error {{overrides prior initialization}} override-note {{previous}} .y = 1, // override-note {{previous}} - .y = 1, // override-error {{overrides prior initialization}} + .y = 1, // override-error {{overrides prior initialization}} // reorder-note {{previous initialization for field 'y' is here}} .x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}} .x = 1, // override-error {{overrides prior initialization}} }; @@ -177,3 +177,22 @@ h({.a = 1}); } } + +namespace GH63605 { +struct { + unsigned : 2; + unsigned a : 6; + unsigned : 1; + unsigned b : 6; + unsigned : 2; + unsigned c : 6; + unsigned d : 1; + unsigned e : 2; +} data = { + .e = 1, // reorder-note {{previous initialization for field 'e' is here}} + .d = 1, // reorder-error {{field 'e' will be initialized after field 'd'}} // reorder-note {{previous initialization for field 'd' is here}} + .c = 1, // reorder-error {{field 'd' will be initialized after field 'c'}} // reorder-note {{previous initialization for field 'c' is here}} + .b = 1, // reorder-error {{field 'c' will be initialized after field 'b'}} // reorder-note {{previous initialization for field 'e' is here}} + .a = 1, // reorder-error {{field 'e' will be initialized after field 'a'}} +}; +} Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -2844,7 +2844,7 @@ SemaRef.Diag(DIE->getBeginLoc(), diag::ext_designated_init_reordered) << KnownField << PrevField << DIE->getSourceRange(); - unsigned OldIndex = NumBases + PrevField->getFieldIndex(); + unsigned OldIndex = NumBases + StructuredIndex - 1; if (StructuredList && OldIndex <= StructuredList->getNumInits()) { if (Expr *PrevInit = StructuredList->getInit(OldIndex)) { SemaRef.Diag(PrevInit->getBeginLoc(),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits