diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -2963,6 +2963,20 @@ EXPECT_EQ(HI->Documentation, "Foo bar baz"); } +TEST(Hover, ForwardStructNoCrash) { + Annotations T(R"cpp( + struct Foo; + int bar; + auto baz = (Fo^o*)&bar; + )cpp"); + + TestTU TU = TestTU::withCode(T.code()); + auto AST = TU.build(); + auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); + ASSERT_TRUE(HI); + EXPECT_EQ(*HI->Value, "&bar"); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -700,7 +700,9 @@ if (!hasLValuePath()) { // No lvalue path: just print the offset. CharUnits O = getLValueOffset(); - CharUnits S = Ctx ? Ctx->getTypeSizeInChars(InnerTy) : CharUnits::Zero(); + CharUnits S = Ctx ? Ctx->getTypeSizeInCharsIfKnown(InnerTy).getValueOr( + CharUnits::Zero()) + : CharUnits::Zero(); if (!O.isZero()) { if (IsReference) Out << "*(";