Skip to content

Commit 2867095

Browse files
[clang] Skip implicit designators in DesignatedInitExpr::getBeginLoc (#83369)
Fixes #83185
1 parent e77378c commit 2867095

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,22 @@ TEST_F(ExtractVariableTest, Test) {
7272
)cpp";
7373
EXPECT_UNAVAILABLE(NoCrashCasesC);
7474

75+
ExtraArgs = {"-xc"};
76+
const char *NoCrashDesignator = R"cpp(
77+
struct A {
78+
struct {
79+
int x;
80+
};
81+
};
82+
struct B {
83+
int y;
84+
};
85+
void foo(struct B *b) {
86+
struct A a = {.x=b[[->]]y};
87+
}
88+
)cpp";
89+
EXPECT_AVAILABLE(NoCrashDesignator);
90+
7591
ExtraArgs = {"-xobjective-c"};
7692
const char *AvailableObjC = R"cpp(
7793
__attribute__((objc_root_class))

clang/lib/AST/Expr.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4604,8 +4604,17 @@ SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const {
46044604
SourceLocation DesignatedInitExpr::getBeginLoc() const {
46054605
auto *DIE = const_cast<DesignatedInitExpr *>(this);
46064606
Designator &First = *DIE->getDesignator(0);
4607-
if (First.isFieldDesignator())
4608-
return GNUSyntax ? First.getFieldLoc() : First.getDotLoc();
4607+
if (First.isFieldDesignator()) {
4608+
// Skip past implicit designators for anonymous structs/unions, since
4609+
// these do not have valid source locations.
4610+
for (unsigned int i = 0; i < DIE->size(); i++) {
4611+
Designator &Des = *DIE->getDesignator(i);
4612+
SourceLocation retval = GNUSyntax ? Des.getFieldLoc() : Des.getDotLoc();
4613+
if (!retval.isValid())
4614+
continue;
4615+
return retval;
4616+
}
4617+
}
46094618
return First.getLBracketLoc();
46104619
}
46114620

0 commit comments

Comments
 (0)