diff --git a/clang-tools-extra/clangd/refactor/tweaks/MemberwiseConstructor.cpp b/clang-tools-extra/clangd/refactor/tweaks/MemberwiseConstructor.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/MemberwiseConstructor.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/MemberwiseConstructor.cpp @@ -178,6 +178,8 @@ // Decide what to do with a field of type C. static FieldAction considerClassValue(const CXXRecordDecl &C) { + if (!C.hasDefinition()) + return Skip; // We can't always tell if C is copyable/movable without doing Sema work. // We assume operations are possible unless we can prove not. bool CanCopy = C.hasUserDeclaredCopyConstructor() || diff --git a/clang-tools-extra/clangd/unittests/tweaks/MemberwiseConstructorTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/MemberwiseConstructorTests.cpp --- a/clang-tools-extra/clangd/unittests/tweaks/MemberwiseConstructorTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/MemberwiseConstructorTests.cpp @@ -23,6 +23,8 @@ TEST_F(MemberwiseConstructorTest, Availability) { EXPECT_AVAILABLE("^struct ^S ^{ int x, y; };"); + // Verify no crashes on incomplete member fields. + EXPECT_UNAVAILABLE("/*error-ok*/class Forward; class ^A { Forward f;}"); EXPECT_UNAVAILABLE("struct S { ^int ^x, y; }; struct ^S;"); EXPECT_UNAVAILABLE("struct ^S {};"); EXPECT_UNAVAILABLE("union ^S { int x; };");