forked from OSchip/llvm-project
[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 llvm-svn: 369098
This commit is contained in:
parent
d3f774d33c
commit
e13e836480
|
@ -3272,23 +3272,6 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
|
|||
// decl and its redeclarations may be required.
|
||||
}
|
||||
|
||||
// Import Ctor initializers.
|
||||
if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
|
||||
if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
|
||||
SmallVector<CXXCtorInitializer *, 4> 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<CXXConstructorDecl>(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<CXXConstructorDecl>(D)) {
|
||||
if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
|
||||
SmallVector<CXXCtorInitializer *, 4> 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<CXXConstructorDecl>(ToFunction);
|
||||
ToCtor->setCtorInitializers(Memory);
|
||||
ToCtor->setNumCtorInitializers(NumInitializers);
|
||||
}
|
||||
}
|
||||
|
||||
if (D->doesThisDeclarationHaveABody()) {
|
||||
Error Err = ImportFunctionDeclBody(D, ToFunction);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue