From a54e9b9382602f1a3830df06104c7e81412bb22a Mon Sep 17 00:00:00 2001 From: Balazs Keri <1.int32@gmail.com> Date: Fri, 16 Aug 2019 12:10:03 +0000 Subject: [PATCH] [ASTImporter] Import ctor initializers after setting flags. Summary: Code to import "ctor initializers" at import of functions is moved to be after the flags in the newly created function are imported. This fixes an error when the already created but incomplete (flags are not set) function declaration is accessed. Reviewers: martong, shafik, a_sidorin, a.sidorin Reviewed By: shafik Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D65935 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@369098 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTImporter.cpp | 34 +++++++++---------- test/Analysis/Inputs/ctu-other.cpp | 11 ++++++ .../Inputs/ctu-other.cpp.externalDefMap.txt | 1 + test/Analysis/ctu-main.cpp | 4 +++ 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 5b7b5438f6..e54677c2dc 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -3272,23 +3272,6 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { // decl and its redeclarations may be required. } - // Import Ctor initializers. - if (auto *FromConstructor = dyn_cast(D)) { - if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) { - SmallVector CtorInitializers(NumInitializers); - // Import first, then allocate memory and copy if there was no error. - if (Error Err = ImportContainerChecked( - FromConstructor->inits(), CtorInitializers)) - return std::move(Err); - auto **Memory = - new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers]; - std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory); - auto *ToCtor = cast(ToFunction); - ToCtor->setCtorInitializers(Memory); - ToCtor->setNumCtorInitializers(NumInitializers); - } - } - ToFunction->setQualifierInfo(ToQualifierLoc); ToFunction->setAccess(D->getAccess()); ToFunction->setLexicalDeclContext(LexicalDC); @@ -3332,6 +3315,23 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { return ToFTOrErr.takeError(); } + // Import Ctor initializers. + if (auto *FromConstructor = dyn_cast(D)) { + if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) { + SmallVector CtorInitializers(NumInitializers); + // Import first, then allocate memory and copy if there was no error. + if (Error Err = ImportContainerChecked( + FromConstructor->inits(), CtorInitializers)) + return std::move(Err); + auto **Memory = + new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers]; + std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory); + auto *ToCtor = cast(ToFunction); + ToCtor->setCtorInitializers(Memory); + ToCtor->setNumCtorInitializers(NumInitializers); + } + } + if (D->doesThisDeclarationHaveABody()) { Error Err = ImportFunctionDeclBody(D, ToFunction); diff --git a/test/Analysis/Inputs/ctu-other.cpp b/test/Analysis/Inputs/ctu-other.cpp index 64c990c5e7..ff37947d5b 100644 --- a/test/Analysis/Inputs/ctu-other.cpp +++ b/test/Analysis/Inputs/ctu-other.cpp @@ -164,3 +164,14 @@ const int DefaultParmContext::I = 0; int DefaultParmContext::f() { return fDefaultParm(); } + +class TestDelegateConstructor { +public: + TestDelegateConstructor() : TestDelegateConstructor(2) {} + TestDelegateConstructor(int) {} +}; + +int testImportOfDelegateConstructor(int i) { + TestDelegateConstructor TDC; + return i; +} diff --git a/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt index 73cd61b0cb..e5fca5d604 100644 --- a/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt +++ b/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt @@ -27,3 +27,4 @@ c:@extSCC ctu-other.cpp.ast c:@extU ctu-other.cpp.ast c:@S@TestAnonUnionUSR@Test ctu-other.cpp.ast c:@F@testImportOfIncompleteDefaultParmDuringImport#I# ctu-other.cpp.ast +c:@F@testImportOfDelegateConstructor#I# ctu-other.cpp.ast \ No newline at end of file diff --git a/test/Analysis/ctu-main.cpp b/test/Analysis/ctu-main.cpp index c4aee409ee..abfacfbdae 100644 --- a/test/Analysis/ctu-main.cpp +++ b/test/Analysis/ctu-main.cpp @@ -127,6 +127,8 @@ public: extern int testImportOfIncompleteDefaultParmDuringImport(int); +extern int testImportOfDelegateConstructor(int); + int main() { clang_analyzer_eval(f(3) == 2); // expected-warning{{TRUE}} clang_analyzer_eval(f(4) == 3); // expected-warning{{TRUE}} @@ -163,4 +165,6 @@ int main() { clang_analyzer_eval(TestAnonUnionUSR::Test == 5); // expected-warning{{TRUE}} clang_analyzer_eval(testImportOfIncompleteDefaultParmDuringImport(9) == 9); // expected-warning{{TRUE}} + + clang_analyzer_eval(testImportOfDelegateConstructor(10) == 10); // expected-warning{{TRUE}} } -- 2.40.0