martong created this revision. martong added reviewers: a_sidorin, r.stahl, xazax.hun. Herald added subscribers: cfe-commits, dkrupp, rnkovacs. Herald added a reviewer: a.sidorin.
Some `Expr` classes set up default values for the `ExprBits` of `Stmt`. These default values are then overwritten by the parser sometimes. One example is `InitListExpr` which sets the value kind to be an rvalue in the ctor. However, this bit may change after the `InitListExpr` is created. There may be other expressions similar to `InitListExpr` in this sense, thus the safest solution is to copy the expression bits. The lack of copying `ExprBits` causes an assertion in the analyzer engine in a specific case: Since the value kind is not imported, the analyzer engine believes that the given InitListExpr is an rvalue, thus it creates a nonloc::CompoundVal instead of creating memory region (as in case of an lvalue reference). Repository: rC Clang https://reviews.llvm.org/D51533 Files: lib/AST/ASTImporter.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -3225,6 +3225,25 @@ unless(classTemplatePartialSpecializationDecl())))); } +TEST_P(ASTImporterTestBase, InitListExprValueKindShouldBeImported) { + Decl *TU = getTuDecl( + R"( + const int &init(); + void foo() { const int &a{init()}; } + )", Lang_CXX11, "input0.cc"); + auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a"))); + ASSERT_TRUE(FromD->getAnyInitializer()); + auto *InitExpr = FromD->getAnyInitializer(); + ASSERT_TRUE(InitExpr); + ASSERT_TRUE(InitExpr->isGLValue()); + + auto *ToD = Import(FromD, Lang_CXX11); + ASSERT_TRUE(ToD); + auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer(); + ASSERT_TRUE(ToInitExpr); + EXPECT_TRUE(ToInitExpr->isGLValue()); +} + struct DeclContextTest : ASTImporterTestBase {}; TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -6849,9 +6849,9 @@ To->setSyntacticForm(ToSyntForm); } + // Copy InitListExprBitfields, which are not handled in the ctor of + // InitListExpr. To->sawArrayRangeDesignator(ILE->hadArrayRangeDesignator()); - To->setValueDependent(ILE->isValueDependent()); - To->setInstantiationDependent(ILE->isInstantiationDependent()); return To; } @@ -7196,6 +7196,19 @@ if (!ToS) return nullptr; + if (auto *ToE = dyn_cast<Expr>(ToS)) { + auto *FromE = cast<Expr>(FromS); + // Copy ExprBitfields, which may not be handled in Expr subclasses + // constructors. + ToE->setValueKind(FromE->getValueKind()); + ToE->setObjectKind(FromE->getObjectKind()); + ToE->setTypeDependent(FromE->isTypeDependent()); + ToE->setValueDependent(FromE->isValueDependent()); + ToE->setInstantiationDependent(FromE->isInstantiationDependent()); + ToE->setContainsUnexpandedParameterPack( + FromE->containsUnexpandedParameterPack()); + } + // Record the imported declaration. ImportedStmts[FromS] = ToS; return ToS;
Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -3225,6 +3225,25 @@ unless(classTemplatePartialSpecializationDecl())))); } +TEST_P(ASTImporterTestBase, InitListExprValueKindShouldBeImported) { + Decl *TU = getTuDecl( + R"( + const int &init(); + void foo() { const int &a{init()}; } + )", Lang_CXX11, "input0.cc"); + auto *FromD = FirstDeclMatcher<VarDecl>().match(TU, varDecl(hasName("a"))); + ASSERT_TRUE(FromD->getAnyInitializer()); + auto *InitExpr = FromD->getAnyInitializer(); + ASSERT_TRUE(InitExpr); + ASSERT_TRUE(InitExpr->isGLValue()); + + auto *ToD = Import(FromD, Lang_CXX11); + ASSERT_TRUE(ToD); + auto *ToInitExpr = cast<VarDecl>(ToD)->getAnyInitializer(); + ASSERT_TRUE(ToInitExpr); + EXPECT_TRUE(ToInitExpr->isGLValue()); +} + struct DeclContextTest : ASTImporterTestBase {}; TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -6849,9 +6849,9 @@ To->setSyntacticForm(ToSyntForm); } + // Copy InitListExprBitfields, which are not handled in the ctor of + // InitListExpr. To->sawArrayRangeDesignator(ILE->hadArrayRangeDesignator()); - To->setValueDependent(ILE->isValueDependent()); - To->setInstantiationDependent(ILE->isInstantiationDependent()); return To; } @@ -7196,6 +7196,19 @@ if (!ToS) return nullptr; + if (auto *ToE = dyn_cast<Expr>(ToS)) { + auto *FromE = cast<Expr>(FromS); + // Copy ExprBitfields, which may not be handled in Expr subclasses + // constructors. + ToE->setValueKind(FromE->getValueKind()); + ToE->setObjectKind(FromE->getObjectKind()); + ToE->setTypeDependent(FromE->isTypeDependent()); + ToE->setValueDependent(FromE->isValueDependent()); + ToE->setInstantiationDependent(FromE->isInstantiationDependent()); + ToE->setContainsUnexpandedParameterPack( + FromE->containsUnexpandedParameterPack()); + } + // Record the imported declaration. ImportedStmts[FromS] = ToS; return ToS;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits