diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -177,6 +177,9 @@ requires-expression. This fixes: (`#64138 `_). +- Update ``FunctionDeclBitfields.NumFunctionDeclBits``. This fixes: + (`#64171 `_). + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -1702,7 +1702,7 @@ }; /// Number of non-inherited bits in FunctionDeclBitfields. - enum { NumFunctionDeclBits = 30 }; + enum { NumFunctionDeclBits = 31 }; /// Stores the bits used by CXXConstructorDecl. If modified /// NumCXXConstructorDeclBits and the accessor @@ -1714,12 +1714,12 @@ /// For the bits in FunctionDeclBitfields. uint64_t : NumFunctionDeclBits; - /// 21 bits to fit in the remaining available space. + /// 20 bits to fit in the remaining available space. /// Note that this makes CXXConstructorDeclBitfields take /// exactly 64 bits and thus the width of NumCtorInitializers /// will need to be shrunk if some bit is added to NumDeclContextBitfields, /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. - uint64_t NumCtorInitializers : 18; + uint64_t NumCtorInitializers : 17; uint64_t IsInheritingConstructor : 1; /// Whether this constructor has a trail-allocated explicit specifier. diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -580,7 +580,7 @@ } void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { - static_assert(DeclContext::NumFunctionDeclBits == 30, + static_assert(DeclContext::NumFunctionDeclBits == 31, "You need to update the serializer after you change the " "FunctionDeclBits"); @@ -1495,7 +1495,7 @@ } void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { - static_assert(DeclContext::NumCXXConstructorDeclBits == 21, + static_assert(DeclContext::NumCXXConstructorDeclBits == 20, "You need to update the serializer after you change the " "CXXConstructorDeclBits"); diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -7832,6 +7832,47 @@ CheckAST(ToTU, ToC); } +TEST_P(ASTImporterOptionSpecificTestBase, + ImportFunctionDeclBitShouldNotOverwriteCtorDeclBits) { + Decl *From, *To; + std::tie(From, To) = getImportedDecl( + R"s( + struct A { + A() : m() {} + int m; + }; + + A foo() { A a; return a; } + A bar() { return {}; } + )s", + Lang_CXX17, + R"s( + struct A { + A() : m() {} + int m; + }; + A baz() { return {}; } + )s", + Lang_CXX17, "A"); + + auto HasCtorInit = + hasAnyConstructorInitializer(cxxCtorInitializer(isMemberInitializer())); + auto ImpMoveCtor = + cxxConstructorDecl(isMoveConstructor(), isImplicit(), HasCtorInit); + + auto *FromImpMoveCtor = FirstDeclMatcher().match( + From, ImpMoveCtor); + auto *ToImpMoveCtor = FirstDeclMatcher().match( + To, ImpMoveCtor); + + EXPECT_TRUE(FromImpMoveCtor->getNumCtorInitializers() == 1); + EXPECT_FALSE(FromImpMoveCtor->FriendConstraintRefersToEnclosingTemplate()); + + EXPECT_TRUE(ToImpMoveCtor->getNumCtorInitializers() == 1); + EXPECT_FALSE(ToImpMoveCtor->FriendConstraintRefersToEnclosingTemplate()); + EXPECT_TRUE(*ToImpMoveCtor->init_begin()); +} + AST_MATCHER_P(UsingShadowDecl, hasIntroducerDecl, internal::Matcher, InnerMatcher) { return InnerMatcher.matches(*Node.getIntroducer(), Finder, Builder); diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp --- a/clang/unittests/AST/DeclTest.cpp +++ b/clang/unittests/AST/DeclTest.cpp @@ -353,6 +353,32 @@ EXPECT_TRUE(getFooValue->isInlined()); } +TEST(Decl, FunctionDeclBitsShouldNotOverlapWithCXXConstructorDeclBits) { + llvm::Annotations Code(R"( + struct A { + A() : m() {} + int m; + }; + + A f() { return A(); } + )"); + + auto AST = tooling::buildASTFromCodeWithArgs(Code.code(), {"-std=c++14"}); + ASTContext &Ctx = AST->getASTContext(); + + auto HasCtorInit = + hasAnyConstructorInitializer(cxxCtorInitializer(isMemberInitializer())); + auto ImpMoveCtor = + cxxConstructorDecl(isMoveConstructor(), isImplicit(), HasCtorInit) + .bind("MoveCtor"); + + auto *ToImpMoveCtor = + selectFirst("MoveCtor", match(ImpMoveCtor, Ctx)); + + EXPECT_TRUE(ToImpMoveCtor->getNumCtorInitializers() == 1); + EXPECT_FALSE(ToImpMoveCtor->FriendConstraintRefersToEnclosingTemplate()); +} + TEST(Decl, NoProtoFunctionDeclAttributes) { llvm::Annotations Code(R"( void f();