r332256 - [ASTImporter] Turn StringRefs back to std::strings to avoid use-after-free
Author: a.sidorin Date: Mon May 14 09:12:31 2018 New Revision: 332256 URL: http://llvm.org/viewvc/llvm-project?rev=332256&view=rev Log: [ASTImporter] Turn StringRefs back to std::strings to avoid use-after-free This is a workaround for the issue in buildASTFromCodeWithArgs() where a local buffer can be used to store the program text referred by SourceManager. FIXME: Fix the root issue in buildASTFromCodeWithArgs(). Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=332256&r1=332255&r2=332256&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon May 14 09:12:31 2018 @@ -207,8 +207,8 @@ class ASTImporterTestBase : public ::tes struct TU { // Buffer for the context, must live in the test scope. -StringRef Code; -StringRef FileName; +std::string Code; +std::string FileName; std::unique_ptr Unit; TranslationUnitDecl *TUDecl = nullptr; TU(StringRef Code, StringRef FileName, ArgVector Args) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r332338 - [ASTImporter] Extend lookup logic in class templates
Author: a.sidorin Date: Tue May 15 04:09:07 2018 New Revision: 332338 URL: http://llvm.org/viewvc/llvm-project?rev=332338&view=rev Log: [ASTImporter] Extend lookup logic in class templates During import of a class template, lookup may find a forward declaration and structural match falsely reports equivalency between a forward decl and a definition. The result is that some definitions are not imported if we had imported a forward decl previously. This patch gives a fix. Patch by Gabor Marton! Differential Revision: https://reviews.llvm.org/D46353 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=332338&r1=332337&r2=332338&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue May 15 04:09:07 2018 @@ -4108,8 +4108,14 @@ Decl *ASTNodeImporter::VisitClassTemplat if (auto *FoundTemplate = dyn_cast(Found)) { if (IsStructuralMatch(D, FoundTemplate)) { // The class templates structurally match; call it the same template. - // FIXME: We may be filling in a forward declaration here. Handle - // this case! + + // We found a forward declaration but the class to be imported has a + // definition. + // FIXME Add this forward declaration to the redeclaration chain. + if (D->isThisDeclarationADefinition() && + !FoundTemplate->isThisDeclarationADefinition()) +continue; + Importer.Imported(D->getTemplatedDecl(), FoundTemplate->getTemplatedDecl()); return Importer.Imported(D, FoundTemplate); Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=332338&r1=332337&r2=332338&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Tue May 15 04:09:07 2018 @@ -1431,6 +1431,39 @@ TEST_P(ASTImporterTestBase, MatchVerifier{}.match(To->getTranslationUnitDecl(), Pattern)); } +TEST_P(ASTImporterTestBase, ImportDefinitionOfClassTemplateAfterFwdDecl) { + { +Decl *FromTU = getTuDecl( +R"( +template +struct B; +)", +Lang_CXX, "input0.cc"); +auto *FromD = FirstDeclMatcher().match( +FromTU, classTemplateDecl(hasName("B"))); + +Import(FromD, Lang_CXX); + } + + { +Decl *FromTU = getTuDecl( +R"( +template +struct B { + void f(); +}; +)", +Lang_CXX, "input1.cc"); +FunctionDecl *FromD = FirstDeclMatcher().match( +FromTU, functionDecl(hasName("f"))); +Import(FromD, Lang_CXX); +auto *FromCTD = FirstDeclMatcher().match( +FromTU, classTemplateDecl(hasName("B"))); +auto *ToCTD = cast(Import(FromCTD, Lang_CXX)); +EXPECT_TRUE(ToCTD->isThisDeclarationADefinition()); + } +} + INSTANTIATE_TEST_CASE_P( ParameterizedTests, ASTImporterTestBase, ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r325116 - [ASTImporter] Fix lexical DC for templated decls; support VarTemplatePartialSpecDecl
Author: a.sidorin Date: Wed Feb 14 03:18:00 2018 New Revision: 325116 URL: http://llvm.org/viewvc/llvm-project?rev=325116&view=rev Log: [ASTImporter] Fix lexical DC for templated decls; support VarTemplatePartialSpecDecl Also minor refactoring in related functions was done. Differential Revision: https://reviews.llvm.org/D43012 Added: cfe/trunk/test/ASTMerge/var-cpp/ cfe/trunk/test/ASTMerge/var-cpp/Inputs/ cfe/trunk/test/ASTMerge/var-cpp/Inputs/var1.cpp cfe/trunk/test/ASTMerge/var-cpp/test.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=325116&r1=325115&r2=325116&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Feb 14 03:18:00 2018 @@ -23,7 +23,6 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/MemoryBuffer.h" -#include namespace clang { class ASTNodeImporter : public TypeVisitor, @@ -1335,6 +1334,21 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } +template <> +bool ASTNodeImporter::ImportTemplateArgumentListInfo( +const TemplateArgumentListInfo &From, TemplateArgumentListInfo &Result) { + return ImportTemplateArgumentListInfo( + From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result); +} + +template <> +bool ASTNodeImporter::ImportTemplateArgumentListInfo< +ASTTemplateArgumentListInfo>(const ASTTemplateArgumentListInfo &From, + TemplateArgumentListInfo &Result) { + return ImportTemplateArgumentListInfo(From.LAngleLoc, From.RAngleLoc, +From.arguments(), Result); +} + bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import @@ -1655,10 +1669,8 @@ Decl *ASTNodeImporter::VisitTypedefNameD SourceLocation StartL = Importer.Import(D->getLocStart()); TypedefNameDecl *ToTypedef; if (IsAlias) -ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC, - StartL, Loc, - Name.getAsIdentifierInfo(), - TInfo); +ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC, StartL, Loc, + Name.getAsIdentifierInfo(), TInfo); else ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC, StartL, Loc, @@ -1668,7 +1680,11 @@ Decl *ASTNodeImporter::VisitTypedefNameD ToTypedef->setAccess(D->getAccess()); ToTypedef->setLexicalDeclContext(LexicalDC); Importer.Imported(D, ToTypedef); - LexicalDC->addDeclInternal(ToTypedef); + + // Templated declarations should not appear in DeclContext. + TypeAliasDecl *FromAlias = IsAlias ? cast(D) : nullptr; + if (!FromAlias || !FromAlias->getDescribedAliasTemplate()) +LexicalDC->addDeclInternal(ToTypedef); return ToTypedef; } @@ -1686,11 +1702,11 @@ Decl *ASTNodeImporter::VisitTypeAliasTem DeclContext *DC, *LexicalDC; DeclarationName Name; SourceLocation Loc; - NamedDecl *ToD; - if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) + NamedDecl *FoundD; + if (ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc)) return nullptr; - if (ToD) -return ToD; + if (FoundD) +return FoundD; // If this typedef is not in block scope, determine whether we've // seen a typedef with the same name (that we can merge with) or any @@ -1723,7 +1739,7 @@ Decl *ASTNodeImporter::VisitTypeAliasTem if (!Params) return nullptr; - NamedDecl *TemplDecl = cast_or_null( + auto *TemplDecl = cast_or_null( Importer.Import(D->getTemplatedDecl())); if (!TemplDecl) return nullptr; @@ -1731,11 +1747,13 @@ Decl *ASTNodeImporter::VisitTypeAliasTem TypeAliasTemplateDecl *ToAlias = TypeAliasTemplateDecl::Create( Importer.getToContext(), DC, Loc, Name, Params, TemplDecl); + TemplDecl->setDescribedAliasTemplate(ToAlias); + ToAlias->setAccess(D->getAccess()); ToAlias->setLexicalDeclContext(LexicalDC); Importer.Imported(D, ToAlias); LexicalDC->addDeclInternal(ToAlias); - return ToD; + return ToAlias; } Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) { @@ -2155,12 +2173,9 @@ bool ASTNodeImporter::ImportTemplateInfo TemplateArgumentListInfo ToTAInfo; const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten; -if (FromTAArgsAsWritten) { - if (ImportTemplateArgumentListInfo( - FromTAArgsAsWritten->LAngleLoc, FromTAArgsAsWritten->RAngleLoc, - FromTAArgsAsWritten->arguments(), ToTAInfo)) +
r325118 - Quick fix for 325116 buildbots: move template specialization into namespace
Author: a.sidorin Date: Wed Feb 14 03:39:33 2018 New Revision: 325118 URL: http://llvm.org/viewvc/llvm-project?rev=325118&view=rev Log: Quick fix for 325116 buildbots: move template specialization into namespace Modified: cfe/trunk/lib/AST/ASTImporter.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=325118&r1=325117&r2=325118&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Feb 14 03:39:33 2018 @@ -360,8 +360,37 @@ namespace clang { // Importing overrides. void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod); }; + + +template +bool ASTNodeImporter::ImportTemplateArgumentListInfo( +SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc, +const InContainerTy &Container, TemplateArgumentListInfo &Result) { + TemplateArgumentListInfo ToTAInfo(Importer.Import(FromLAngleLoc), +Importer.Import(FromRAngleLoc)); + if (ImportTemplateArgumentListInfo(Container, ToTAInfo)) +return true; + Result = ToTAInfo; + return false; +} + +template <> +bool ASTNodeImporter::ImportTemplateArgumentListInfo( +const TemplateArgumentListInfo &From, TemplateArgumentListInfo &Result) { + return ImportTemplateArgumentListInfo( + From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result); +} + +template <> +bool ASTNodeImporter::ImportTemplateArgumentListInfo< +ASTTemplateArgumentListInfo>(const ASTTemplateArgumentListInfo &From, + TemplateArgumentListInfo &Result) { + return ImportTemplateArgumentListInfo(From.LAngleLoc, From.RAngleLoc, +From.arguments(), Result); } +} // end namespace clang + // // Import Types // @@ -1322,33 +1351,6 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } -template -bool ASTNodeImporter::ImportTemplateArgumentListInfo( -SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc, -const InContainerTy &Container, TemplateArgumentListInfo &Result) { - TemplateArgumentListInfo ToTAInfo(Importer.Import(FromLAngleLoc), -Importer.Import(FromRAngleLoc)); - if (ImportTemplateArgumentListInfo(Container, ToTAInfo)) -return true; - Result = ToTAInfo; - return false; -} - -template <> -bool ASTNodeImporter::ImportTemplateArgumentListInfo( -const TemplateArgumentListInfo &From, TemplateArgumentListInfo &Result) { - return ImportTemplateArgumentListInfo( - From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result); -} - -template <> -bool ASTNodeImporter::ImportTemplateArgumentListInfo< -ASTTemplateArgumentListInfo>(const ASTTemplateArgumentListInfo &From, - TemplateArgumentListInfo &Result) { - return ImportTemplateArgumentListInfo(From.LAngleLoc, From.RAngleLoc, -From.arguments(), Result); -} - bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r320942 - [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr
Author: a.sidorin Date: Sun Dec 17 06:16:17 2017 New Revision: 320942 URL: http://llvm.org/viewvc/llvm-project?rev=320942&view=rev Log: [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr * Also introduces ImportTemplateArgumentListInfo facility (A. Sidorin) Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D38692 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=320942&r1=320941&r2=320942&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Dec 17 06:16:17 2017 @@ -134,12 +134,17 @@ namespace clang { bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); +template +bool ImportTemplateArgumentListInfo(const InContainerTy &Container, +TemplateArgumentListInfo &ToTAInfo); bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain = true); bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, bool Complain = true); bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); +bool IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To); bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); @@ -195,6 +200,7 @@ namespace clang { ClassTemplateSpecializationDecl *D); Decl *VisitVarTemplateDecl(VarTemplateDecl *D); Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); +Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); // Importing statements DeclGroupRef ImportDeclGroup(DeclGroupRef DG); @@ -280,6 +286,7 @@ namespace clang { Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); +Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -1247,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } +template +bool ASTNodeImporter::ImportTemplateArgumentListInfo( +const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { + for (const auto &FromLoc : Container) { +if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) + ToTAInfo.addArgument(*ToLoc); +else + return true; + } + return false; +} + bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import @@ -1280,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch( return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); } +bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, +FunctionTemplateDecl *To) { + StructuralEquivalenceContext Ctx( + Importer.getFromContext(), Importer.getToContext(), + Importer.getNonEquivalentDecls(), false, false); + return Ctx.IsStructurallyEquivalent(From, To); +} + bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC) { @@ -4197,6 +4224,64 @@ Decl *ASTNodeImporter::VisitVarTemplateS return D2; } +Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD; + + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) +return nullptr; + + if (ToD) +return ToD; + + // Try to find a function in our own ("to") context with the same name, same + // type, and in the same context as the function we're importing. + if (!LexicalDC->isFunctionOrMethod()) { +unsigned IDNS = Decl::IDNS_Ordinary; +SmallVector FoundDecls; +DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); +for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { + if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) +continue; + + if (FunctionTemplateDecl *FoundFunction = + dyn_cast(FoundDecls[I])) { +if (FoundFunction->hasExternalFormalLinkage() && +D->hasExternal
Re: r320942 - [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr
Thank you, Peter! I'll take a look. Unfortunately, there were no any buildbot e-mail complains about it so I didn't even notice the issue. 20.12.2017 04:48, Peter Collingbourne пишет: Hi, I reverted this change in r321139 because it causes a test failure on Windows. e.g. https://logs.chromium.org/v/?s=chromium%2Fbb%2Ftryserver.chromium.win%2Fwin_upload_clang%2F277%2F%2B%2Frecipes%2Fsteps%2Fpackage_clang%2F0%2Fstdout Please let me know if you have trouble reproducing. Thanks, Peter On Sun, Dec 17, 2017 at 6:16 AM, Aleksei Sidorin via cfe-commits mailto:cfe-commits@lists.llvm.org>> wrote: Author: a.sidorin Date: Sun Dec 17 06:16:17 2017 New Revision: 320942 URL: http://llvm.org/viewvc/llvm-project?rev=320942&view=rev <http://llvm.org/viewvc/llvm-project?rev=320942&view=rev> Log: [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr * Also introduces ImportTemplateArgumentListInfo facility (A. Sidorin) Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D38692 <https://reviews.llvm.org/D38692> Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=320942&r1=320941&r2=320942&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=320942&r1=320941&r2=320942&view=diff> == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Dec 17 06:16:17 2017 @@ -134,12 +134,17 @@ namespace clang { bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); + template + bool ImportTemplateArgumentListInfo(const InContainerTy &Container, + TemplateArgumentListInfo &ToTAInfo); bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain = true); bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, bool Complain = true); bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); + bool IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To); bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); @@ -195,6 +200,7 @@ namespace clang { ClassTemplateSpecializationDecl *D); Decl *VisitVarTemplateDecl(VarTemplateDecl *D); Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); + Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); // Importing statements DeclGroupRef ImportDeclGroup(DeclGroupRef DG); @@ -280,6 +286,7 @@ namespace clang { Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); + Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -1247,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } +template +bool ASTNodeImporter::ImportTemplateArgumentListInfo( + const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { + for (const auto &FromLoc : Container) { + if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) + ToTAInfo.addArgument(*ToLoc); + else + return true; + } + return false; +} + bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import @@ -1280,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch( return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); } +bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To) { + StructuralEquivalenceContext Ctx( + Importer.getFromContext(), Importer.getToContext(), + Importer.getNonEquivalentDecls(), false, false); + return Ctx.IsStructurallyEquivalent(Fro
r321285 - [ASTImporterTest] Add mandatory testing with '-fdelayed-template-parsing'
Author: a.sidorin Date: Thu Dec 21 09:41:06 2017 New Revision: 321285 URL: http://llvm.org/viewvc/llvm-project?rev=321285&view=rev Log: [ASTImporterTest] Add mandatory testing with '-fdelayed-template-parsing' * While running ASTImporterTests, we often forget about Windows MSVC buildbots which enable '-fdelayed-template-parsing' by default. This leads to AST import errors because templates are not parsed and corresponding parts of AST are not built so importer cannot import them. It takes both reviewing time to find such issues and post-commit time to fix unexpected buildbot failures. To solve this issue, we enable testing with '-fdelayed-template-parsing' option enabled by default in addition to testing with default compiler options. This allows us to catch the problem during development. Differential Revision: https://reviews.llvm.org/D41444 Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=321285&r1=321284&r2=321285&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Thu Dec 21 09:41:06 2017 @@ -22,38 +22,50 @@ namespace clang { namespace ast_matchers { -typedef std::vector StringVector; +typedef std::vector ArgVector; +typedef std::vector RunOptions; -void getLangArgs(Language Lang, StringVector &Args) { +static bool isCXX(Language Lang) { + return Lang == Lang_CXX || Lang == Lang_CXX11; +} + +static RunOptions getRunOptionsForLanguage(Language Lang) { + ArgVector BasicArgs; + // Test with basic arguments. switch (Lang) { case Lang_C: -Args.insert(Args.end(), { "-x", "c", "-std=c99" }); +BasicArgs = {"-x", "c", "-std=c99"}; break; case Lang_C89: -Args.insert(Args.end(), { "-x", "c", "-std=c89" }); +BasicArgs = {"-x", "c", "-std=c89"}; break; case Lang_CXX: -Args.push_back("-std=c++98"); +BasicArgs = {"-std=c++98"}; break; case Lang_CXX11: -Args.push_back("-std=c++11"); +BasicArgs = {"-std=c++11"}; break; case Lang_OpenCL: case Lang_OBJCXX: -break; +llvm_unreachable("Not implemented yet!"); } + + // For C++, test with "-fdelayed-template-parsing" enabled to handle MSVC + // default behaviour. + if (isCXX(Lang)) { +ArgVector ArgsForDelayedTemplateParse = BasicArgs; +ArgsForDelayedTemplateParse.emplace_back("-fdelayed-template-parsing"); +return {BasicArgs, ArgsForDelayedTemplateParse}; + } + + return {BasicArgs}; } template testing::AssertionResult -testImport(const std::string &FromCode, Language FromLang, - const std::string &ToCode, Language ToLang, - MatchVerifier &Verifier, - const MatcherType &AMatcher) { - StringVector FromArgs, ToArgs; - getLangArgs(FromLang, FromArgs); - getLangArgs(ToLang, ToArgs); - +testImport(const std::string &FromCode, const ArgVector &FromArgs, + const std::string &ToCode, const ArgVector &ToArgs, + MatchVerifier &Verifier, const MatcherType &AMatcher) { const char *const InputFileName = "input.cc"; const char *const OutputFileName = "output.cc"; @@ -92,7 +104,7 @@ testImport(const std::string &FromCode, return testing::AssertionFailure() << "Import failed, nullptr returned!"; // This should dump source locations and assert if some source locations - // were not imported + // were not imported. SmallString<1024> ImportChecker; llvm::raw_svector_ostream ToNothing(ImportChecker); ToCtx.getTranslationUnitDecl()->print(ToNothing); @@ -104,148 +116,154 @@ testImport(const std::string &FromCode, return Verifier.match(Imported, AMatcher); } +template +void testImport(const std::string &FromCode, Language FromLang, +const std::string &ToCode, Language ToLang, +MatchVerifier &Verifier, +const MatcherType &AMatcher) { + auto RunOptsFrom = getRunOptionsForLanguage(FromLang); + auto RunOptsTo = getRunOptionsForLanguage(ToLang); + for (const auto &FromArgs : RunOptsFrom) +for (const auto &ToArgs : RunOptsTo) + EXPECT_TRUE(testImport(FromCode, FromArgs, ToCode, ToArgs, + Verifier, AMatcher)); +} + + TEST(ImportExpr, ImportStringLiteral) { MatchVerifier Verifier; - EXPECT_TRUE(testImport("void declToImport() { \"foo\"; }", - Lang_CXX, "", Lang_CXX, Verifier, - functionDecl( - hasBody( - compoundStmt( - has( - stringLiteral( - hasType( - asString("const char [4]"); - EXPECT_TRUE(testImport("void declToImport() { L\"foo\"; }", -
r321492 - [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr
Author: a.sidorin Date: Wed Dec 27 09:04:42 2017 New Revision: 321492 URL: http://llvm.org/viewvc/llvm-project?rev=321492&view=rev Log: [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr * Also introduces ImportTemplateArgumentListInfo facility (A. Sidorin) This re-commits r320942 after fixing the behaviour on '-fdelayed-template-parsing' option and adding additional checks. Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D38692 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=321492&r1=321491&r2=321492&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Dec 27 09:04:42 2017 @@ -134,12 +134,17 @@ namespace clang { bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); +template +bool ImportTemplateArgumentListInfo(const InContainerTy &Container, +TemplateArgumentListInfo &ToTAInfo); bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain = true); bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, bool Complain = true); bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); +bool IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To); bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); @@ -195,6 +200,7 @@ namespace clang { ClassTemplateSpecializationDecl *D); Decl *VisitVarTemplateDecl(VarTemplateDecl *D); Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); +Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); // Importing statements DeclGroupRef ImportDeclGroup(DeclGroupRef DG); @@ -280,6 +286,7 @@ namespace clang { Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); +Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -1247,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } +template +bool ASTNodeImporter::ImportTemplateArgumentListInfo( +const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { + for (const auto &FromLoc : Container) { +if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) + ToTAInfo.addArgument(*ToLoc); +else + return true; + } + return false; +} + bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import @@ -1280,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch( return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); } +bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, +FunctionTemplateDecl *To) { + StructuralEquivalenceContext Ctx( + Importer.getFromContext(), Importer.getToContext(), + Importer.getNonEquivalentDecls(), false, false); + return Ctx.IsStructurallyEquivalent(From, To); +} + bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC) { @@ -4197,6 +4224,64 @@ Decl *ASTNodeImporter::VisitVarTemplateS return D2; } +Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { + DeclContext *DC, *LexicalDC; + DeclarationName Name; + SourceLocation Loc; + NamedDecl *ToD; + + if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc)) +return nullptr; + + if (ToD) +return ToD; + + // Try to find a function in our own ("to") context with the same name, same + // type, and in the same context as the function we're importing. + if (!LexicalDC->isFunctionOrMethod()) { +unsigned IDNS = Decl::IDNS_Ordinary; +SmallVector FoundDecls; +DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls); +for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) { + if (!FoundDecls[I]->isInIdentifierNamespace(IDNS)) +continue; + + if (FunctionTemplateDecl *FoundFunction = +
Re: r320942 - [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr
Hello Peter, I've recommitted the patch after attempt to fix it (rL321492). Please tell me if you see any issue. Thank you. 20.12.2017 12:05, Aleksei Sidorin пишет: Thank you, Peter! I'll take a look. Unfortunately, there were no any buildbot e-mail complains about it so I didn't even notice the issue. 20.12.2017 04:48, Peter Collingbourne пишет: Hi, I reverted this change in r321139 because it causes a test failure on Windows. e.g. https://logs.chromium.org/v/?s=chromium%2Fbb%2Ftryserver.chromium.win%2Fwin_upload_clang%2F277%2F%2B%2Frecipes%2Fsteps%2Fpackage_clang%2F0%2Fstdout Please let me know if you have trouble reproducing. Thanks, Peter On Sun, Dec 17, 2017 at 6:16 AM, Aleksei Sidorin via cfe-commits mailto:cfe-commits@lists.llvm.org>> wrote: Author: a.sidorin Date: Sun Dec 17 06:16:17 2017 New Revision: 320942 URL: http://llvm.org/viewvc/llvm-project?rev=320942&view=rev <http://llvm.org/viewvc/llvm-project?rev=320942&view=rev> Log: [ASTImporter] Support importing FunctionTemplateDecl and CXXDependentScopeMemberExpr * Also introduces ImportTemplateArgumentListInfo facility (A. Sidorin) Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D38692 <https://reviews.llvm.org/D38692> Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=320942&r1=320941&r2=320942&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=320942&r1=320941&r2=320942&view=diff> == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Dec 17 06:16:17 2017 @@ -134,12 +134,17 @@ namespace clang { bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); + template + bool ImportTemplateArgumentListInfo(const InContainerTy &Container, + TemplateArgumentListInfo &ToTAInfo); bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain = true); bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, bool Complain = true); bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord); bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC); + bool IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To); bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); @@ -195,6 +200,7 @@ namespace clang { ClassTemplateSpecializationDecl *D); Decl *VisitVarTemplateDecl(VarTemplateDecl *D); Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D); + Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D); // Importing statements DeclGroupRef ImportDeclGroup(DeclGroupRef DG); @@ -280,6 +286,7 @@ namespace clang { Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); + Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -1247,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } +template +bool ASTNodeImporter::ImportTemplateArgumentListInfo( + const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { + for (const auto &FromLoc : Container) { + if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc)) + ToTAInfo.addArgument(*ToLoc); + else + return true; + } + return false; +} + bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain) { // Eliminate a potential failure point where we attempt to re-import @@ -1280,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch( return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum); } +bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From, + FunctionTemplateDecl *To) { +
r322079 - [ASTImporter] Fix missing SourceLoc import for ObjCMethodDecl selectors
Author: a.sidorin Date: Tue Jan 9 06:25:05 2018 New Revision: 322079 URL: http://llvm.org/viewvc/llvm-project?rev=322079&view=rev Log: [ASTImporter] Fix missing SourceLoc import for ObjCMethodDecl selectors Patch by Nico Rieck, test case by Sean Callanan! Differential Revision: https://reviews.llvm.org/D6550 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/test/ASTMerge/interface/Inputs/interface1.m Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=322079&r1=322078&r2=322079&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Jan 9 06:25:05 2018 @@ -2857,9 +2857,13 @@ Decl *ASTNodeImporter::VisitObjCMethodDe ToParams[I]->setOwningFunction(ToMethod); ToMethod->addDeclInternal(ToParams[I]); } + SmallVector SelLocs; D->getSelectorLocs(SelLocs); - ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs); + for (SourceLocation &Loc : SelLocs) +Loc = Importer.Import(Loc); + + ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs); ToMethod->setLexicalDeclContext(LexicalDC); Importer.Imported(D, ToMethod); Modified: cfe/trunk/test/ASTMerge/interface/Inputs/interface1.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/interface/Inputs/interface1.m?rev=322079&r1=322078&r2=322079&view=diff == --- cfe/trunk/test/ASTMerge/interface/Inputs/interface1.m (original) +++ cfe/trunk/test/ASTMerge/interface/Inputs/interface1.m Tue Jan 9 06:25:05 2018 @@ -100,4 +100,6 @@ @implementation I15 : I12 @end - +@interface ImportSelectorSLoc { } +-(int)addInt:(int)a toInt:(int)b moduloInt:(int)c; // don't crash here +@end ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r322091 - [ASTImporter] Support importing CXXUnresolvedConstructExpr and UnresolvedLookupExpr
Author: a.sidorin Date: Tue Jan 9 08:40:40 2018 New Revision: 322091 URL: http://llvm.org/viewvc/llvm-project?rev=322091&view=rev Log: [ASTImporter] Support importing CXXUnresolvedConstructExpr and UnresolvedLookupExpr * Note: This solution is based on https://github.com/haoNoQ/clang/blob/summary-ipa-draft/lib/AST/ASTImporter.cpp#L7605. Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D38694 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=322091&r1=322090&r2=322091&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Jan 9 08:40:40 2018 @@ -287,6 +287,8 @@ namespace clang { Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E); Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); +Expr *VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *CE); +Expr *VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E); Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); @@ -5887,6 +5889,65 @@ Expr *ASTNodeImporter::VisitCXXDependent cast_or_null(ToFQ), MemberNameInfo, ResInfo); } +Expr *ASTNodeImporter::VisitCXXUnresolvedConstructExpr( +CXXUnresolvedConstructExpr *CE) { + + unsigned NumArgs = CE->arg_size(); + + llvm::SmallVector ToArgs(NumArgs); + if (ImportArrayChecked(CE->arg_begin(), CE->arg_end(), ToArgs.begin())) +return nullptr; + + return CXXUnresolvedConstructExpr::Create( + Importer.getToContext(), Importer.Import(CE->getTypeSourceInfo()), + Importer.Import(CE->getLParenLoc()), llvm::makeArrayRef(ToArgs), + Importer.Import(CE->getRParenLoc())); +} + +Expr *ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { + CXXRecordDecl *NamingClass = + cast_or_null(Importer.Import(E->getNamingClass())); + if (E->getNamingClass() && !NamingClass) +return nullptr; + + DeclarationName Name = Importer.Import(E->getName()); + if (E->getName() && !Name) +return nullptr; + + DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc())); + // Import additional name location/type info. + ImportDeclarationNameLoc(E->getNameInfo(), NameInfo); + + UnresolvedSet<8> ToDecls; + for (Decl *D : E->decls()) { +if (NamedDecl *To = cast_or_null(Importer.Import(D))) + ToDecls.addDecl(To); +else + return nullptr; + } + + TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()), +Importer.Import(E->getRAngleLoc())); + TemplateArgumentListInfo *ResInfo = nullptr; + if (E->hasExplicitTemplateArgs()) { +if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo)) + return nullptr; +ResInfo = &ToTAInfo; + } + + if (ResInfo || E->getTemplateKeywordLoc().isValid()) +return UnresolvedLookupExpr::Create( +Importer.getToContext(), NamingClass, +Importer.Import(E->getQualifierLoc()), +Importer.Import(E->getTemplateKeywordLoc()), NameInfo, E->requiresADL(), +ResInfo, ToDecls.begin(), ToDecls.end()); + + return UnresolvedLookupExpr::Create( + Importer.getToContext(), NamingClass, + Importer.Import(E->getQualifierLoc()), NameInfo, E->requiresADL(), + E->isOverloaded(), ToDecls.begin(), ToDecls.end()); +} + Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=322091&r1=322090&r2=322091&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Tue Jan 9 08:40:40 2018 @@ -656,5 +656,40 @@ TEST(ImportDecl, ImportUsingShadowDecl) namespaceDecl(has(usingShadowDecl(; } +TEST(ImportExpr, ImportUnresolvedLookupExpr) { + MatchVerifier Verifier; + testImport("template int foo();" + "template void declToImport() {" + " ::foo;" + " ::template foo;" + "}" + "void instantiate() { declToImport(); }", + Lang_CXX, "", Lang_CXX, Verifier, + functionTemplateDecl(has(functionDecl(has( + compoundStmt(has(unresolvedLookupExpr(; +} + +TEST(ImportExpr, ImportCXXUnresolvedConstructExpr) { + MatchVerifier Verifier; + testImport("template class C { T t; };" + "template void declToImport() {" + " C d;" + " d.t = T();"
r344847 - [NFC][Test commit] Fix typos in a comment
Author: a.sidorin Date: Sat Oct 20 07:47:37 2018 New Revision: 344847 URL: http://llvm.org/viewvc/llvm-project?rev=344847&view=rev Log: [NFC][Test commit] Fix typos in a comment Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp?rev=344847&r1=344846&r2=344847&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp Sat Oct 20 07:47:37 2018 @@ -441,8 +441,8 @@ void CheckerManager::runCheckersForEndFu ExplodedNode *Pred, ExprEngine &Eng, const ReturnStmt *RS) { - // We define the builder outside of the loop bacause if at least one checkers - // creates a sucsessor for Pred, we do not need to generate an + // We define the builder outside of the loop because if at least one checker + // creates a successor for Pred, we do not need to generate an // autotransition for it. NodeBuilder Bldr(Pred, Dst, BC); for (const auto checkFn : EndFunctionCheckers) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r344864 - [AST, analyzer] Transform rvalue cast outputs to lvalues (fheinous-gnu-extensions)
Author: a.sidorin Date: Sat Oct 20 15:49:23 2018 New Revision: 344864 URL: http://llvm.org/viewvc/llvm-project?rev=344864&view=rev Log: [AST, analyzer] Transform rvalue cast outputs to lvalues (fheinous-gnu-extensions) Despite the fact that cast expressions return rvalues, GCC still handles such outputs as lvalues when compiling inline assembler. In this commit, we are treating it by removing LValueToRValue casts inside GCCAsmStmt outputs. Differential Revision: https://reviews.llvm.org/D45416 Added: cfe/trunk/test/Analysis/asm.cpp Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp cfe/trunk/test/Analysis/cfg.cpp Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=344864&r1=344863&r2=344864&view=diff == --- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original) +++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Sat Oct 20 15:49:23 2018 @@ -27,6 +27,58 @@ using namespace clang; using namespace sema; +/// Remove the upper-level LValueToRValue cast from an expression. +static void removeLValueToRValueCast(Expr *E) { + Expr *Parent = E; + Expr *ExprUnderCast = nullptr; + SmallVector ParentsToUpdate; + + while (true) { +ParentsToUpdate.push_back(Parent); +if (auto *ParenE = dyn_cast(Parent)) { + Parent = ParenE->getSubExpr(); + continue; +} + +Expr *Child = nullptr; +CastExpr *ParentCast = dyn_cast(Parent); +if (ParentCast) + Child = ParentCast->getSubExpr(); +else + return; + +if (auto *CastE = dyn_cast(Child)) + if (CastE->getCastKind() == CK_LValueToRValue) { +ExprUnderCast = CastE->getSubExpr(); +// LValueToRValue cast inside GCCAsmStmt requires an explicit cast. +ParentCast->setSubExpr(ExprUnderCast); +break; + } +Parent = Child; + } + + // Update parent expressions to have same ValueType as the underlying. + assert(ExprUnderCast && + "Should be reachable only if LValueToRValue cast was found!"); + auto ValueKind = ExprUnderCast->getValueKind(); + for (Expr *E : ParentsToUpdate) +E->setValueKind(ValueKind); +} + +/// Emit a warning about usage of "noop"-like casts for lvalues (GNU extension) +/// and fix the argument with removing LValueToRValue cast from the expression. +static void emitAndFixInvalidAsmCastLValue(const Expr *LVal, Expr *BadArgument, + Sema &S) { + if (!S.getLangOpts().HeinousExtensions) { +S.Diag(LVal->getBeginLoc(), diag::err_invalid_asm_cast_lvalue) +<< BadArgument->getSourceRange(); + } else { +S.Diag(LVal->getBeginLoc(), diag::warn_invalid_asm_cast_lvalue) +<< BadArgument->getSourceRange(); + } + removeLValueToRValueCast(BadArgument); +} + /// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently /// ignore "noop" casts in places where an lvalue is required by an inline asm. /// We emulate this behavior when -fheinous-gnu-extensions is specified, but @@ -34,7 +86,7 @@ using namespace sema; /// /// This method checks to see if the argument is an acceptable l-value and /// returns false if it is a case we can handle. -static bool CheckAsmLValue(const Expr *E, Sema &S) { +static bool CheckAsmLValue(Expr *E, Sema &S) { // Type dependent expressions will be checked during instantiation. if (E->isTypeDependent()) return false; @@ -46,12 +98,7 @@ static bool CheckAsmLValue(const Expr *E // are supposed to allow. const Expr *E2 = E->IgnoreParenNoopCasts(S.Context); if (E != E2 && E2->isLValue()) { -if (!S.getLangOpts().HeinousExtensions) - S.Diag(E2->getBeginLoc(), diag::err_invalid_asm_cast_lvalue) - << E->getSourceRange(); -else - S.Diag(E2->getBeginLoc(), diag::warn_invalid_asm_cast_lvalue) - << E->getSourceRange(); +emitAndFixInvalidAsmCastLValue(E2, E, S); // Accept, even if we emitted an error diagnostic. return false; } @@ -264,13 +311,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceL break; case Expr::MLV_LValueCast: { const Expr *LVal = OutputExpr->IgnoreParenNoopCasts(Context); - if (!getLangOpts().HeinousExtensions) { -Diag(LVal->getBeginLoc(), diag::err_invalid_asm_cast_lvalue) -<< OutputExpr->getSourceRange(); - } else { -Diag(LVal->getBeginLoc(), diag::warn_invalid_asm_cast_lvalue) -<< OutputExpr->getSourceRange(); - } + emitAndFixInvalidAsmCastLValue(LVal, OutputExpr, *this); // Accept, even if we emitted an error diagnostic. break; } Added: cfe/trunk/test/Analysis/asm.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/asm.cpp?rev=344864&view=auto == --- cfe/trunk/test/Analysis/asm.cpp (added) +++ cfe/trunk/test/Analysis/asm.cpp Sat Oct 20 15:49:23 2018 @@ -0,0 +
r345545 - [ASTImporter] Reorder fields after structure import is finished
Author: a.sidorin Date: Mon Oct 29 14:46:18 2018 New Revision: 345545 URL: http://llvm.org/viewvc/llvm-project?rev=345545&view=rev Log: [ASTImporter] Reorder fields after structure import is finished There are multiple reasons why field structures can be imported in wrong order. The simplest is the ability of field initializers and method bodies to refer fields not in order they are listed in. Unfortunately, there is no clean solution for that currently so I'm leaving a FIXME. Differential Revision: https://reviews.llvm.org/D44100 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=345545&r1=345544&r2=345545&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Oct 29 14:46:18 2018 @@ -1658,13 +1658,53 @@ ASTNodeImporter::ImportDeclContext(DeclC auto ToDCOrErr = Importer.ImportContext(FromDC); return ToDCOrErr.takeError(); } - llvm::SmallVector ImportedDecls; + + const auto *FromRD = dyn_cast(FromDC); for (auto *From : FromDC->decls()) { ExpectedDecl ImportedOrErr = import(From); -if (!ImportedOrErr) +if (!ImportedOrErr) { + // For RecordDecls, failed import of a field will break the layout of the + // structure. Handle it as an error. + if (FromRD) +return ImportedOrErr.takeError(); // Ignore the error, continue with next Decl. // FIXME: Handle this case somehow better. - consumeError(ImportedOrErr.takeError()); + else +consumeError(ImportedOrErr.takeError()); +} + } + + // Reorder declarations in RecordDecls because they may have another + // order. Keeping field order is vitable because it determines structure + // layout. + // FIXME: This is an ugly fix. Unfortunately, I cannot come with better + // solution for this issue. We cannot defer expression import here because + // type import can depend on them. + if (!FromRD) +return Error::success(); + + auto ImportedDC = import(cast(FromDC)); + assert(ImportedDC); + auto *ToRD = cast(*ImportedDC); + + for (auto *D : FromRD->decls()) { +if (isa(D) || isa(D)) { + Decl *ToD = Importer.GetAlreadyImportedOrNull(D); + assert(ToRD == ToD->getDeclContext() && ToRD->containsDecl(ToD)); + ToRD->removeDecl(ToD); +} + } + + assert(ToRD->field_empty()); + + for (auto *D : FromRD->decls()) { +if (isa(D) || isa(D)) { + Decl *ToD = Importer.GetAlreadyImportedOrNull(D); + assert(ToRD == ToD->getDeclContext()); + assert(ToRD == ToD->getLexicalDeclContext()); + assert(!ToRD->containsDecl(ToD)); + ToRD->addDeclInternal(ToD); +} } return Error::success(); Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=345545&r1=345544&r2=345545&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Oct 29 14:46:18 2018 @@ -1457,7 +1457,7 @@ TEST_P(ASTImporterTestBase, CXXRecordDec } TEST_P(ASTImporterTestBase, - DISABLED_CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) { + CXXRecordDeclFieldOrderShouldNotDependOnImportOrder) { Decl *From, *To; std::tie(From, To) = getImportedDecl( // The original recursive algorithm of ASTImporter first imports 'c' then @@ -3767,5 +3767,16 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTes INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportVariables, DefaultTestValuesForRunOptions, ); +TEST_P(ImportDecl, ImportFieldOrder) { + MatchVerifier Verifier; + testImport("struct declToImport {" + " int b = a + 2;" + " int a = 5;" + "};", + Lang_CXX11, "", Lang_CXX11, Verifier, + recordDecl(hasFieldOrder({"b", "a"}))); +} + + } // end namespace ast_matchers } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r330605 - [analyzer] Don't crash on printing ConcreteInt of size >64 bits
Author: a.sidorin Date: Mon Apr 23 08:41:44 2018 New Revision: 330605 URL: http://llvm.org/viewvc/llvm-project?rev=330605&view=rev Log: [analyzer] Don't crash on printing ConcreteInt of size >64 bits Printing of ConcreteInts with size >64 bits resulted in assertion failure in get[Z|S]ExtValue() because these methods are only allowed to be used with integers of 64 max bit width. This patch fixes the issue. Added: cfe/trunk/test/Analysis/sval-dump-int128.c Modified: cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp?rev=330605&r1=330604&r2=330605&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/SVals.cpp Mon Apr 23 08:41:44 2018 @@ -300,13 +300,9 @@ void SVal::dumpToStream(raw_ostream &os) void NonLoc::dumpToStream(raw_ostream &os) const { switch (getSubKind()) { case nonloc::ConcreteIntKind: { - const nonloc::ConcreteInt& C = castAs(); - if (C.getValue().isUnsigned()) -os << C.getValue().getZExtValue(); - else -os << C.getValue().getSExtValue(); - os << ' ' << (C.getValue().isUnsigned() ? 'U' : 'S') - << C.getValue().getBitWidth() << 'b'; + const auto &Value = castAs().getValue(); + os << Value << ' ' << (Value.isSigned() ? 'S' : 'U') + << Value.getBitWidth() << 'b'; break; } case nonloc::SymbolValKind: Added: cfe/trunk/test/Analysis/sval-dump-int128.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/sval-dump-int128.c?rev=330605&view=auto == --- cfe/trunk/test/Analysis/sval-dump-int128.c (added) +++ cfe/trunk/test/Analysis/sval-dump-int128.c Mon Apr 23 08:41:44 2018 @@ -0,0 +1,7 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection %s -verify + +void clang_analyzer_dump(unsigned __int128 x); + +void testDumpInt128() { + clang_analyzer_dump((unsigned __int128)5 << 64); // expected-warning{{92233720368547758080 U128b}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r330613 - Quick fix for rC330605: specify a target arch for test
Author: a.sidorin Date: Mon Apr 23 09:38:29 2018 New Revision: 330613 URL: http://llvm.org/viewvc/llvm-project?rev=330613&view=rev Log: Quick fix for rC330605: specify a target arch for test Modified: cfe/trunk/test/Analysis/sval-dump-int128.c Modified: cfe/trunk/test/Analysis/sval-dump-int128.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/sval-dump-int128.c?rev=330613&r1=330612&r2=330613&view=diff == --- cfe/trunk/test/Analysis/sval-dump-int128.c (original) +++ cfe/trunk/test/Analysis/sval-dump-int128.c Mon Apr 23 09:38:29 2018 @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection %s -verify +// RUN: %clang_analyze_cc1 -triple x86_64-linux-gnu -analyzer-checker=debug.ExprInspection %s -verify void clang_analyzer_dump(unsigned __int128 x); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r330704 - [ASTImporter] Allow testing of import sequences; fix import of typedefs for anonymous decls
Author: a.sidorin Date: Tue Apr 24 03:11:53 2018 New Revision: 330704 URL: http://llvm.org/viewvc/llvm-project?rev=330704&view=rev Log: [ASTImporter] Allow testing of import sequences; fix import of typedefs for anonymous decls This patch introduces the ability to test an arbitrary sequence of imports between a given set of virtual source files. This should finally allow us to write simple tests and fix annoying issues inside ASTImporter that cause failures in CSA CTU. This is done by refactoring ASTImporterTest functions and introducing `testImportSequence` facility. As a side effect, `testImport` facility was generalized a bit more. It should now allow import of non-decl AST nodes; however, there is still no test using this ability. As a "test for test", there is also a fix for import anonymous TagDecls referred by typedef. Before this patch, the setting of typedef for anonymous structure was delayed; however, this approach misses the corner case if an enum constant is imported directly. In this patch, typedefs for anonymous declarations are imported right after the anonymous declaration is imported, without any delay. Thanks to Adam Balogh for suggestions included into this patch. Differential Revision: https://reviews.llvm.org/D44079 Modified: cfe/trunk/include/clang/AST/ASTImporter.h cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/test/Analysis/Inputs/ctu-other.cpp cfe/trunk/test/Analysis/Inputs/externalFnMap.txt cfe/trunk/test/Analysis/ctu-main.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/include/clang/AST/ASTImporter.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=330704&r1=330703&r2=330704&view=diff == --- cfe/trunk/include/clang/AST/ASTImporter.h (original) +++ cfe/trunk/include/clang/AST/ASTImporter.h Tue Apr 24 03:11:53 2018 @@ -83,10 +83,6 @@ class TypeSourceInfo; /// the "from" source manager to the corresponding CXXBasesSpecifier /// in the "to" source manager. ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers; - -/// \brief Imported, anonymous tag declarations that are missing their -/// corresponding typedefs. -SmallVector AnonTagsWithPendingTypedefs; /// \brief Declaration (from, to) pairs that are known not to be equivalent /// (which we have already complained about). @@ -136,6 +132,9 @@ class TypeSourceInfo; /// \returns the equivalent declaration in the "to" context, or a NULL type /// if an error occurred. Decl *Import(Decl *FromD); +Decl *Import(const Decl *FromD) { + return Import(const_cast(FromD)); +} /// \brief Return the copy of the given declaration in the "to" context if /// it has already been imported from the "from" context. Otherwise return Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=330704&r1=330703&r2=330704&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Apr 24 03:11:53 2018 @@ -1088,6 +1088,17 @@ void ASTNodeImporter::ImportDeclContext( Importer.Import(From); } +static void setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To, + ASTImporter &Importer) { + if (TypedefNameDecl *FromTypedef = From->getTypedefNameForAnonDecl()) { +auto *ToTypedef = + cast_or_null(Importer.Import(FromTypedef)); +assert (ToTypedef && "Failed to import typedef of an anonymous structure"); + +To->setTypedefNameForAnonDecl(ToTypedef); + } +} + bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) { if (To->getDefinition() || To->isBeingDefined()) { @@ -1098,6 +1109,8 @@ bool ASTNodeImporter::ImportDefinition(R } To->startDefinition(); + + setTypedefNameForAnonDecl(From, To, Importer); // Add base classes. if (auto *ToCXX = dyn_cast(To)) { @@ -1229,6 +1242,8 @@ bool ASTNodeImporter::ImportDefinition(E To->startDefinition(); + setTypedefNameForAnonDecl(From, To, Importer); + QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From)); if (T.isNull()) return true; @@ -1707,6 +1722,11 @@ Decl *ASTNodeImporter::VisitTypedefNameD if (T.isNull()) return nullptr; + // Some nodes (like anonymous tags referred by typedefs) are allowed to + // import their enclosing typedef directly. Check if this is the case. + if (Decl *AlreadyImported = Importer.GetAlreadyImportedOrNull(D)) +return AlreadyImported; + // Create the new typedef node. TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo()); SourceLocation StartL = Importer.Import(D->getLocStart()); @@ -6576,29 +6596,7 @@ Decl *ASTImporter::Import(Dec
r331762 - [ASTImporter] Properly import SourceLocations of Attrs
Author: a.sidorin Date: Tue May 8 05:45:21 2018 New Revision: 331762 URL: http://llvm.org/viewvc/llvm-project?rev=331762&view=rev Log: [ASTImporter] Properly import SourceLocations of Attrs Patch by Rafael Stahl! Differential Revision: https://reviews.llvm.org/D46115 Added: cfe/trunk/test/Import/attr/ cfe/trunk/test/Import/attr/Inputs/ cfe/trunk/test/Import/attr/Inputs/S.cpp cfe/trunk/test/Import/attr/test.cpp Modified: cfe/trunk/include/clang/AST/ASTImporter.h cfe/trunk/lib/AST/ASTImporter.cpp Modified: cfe/trunk/include/clang/AST/ASTImporter.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=331762&r1=331761&r2=331762&view=diff == --- cfe/trunk/include/clang/AST/ASTImporter.h (original) +++ cfe/trunk/include/clang/AST/ASTImporter.h Tue May 8 05:45:21 2018 @@ -41,6 +41,7 @@ class NamedDecl; class Stmt; class TagDecl; class TypeSourceInfo; +class Attr; /// \brief Imports selected nodes from one AST context into another context, /// merging AST nodes where appropriate. @@ -126,6 +127,12 @@ class TypeSourceInfo; /// context, or NULL if an error occurred. TypeSourceInfo *Import(TypeSourceInfo *FromTSI); +/// \brief Import the given attribute from the "from" context into the +/// "to" context. +/// +/// \returns the equivalent attribute in the "to" context. +Attr *Import(const Attr *FromAttr); + /// \brief Import the given declaration from the "from" context into the /// "to" context. /// Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=331762&r1=331761&r2=331762&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue May 8 05:45:21 2018 @@ -2687,8 +2687,8 @@ Decl *ASTNodeImporter::VisitIndirectFiel Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), T, {NamedChain, D->getChainingSize()}); - for (const auto *Attr : D->attrs()) -ToIndirectField->addAttr(Attr->clone(Importer.getToContext())); + for (const auto *A : D->attrs()) +ToIndirectField->addAttr(Importer.Import(A)); ToIndirectField->setAccess(D->getAccess()); ToIndirectField->setLexicalDeclContext(LexicalDC); @@ -4766,15 +4766,8 @@ Stmt *ASTNodeImporter::VisitAttributedSt SourceLocation ToAttrLoc = Importer.Import(S->getAttrLoc()); ArrayRef FromAttrs(S->getAttrs()); SmallVector ToAttrs(FromAttrs.size()); - ASTContext &_ToContext = Importer.getToContext(); - std::transform(FromAttrs.begin(), FromAttrs.end(), ToAttrs.begin(), -[&_ToContext](const Attr *A) -> const Attr * { - return A->clone(_ToContext); -}); - for (const auto *ToA : ToAttrs) { -if (!ToA) - return nullptr; - } + if (ImportContainerChecked(FromAttrs, ToAttrs)) +return nullptr; Stmt *ToSubStmt = Importer.Import(S->getSubStmt()); if (!ToSubStmt && S->getSubStmt()) return nullptr; @@ -6657,6 +6650,12 @@ TypeSourceInfo *ASTImporter::Import(Type Import(FromTSI->getTypeLoc().getLocStart())); } +Attr *ASTImporter::Import(const Attr *FromAttr) { + Attr *ToAttr = FromAttr->clone(ToContext); + ToAttr->setRange(Import(FromAttr->getRange())); + return ToAttr; +} + Decl *ASTImporter::GetAlreadyImportedOrNull(Decl *FromD) { llvm::DenseMap::iterator Pos = ImportedDecls.find(FromD); if (Pos != ImportedDecls.end()) { @@ -7290,8 +7289,8 @@ void ASTImporter::CompleteDecl (Decl *D) Decl *ASTImporter::Imported(Decl *From, Decl *To) { if (From->hasAttrs()) { -for (auto *FromAttr : From->getAttrs()) - To->addAttr(FromAttr->clone(To->getASTContext())); +for (const auto *FromAttr : From->getAttrs()) + To->addAttr(Import(FromAttr)); } if (From->isUsed()) { To->setIsUsed(); Added: cfe/trunk/test/Import/attr/Inputs/S.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Import/attr/Inputs/S.cpp?rev=331762&view=auto == --- cfe/trunk/test/Import/attr/Inputs/S.cpp (added) +++ cfe/trunk/test/Import/attr/Inputs/S.cpp Tue May 8 05:45:21 2018 @@ -0,0 +1,13 @@ +extern void f() __attribute__((const)); + +struct S { + struct { +int a __attribute__((packed)); + }; +}; + +void stmt() { +#pragma unroll + for (;;) +; +} Added: cfe/trunk/test/Import/attr/test.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Import/attr/test.cpp?rev=331762&view=auto == --- cfe/trunk/test/Import/attr/test.cpp (added) +++ cfe/trunk/test/Import/attr/test.cpp Tue May 8 05:45:21 2018 @@ -0,0 +1,26 @@ +// RUN: clang-import-test -dump-ast -import %S/Inputs/S.cpp -expression %s | FileCheck %s +// CHECK: FunctionDecl +// CHECK
[PATCH] D24807: [Serialization] ArrayTypeTraitExpr: serialize sub-expression to avoid keeping it undefined
a.sidorin created this revision. a.sidorin added reviewers: aaron.ballman, doug.gregor. a.sidorin added a subscriber: cfe-commits. I have encountered a segfault when I tried to get sub-expression of serialized ArrayTypeTraitExpr. The fix is simple but I have no idea about nice test. Maybe you have any suggestions? https://reviews.llvm.org/D24807 Files: lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp Index: lib/Serialization/ASTWriterStmt.cpp === --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -1576,6 +1576,7 @@ Record.push_back(E->getValue()); Record.AddSourceRange(E->getSourceRange()); Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo()); + Record.AddStmt(E->getDimensionExpression()); Code = serialization::EXPR_ARRAY_TYPE_TRAIT; } Index: lib/Serialization/ASTReaderStmt.cpp === --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -1575,6 +1575,7 @@ E->Loc = Range.getBegin(); E->RParen = Range.getEnd(); E->QueriedType = GetTypeSourceInfo(Record, Idx); + E->Dimension = Reader.ReadSubExpr(); } void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { Index: lib/Serialization/ASTWriterStmt.cpp === --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -1576,6 +1576,7 @@ Record.push_back(E->getValue()); Record.AddSourceRange(E->getSourceRange()); Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo()); + Record.AddStmt(E->getDimensionExpression()); Code = serialization::EXPR_ARRAY_TYPE_TRAIT; } Index: lib/Serialization/ASTReaderStmt.cpp === --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -1575,6 +1575,7 @@ E->Loc = Range.getBegin(); E->RParen = Range.getEnd(); E->QueriedType = GetTypeSourceInfo(Record, Idx); + E->Dimension = Reader.ReadSubExpr(); } void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin added a comment. Don't hurry. The segfault is fixed already and patch waits for approval: https://reviews.llvm.org/D24807. I'll update this fix in Monday. https://reviews.llvm.org/D14326 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin updated the summary for this revision. a.sidorin added reviewers: ABataev, aaron.ballman. a.sidorin updated this revision to Diff 72614. a.sidorin added a comment. Merge patch https://reviews.llvm.org/D24807 to both fix segmentation fault and provide a test for it. https://reviews.llvm.org/D14326 Files: include/clang/AST/ASTImporter.h include/clang/AST/DeclFriend.h lib/AST/ASTImporter.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp test/ASTMerge/Inputs/class3.cpp test/ASTMerge/class2.cpp test/ASTMerge/exprs.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -456,5 +456,24 @@ } +const internal::VariadicDynCastAllOfMatcher vaArgExpr; + +TEST(ImportExpr, ImportVAArgExpr) { + MatchVerifier Verifier; + EXPECT_TRUE( +testImport( + "void declToImport(__builtin_va_list list, ...) {" + " (void)__builtin_va_arg(list, int); }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl( +hasBody( + compoundStmt( +has( + cStyleCastExpr( +hasSourceExpression( + vaArgExpr(); +} + + } // end namespace ast_matchers } // end namespace clang Index: test/ASTMerge/exprs.cpp === --- /dev/null +++ test/ASTMerge/exprs.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(Ch1 == 'a'); +static_assert(Ch2 == 'b'); +static_assert(Ch3 == 'c'); + +static_assert(Ch4 == L'd'); +static_assert(Ch5 == L'e'); +static_assert(Ch6 == L'f'); + +static_assert(C1 == 12); +static_assert(C2 == 13); + +static_assert(C3 == 12); +static_assert(C4 == 13); + +static_assert(C5 == 22L); +static_assert(C6 == 23L); + +static_assert(C7 == 66LL); +static_assert(C8 == 67ULL); + +static_assert(bval1 == true); +static_assert(bval2 == false); + +static_assert(ExpressionTrait == false); + +static_assert(ArrayRank == 2); +static_assert(ArrayExtent == 20); + +void testImport(int *x, const S1 &cs1, S1 &s1) { + testNewThrowDelete(); + testArrayElement(nullptr, 12); + testTernaryOp(0, 1, 2); + testConstCast(cs1); + testStaticCast(s1); + testReinterpretCast(s1); + testDynamicCast(s1); + testScalarInit(42); + testOffsetOf(); + testDefaultArg(12); + useTemplateType(); +} Index: test/ASTMerge/class2.cpp === --- /dev/null +++ test/ASTMerge/class2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class C3 { + int method_1(C2 *x) { +return x->x; + } +}; Index: test/ASTMerge/Inputs/class3.cpp === --- /dev/null +++ test/ASTMerge/Inputs/class3.cpp @@ -0,0 +1,26 @@ +class C1 { +public: + C1(); + ~C1(); + C1 *method_1() { +return this; + } + C1 method_2() { +return C1(); + } + void method_3() { +const C1 &ref = C1(); + } +}; + +class C11 : public C1 { +}; + +class C2 { +private: + int x; + friend class C3; +public: + static_assert(sizeof(x) == sizeof(int), "Error"); + typedef class C2::C2 InjType; +}; Index: lib/Serialization/ASTWriterStmt.cpp === --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -1576,6 +1576,7 @@ Record.push_back(E->getValue()); Record.AddSourceRange(E->getSourceRange()); Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo()); + Record.AddStmt(E->getDimensionExpression()); Code = serialization::EXPR_ARRAY_TYPE_TRAIT; } Index: lib/Serialization/ASTReaderStmt.cpp === --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -1575,6 +1575,7 @@ E->Loc = Range.getBegin(); E->RParen = Range.getEnd(); E->QueriedType = GetTypeSourceInfo(Record, Idx); + E->Dimension = Reader.ReadSubExpr(); } void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -40,6 +40,7 @@ // Importing types QualType VisitType(const Type *T); QualType VisitBuiltinType(const BuiltinType *T); +QualType VisitDecayedType(const DecayedType *T
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin updated this revision to Diff 72625. a.sidorin added a comment. Address review comments; add accidentally missed file. https://reviews.llvm.org/D14326 Files: include/clang/AST/ASTImporter.h include/clang/AST/DeclFriend.h lib/AST/ASTImporter.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp test/ASTMerge/Inputs/class3.cpp test/ASTMerge/Inputs/exprs3.cpp test/ASTMerge/class2.cpp test/ASTMerge/exprs.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -456,5 +456,24 @@ } +const internal::VariadicDynCastAllOfMatcher vaArgExpr; + +TEST(ImportExpr, ImportVAArgExpr) { + MatchVerifier Verifier; + EXPECT_TRUE( +testImport( + "void declToImport(__builtin_va_list list, ...) {" + " (void)__builtin_va_arg(list, int); }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl( +hasBody( + compoundStmt( +has( + cStyleCastExpr( +hasSourceExpression( + vaArgExpr(); +} + + } // end namespace ast_matchers } // end namespace clang Index: test/ASTMerge/exprs.cpp === --- /dev/null +++ test/ASTMerge/exprs.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(Ch1 == 'a'); +static_assert(Ch2 == 'b'); +static_assert(Ch3 == 'c'); + +static_assert(Ch4 == L'd'); +static_assert(Ch5 == L'e'); +static_assert(Ch6 == L'f'); + +static_assert(C1 == 12); +static_assert(C2 == 13); + +static_assert(C3 == 12); +static_assert(C4 == 13); + +static_assert(C5 == 22L); +static_assert(C6 == 23L); + +static_assert(C7 == 66LL); +static_assert(C8 == 67ULL); + +static_assert(bval1 == true); +static_assert(bval2 == false); + +static_assert(ExpressionTrait == false); + +static_assert(ArrayRank == 2); +static_assert(ArrayExtent == 20); + +void testImport(int *x, const S1 &cs1, S1 &s1) { + testNewThrowDelete(); + testArrayElement(nullptr, 12); + testTernaryOp(0, 1, 2); + testConstCast(cs1); + testStaticCast(s1); + testReinterpretCast(s1); + testDynamicCast(s1); + testScalarInit(42); + testOffsetOf(); + testDefaultArg(12); + useTemplateType(); +} Index: test/ASTMerge/class2.cpp === --- /dev/null +++ test/ASTMerge/class2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class C3 { + int method_1(C2 *x) { +return x->x; + } +}; Index: test/ASTMerge/Inputs/exprs3.cpp === --- /dev/null +++ test/ASTMerge/Inputs/exprs3.cpp @@ -0,0 +1,131 @@ +// Integer literals +const char Ch1 = 'a'; +const signed char Ch2 = 'b'; +const unsigned char Ch3 = 'c'; + +const wchar_t Ch4 = L'd'; +const signed wchar_t Ch5 = L'e'; +const unsigned wchar_t Ch6 = L'f'; + +const short C1 = 12; +const unsigned short C2 = 13; + +const int C3 = 12; +const unsigned int C4 = 13; + +const long C5 = 22; +const unsigned long C6 = 23; + +const long long C7 = 66; +const unsigned long long C8 = 67; + + +// String literals +const char str1[] = "ABCD"; +const char str2[] = "ABCD" "0123"; + +const wchar_t wstr1[] = L"DEF"; +const wchar_t wstr2[] = L"DEF" L"123"; + + +// Boolean literals +const bool bval1 = true; +const bool bval2 = false; + +// Floating Literals +const float F1 = 12.2F; +const double F2 = 1E4; +const long double F3 = 1.2E-3L; + + +// nullptr literal +const void *vptr = nullptr; + + +int glb_1[4] = { 10, 20, 30, 40 }; + +struct S1 { + int a; + int b[3]; +}; + +struct S2 { + int c; + S1 d; +}; + +S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 }; + +void testNewThrowDelete() { + throw; + char *p = new char[10]; + delete[] p; +} + +int testArrayElement(int *x, int n) { + return x[n]; +} + +int testTernaryOp(int c, int x, int y) { + return c ? x : y; +} + +S1 &testConstCast(const S1 &x) { + return const_cast(x); +} + +S1 &testStaticCast(S1 &x) { + return static_cast(x); +} + +S1 &testReinterpretCast(S1 &x) { + return reinterpret_cast(x); +} + +S1 &testDynamicCast(S1 &x) { + return dynamic_cast(x); +} + +int testScalarInit(int x) { + return int(x); +} + +struct S { + float f; + double d; +}; +struct T { + int i; + struct S s[10]; +}; + +void testOffsetOf() { + __builtin_offsetof(struct T, s[2].d); +} + + +unsigned char asmFunc(unsign
r282572 - [ASTImporter] Implement some expression-related AST node import (part 2)
Author: a.sidorin Date: Wed Sep 28 05:16:56 2016 New Revision: 282572 URL: http://llvm.org/viewvc/llvm-project?rev=282572&view=rev Log: [ASTImporter] Implement some expression-related AST node import (part 2) * Some code cleanup * Add tests not present in http://reviews.llvm.org/D14286 * Integrate a test suite from Serge Pavlov (http://reviews.llvm.org/D14224) * ArrayTypeTraitExpr: serialize sub-expression to avoid keeping it undefined * Implement import of some nodes: - ArrayTypeTraitExpr - ExpressionTraitExpr - OpaqueValueExpr - ArraySubscriptExpr - ExplicitCastExpr - ImplicitValueInitExpr - OffsetOfExpr - CXXThisExpr - CXXThrowExpr - CXXNoexceptExpr - CXXDefaultArgExpr - CXXScalarValueInitExpr - CXXBindTemporaryExpr - CXXTemporaryObjectExpr - MaterializeTemporaryExpr - ExprWithCleanups - StaticAssertDecl - FriendDecl - DecayedType Differential Revision: https://reviews.llvm.org/D14326 Added: cfe/trunk/test/ASTMerge/Inputs/class3.cpp cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp cfe/trunk/test/ASTMerge/class2.cpp cfe/trunk/test/ASTMerge/exprs.cpp Modified: cfe/trunk/include/clang/AST/ASTImporter.h cfe/trunk/include/clang/AST/DeclFriend.h cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/include/clang/AST/ASTImporter.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=282572&r1=282571&r2=282572&view=diff == --- cfe/trunk/include/clang/AST/ASTImporter.h (original) +++ cfe/trunk/include/clang/AST/ASTImporter.h Wed Sep 28 05:16:56 2016 @@ -24,6 +24,7 @@ namespace clang { class ASTContext; class CXXCtorInitializer; + class CXXBaseSpecifier; class Decl; class DeclContext; class DiagnosticsEngine; @@ -39,7 +40,9 @@ namespace clang { class ASTImporter { public: typedef llvm::DenseSet > NonEquivalentDeclSet; - +typedef llvm::DenseMap +ImportedCXXBaseSpecifierMap; + private: /// \brief The contexts we're importing to and from. ASTContext &ToContext, &FromContext; @@ -68,7 +71,12 @@ namespace clang { /// \brief Mapping from the already-imported FileIDs in the "from" source /// manager to the corresponding FileIDs in the "to" source manager. llvm::DenseMap ImportedFileIDs; - + +/// \brief Mapping from the already-imported CXXBasesSpecifier in +/// the "from" source manager to the corresponding CXXBasesSpecifier +/// in the "to" source manager. +ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers; + /// \brief Imported, anonymous tag declarations that are missing their /// corresponding typedefs. SmallVector AnonTagsWithPendingTypedefs; @@ -212,8 +220,13 @@ namespace clang { /// \returns the equivalent initializer in the "to" context. CXXCtorInitializer *Import(CXXCtorInitializer *FromInit); +/// \brief Import the given CXXBaseSpecifier from the "from" context into +/// the "to" context. +/// +/// \returns the equivalent CXXBaseSpecifier in the source manager of the +/// "to" context. +CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec); - /// \brief Import the definition of the given declaration, including all of /// the declarations it contains. /// Modified: cfe/trunk/include/clang/AST/DeclFriend.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclFriend.h?rev=282572&r1=282571&r2=282572&view=diff == --- cfe/trunk/include/clang/AST/DeclFriend.h (original) +++ cfe/trunk/include/clang/AST/DeclFriend.h Wed Sep 28 05:16:56 2016 @@ -166,6 +166,7 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend class ASTNodeImporter; friend TrailingObjects; }; Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=282572&r1=282571&r2=282572&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Sep 28 05:16:56 2016 @@ -40,6 +40,7 @@ namespace clang { // Importing types QualType VisitType(const Type *T); QualType VisitBuiltinType(const BuiltinType *T); +QualType VisitDecayedType(const DecayedType *T); QualType VisitComplexType(const ComplexType *T); QualType VisitPointerType(const PointerType *T); QualType VisitBlockPointerType(const BlockPointerType *T); @@ -88,6 +89,8 @@ namespace clang { DeclarationNameInfo& To); void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); +bool ImportCastPath(CastExpr *E, CXXCastPath
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
This revision was automatically updated to reflect the committed changes. Closed by commit rL282572: [ASTImporter] Implement some expression-related AST node import (part 2) (authored by a.sidorin). Changed prior to commit: https://reviews.llvm.org/D14326?vs=72625&id=72791#toc Repository: rL LLVM https://reviews.llvm.org/D14326 Files: cfe/trunk/include/clang/AST/ASTImporter.h cfe/trunk/include/clang/AST/DeclFriend.h cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp cfe/trunk/test/ASTMerge/Inputs/class3.cpp cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp cfe/trunk/test/ASTMerge/class2.cpp cfe/trunk/test/ASTMerge/exprs.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Index: cfe/trunk/test/ASTMerge/class2.cpp === --- cfe/trunk/test/ASTMerge/class2.cpp +++ cfe/trunk/test/ASTMerge/class2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class C3 { + int method_1(C2 *x) { +return x->x; + } +}; Index: cfe/trunk/test/ASTMerge/exprs.cpp === --- cfe/trunk/test/ASTMerge/exprs.cpp +++ cfe/trunk/test/ASTMerge/exprs.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(Ch1 == 'a'); +static_assert(Ch2 == 'b'); +static_assert(Ch3 == 'c'); + +static_assert(Ch4 == L'd'); +static_assert(Ch5 == L'e'); +static_assert(Ch6 == L'f'); + +static_assert(C1 == 12); +static_assert(C2 == 13); + +static_assert(C3 == 12); +static_assert(C4 == 13); + +static_assert(C5 == 22L); +static_assert(C6 == 23L); + +static_assert(C7 == 66LL); +static_assert(C8 == 67ULL); + +static_assert(bval1 == true); +static_assert(bval2 == false); + +static_assert(ExpressionTrait == false); + +static_assert(ArrayRank == 2); +static_assert(ArrayExtent == 20); + +void testImport(int *x, const S1 &cs1, S1 &s1) { + testNewThrowDelete(); + testArrayElement(nullptr, 12); + testTernaryOp(0, 1, 2); + testConstCast(cs1); + testStaticCast(s1); + testReinterpretCast(s1); + testDynamicCast(s1); + testScalarInit(42); + testOffsetOf(); + testDefaultArg(12); + useTemplateType(); +} Index: cfe/trunk/test/ASTMerge/Inputs/class3.cpp === --- cfe/trunk/test/ASTMerge/Inputs/class3.cpp +++ cfe/trunk/test/ASTMerge/Inputs/class3.cpp @@ -0,0 +1,26 @@ +class C1 { +public: + C1(); + ~C1(); + C1 *method_1() { +return this; + } + C1 method_2() { +return C1(); + } + void method_3() { +const C1 &ref = C1(); + } +}; + +class C11 : public C1 { +}; + +class C2 { +private: + int x; + friend class C3; +public: + static_assert(sizeof(x) == sizeof(int), "Error"); + typedef class C2::C2 InjType; +}; Index: cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp === --- cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp +++ cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp @@ -0,0 +1,131 @@ +// Integer literals +const char Ch1 = 'a'; +const signed char Ch2 = 'b'; +const unsigned char Ch3 = 'c'; + +const wchar_t Ch4 = L'd'; +const signed wchar_t Ch5 = L'e'; +const unsigned wchar_t Ch6 = L'f'; + +const short C1 = 12; +const unsigned short C2 = 13; + +const int C3 = 12; +const unsigned int C4 = 13; + +const long C5 = 22; +const unsigned long C6 = 23; + +const long long C7 = 66; +const unsigned long long C8 = 67; + + +// String literals +const char str1[] = "ABCD"; +const char str2[] = "ABCD" "0123"; + +const wchar_t wstr1[] = L"DEF"; +const wchar_t wstr2[] = L"DEF" L"123"; + + +// Boolean literals +const bool bval1 = true; +const bool bval2 = false; + +// Floating Literals +const float F1 = 12.2F; +const double F2 = 1E4; +const long double F3 = 1.2E-3L; + + +// nullptr literal +const void *vptr = nullptr; + + +int glb_1[4] = { 10, 20, 30, 40 }; + +struct S1 { + int a; + int b[3]; +}; + +struct S2 { + int c; + S1 d; +}; + +S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 }; + +void testNewThrowDelete() { + throw; + char *p = new char[10]; + delete[] p; +} + +int testArrayElement(int *x, int n) { + return x[n]; +} + +int testTernaryOp(int c, int x, int y) { + return c ? x : y; +} + +S1 &testConstCast(const S1 &x) { + return const_cast(x); +} + +S1 &testStaticCast(S1 &x) { + return static_cast(x); +} + +S1 &testReinterpretCast(S1 &x) { + return reinterpret_cast(x); +} + +S1 &testDynamicCast(S1 &x) { + return dynamic_cast(x); +} + +int testScalarInit(int x) { + return int(x); +}
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin added a comment. Committed after Aaron's comment were addressed. Big thanks to all reviewers! Repository: rL LLVM https://reviews.llvm.org/D14326 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r282576 - ASTMerge: specify arch for GCCAsmStmt test explicitly to calm non-x86 buildbots
Author: a.sidorin Date: Wed Sep 28 05:57:36 2016 New Revision: 282576 URL: http://llvm.org/viewvc/llvm-project?rev=282576&view=rev Log: ASTMerge: specify arch for GCCAsmStmt test explicitly to calm non-x86 buildbots Modified: cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp Modified: cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp?rev=282576&r1=282575&r2=282576&view=diff == --- cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp (original) +++ cfe/trunk/test/ASTMerge/Inputs/exprs3.cpp Wed Sep 28 05:57:36 2016 @@ -104,17 +104,6 @@ void testOffsetOf() { } -unsigned char asmFunc(unsigned char a, unsigned char b) { - unsigned int la = a; - unsigned int lb = b; - unsigned int bigres; - unsigned char res; - __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) : -"edx", "cc"); - res = bigres; - return res; -} - int testDefaultArg(int a = 2*2) { return a; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r282578 - ASTMerge: explicitly specify arch for GCCAsmStmt test to calm non-x86 buildbots
Author: a.sidorin Date: Wed Sep 28 06:04:42 2016 New Revision: 282578 URL: http://llvm.org/viewvc/llvm-project?rev=282578&view=rev Log: ASTMerge: explicitly specify arch for GCCAsmStmt test to calm non-x86 buildbots This should fix r282572. Added: cfe/trunk/test/ASTMerge/Inputs/asm-function.cpp cfe/trunk/test/ASTMerge/asm.cpp Added: cfe/trunk/test/ASTMerge/Inputs/asm-function.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/asm-function.cpp?rev=282578&view=auto == --- cfe/trunk/test/ASTMerge/Inputs/asm-function.cpp (added) +++ cfe/trunk/test/ASTMerge/Inputs/asm-function.cpp Wed Sep 28 06:04:42 2016 @@ -0,0 +1,11 @@ + +unsigned char asmFunc(unsigned char a, unsigned char b) { + unsigned int la = a; + unsigned int lb = b; + unsigned int bigres; + unsigned char res; + __asm__ ("0:\n1:\n" : [bigres] "=la"(bigres) : [la] "0"(la), [lb] "c"(lb) : +"edx", "cc"); + res = bigres; + return res; +} Added: cfe/trunk/test/ASTMerge/asm.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/asm.cpp?rev=282578&view=auto == --- cfe/trunk/test/ASTMerge/asm.cpp (added) +++ cfe/trunk/test/ASTMerge/asm.cpp Wed Sep 28 06:04:42 2016 @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/asm-function.cpp +// RUN: %clang_cc1 -triple i386-unknown-unknown -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +void testAsmImport() { + asmFunc(12, 42); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D24807: [Serialization] ArrayTypeTraitExpr: serialize sub-expression to avoid keeping it undefined
a.sidorin abandoned this revision. a.sidorin added a comment. Merged into https://reviews.llvm.org/D14326 and committed. https://reviews.llvm.org/D24807 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25326: [StaticAnalyser] Don't merge different returns in ExplodedGraph
a.sidorin added inline comments. Comment at: test/Analysis/unreachable-code-path.c:201 +static int inlineFunction(const int i) { + if (table[i] != 0) +return 1; I have a small question. Is it possible to simplify this sample with removing of table[] array? Like putting something like `i != 0` into condition. As I understand, the problem is not array-related. https://reviews.llvm.org/D25326 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D25503: [analyzer] Remove superquadratic behaviour from DataflowWorklist
a.sidorin accepted this revision. a.sidorin added a comment. This patch reduces both the analysis time and the line count. I like it! :) Did you test Artem's approach? Repository: rL LLVM https://reviews.llvm.org/D25503 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r318998 - [ASTImporter] Support TypeTraitExpr
Author: a.sidorin Date: Sun Nov 26 09:04:06 2017 New Revision: 318998 URL: http://llvm.org/viewvc/llvm-project?rev=318998&view=rev Log: [ASTImporter] Support TypeTraitExpr Patch by Takafumi Kubota! Differential Revision: https://reviews.llvm.org/D39722 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=318998&r1=318997&r2=318998&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Sun Nov 26 09:04:06 2017 @@ -291,6 +291,7 @@ namespace clang { Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E); Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E); Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E); +Expr *VisitTypeTraitExpr(TypeTraitExpr *E); template @@ -5890,6 +5891,26 @@ Expr *ASTNodeImporter::VisitSubstNonType Replacement); } +Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) { + QualType ToType = Importer.Import(E->getType()); + if (ToType.isNull()) +return nullptr; + + SmallVector ToArgs(E->getNumArgs()); + if (ImportContainerChecked(E->getArgs(), ToArgs)) +return nullptr; + + // According to Sema::BuildTypeTrait(), if E is value-dependent, + // Value is always false. + bool ToValue = false; + if (!E->isValueDependent()) +ToValue = E->getValue(); + + return TypeTraitExpr::Create( + Importer.getToContext(), ToType, Importer.Import(E->getLocStart()), + E->getTrait(), ToArgs, Importer.Import(E->getLocEnd()), ToValue); +} + void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod) { for (auto *FromOverriddenMethod : FromMethod->overridden_methods()) Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=318998&r1=318997&r2=318998&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Sun Nov 26 09:04:06 2017 @@ -525,6 +525,47 @@ TEST(ImportType, ImportPackExpansion) { declRefExpr())); } +/// \brief Matches __builtin_types_compatible_p: +/// GNU extension to check equivalent types +/// Given +/// \code +/// __builtin_types_compatible_p(int, int) +/// \endcode +// will generate TypeTraitExpr <...> 'int' +const internal::VariadicDynCastAllOfMatcher typeTraitExpr; + +TEST(ImportExpr, ImportTypeTraitExpr) { + MatchVerifier Verifier; + EXPECT_TRUE(testImport("void declToImport() { " + " __builtin_types_compatible_p(int, int);" + "}", + Lang_C, "", Lang_C, Verifier, + functionDecl( + hasBody( + compoundStmt( + has( + typeTraitExpr(hasType(asString("int"); +} + +TEST(ImportExpr, ImportTypeTraitExprValDep) { + MatchVerifier Verifier; + EXPECT_TRUE(testImport("template struct declToImport {" + " void m() { __is_pod(T); }" + "};" + "void f() { declToImport().m(); }", + Lang_CXX11, "", Lang_CXX11, Verifier, + classTemplateDecl( + has( + cxxRecordDecl( + has( + functionDecl( + hasBody( + compoundStmt( + has( + typeTraitExpr( + hasType(booleanType()) + ))); +} } // end namespace ast_matchers } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r319015 - [ASTImporter] Support importing CXXPseudoDestructorExpr
Author: a.sidorin Date: Mon Nov 27 02:30:00 2017 New Revision: 319015 URL: http://llvm.org/viewvc/llvm-project?rev=319015&view=rev Log: [ASTImporter] Support importing CXXPseudoDestructorExpr Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D38843 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=319015&r1=319014&r2=319015&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Nov 27 02:30:00 2017 @@ -283,6 +283,7 @@ namespace clang { Expr *VisitExprWithCleanups(ExprWithCleanups *EWC); Expr *VisitCXXThisExpr(CXXThisExpr *E); Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); +Expr *VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); Expr *VisitInitListExpr(InitListExpr *E); @@ -5725,6 +5726,39 @@ Expr *ASTNodeImporter::VisitMemberExpr(M E->getObjectKind()); } +Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr( +CXXPseudoDestructorExpr *E) { + + Expr *BaseE = Importer.Import(E->getBase()); + if (!BaseE) +return nullptr; + + TypeSourceInfo *ScopeInfo = Importer.Import(E->getScopeTypeInfo()); + if (!ScopeInfo && E->getScopeTypeInfo()) +return nullptr; + + PseudoDestructorTypeStorage Storage; + if (IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) { +IdentifierInfo *ToII = Importer.Import(FromII); +if (!ToII) + return nullptr; +Storage = PseudoDestructorTypeStorage( + ToII, Importer.Import(E->getDestroyedTypeLoc())); + } else { +TypeSourceInfo *TI = Importer.Import(E->getDestroyedTypeInfo()); +if (!TI) + return nullptr; +Storage = PseudoDestructorTypeStorage(TI); + } + + return new (Importer.getToContext()) CXXPseudoDestructorExpr( +Importer.getToContext(), BaseE, E->isArrow(), +Importer.Import(E->getOperatorLoc()), +Importer.Import(E->getQualifierLoc()), +ScopeInfo, Importer.Import(E->getColonColonLoc()), +Importer.Import(E->getTildeLoc()), Storage); +} + Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=319015&r1=319014&r2=319015&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Mon Nov 27 02:30:00 2017 @@ -567,5 +567,21 @@ TEST(ImportExpr, ImportTypeTraitExprValD ))); } +const internal::VariadicDynCastAllOfMatcher +cxxPseudoDestructorExpr; + +TEST(ImportExpr, ImportCXXPseudoDestructorExpr) { + MatchVerifier Verifier; + EXPECT_TRUE( + testImport("typedef int T;" + "void declToImport(int *p) {" + " T t;" + " p->T::~T();" + "}", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl(has(compoundStmt(has( + callExpr(has(cxxPseudoDestructorExpr(); +} + } // end namespace ast_matchers } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r319632 - [ASTImporter] Add unit tests for UsingDecl and UsingShadowDecl
Author: a.sidorin Date: Sun Dec 3 08:04:07 2017 New Revision: 319632 URL: http://llvm.org/viewvc/llvm-project?rev=319632&view=rev Log: [ASTImporter] Add unit tests for UsingDecl and UsingShadowDecl Patch by Kareem Khazem! Differential Revision: https://reviews.llvm.org/D27181 Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=319632&r1=319631&r2=319632&view=diff == --- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original) +++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Sun Dec 3 08:04:07 2017 @@ -583,5 +583,46 @@ TEST(ImportExpr, ImportCXXPseudoDestruct callExpr(has(cxxPseudoDestructorExpr(); } +TEST(ImportDecl, ImportUsingDecl) { + MatchVerifier Verifier; + EXPECT_TRUE( +testImport( + "namespace foo { int bar; }" + "int declToImport(){ using foo::bar; }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl( +has( + compoundStmt( +has( + declStmt( +has( + usingDecl(); +} + +/// \brief Matches shadow declarations introduced into a scope by a +///(resolved) using declaration. +/// +/// Given +/// \code +/// namespace n { int f; } +/// namespace declToImport { using n::f; } +/// \endcode +/// usingShadowDecl() +/// matches \code f \endcode +const internal::VariadicDynCastAllOfMatcher usingShadowDecl; + +TEST(ImportDecl, ImportUsingShadowDecl) { + MatchVerifier Verifier; + EXPECT_TRUE( +testImport( + "namespace foo { int bar; }" + "namespace declToImport { using foo::bar; }", + Lang_CXX, "", Lang_CXX, Verifier, + namespaceDecl( +has( + usingShadowDecl(); +} + } // end namespace ast_matchers } // end namespace clang ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r329301 - [ASTImporter] Fix for importing unnamed structs
Author: a.sidorin Date: Thu Apr 5 08:31:49 2018 New Revision: 329301 URL: http://llvm.org/viewvc/llvm-project?rev=329301&view=rev Log: [ASTImporter] Fix for importing unnamed structs Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D30876 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp cfe/trunk/test/ASTMerge/struct/Inputs/struct1.c cfe/trunk/test/ASTMerge/struct/Inputs/struct2.c cfe/trunk/test/ASTMerge/struct/test.c Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=329301&r1=329300&r2=329301&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Apr 5 08:31:49 2018 @@ -1923,9 +1923,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(R } if (RecordDecl *FoundRecord = dyn_cast(Found)) { -if (D->isAnonymousStructOrUnion() && -FoundRecord->isAnonymousStructOrUnion()) { - // If both anonymous structs/unions are in a record context, make sure +if (!SearchName) { + // If both unnamed structs/unions are in a record context, make sure // they occur in the same location in the context records. if (Optional Index1 = StructuralEquivalenceContext::findUntaggedStructOrUnionIndex( Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=329301&r1=329300&r2=329301&view=diff == --- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original) +++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Thu Apr 5 08:31:49 2018 @@ -1256,6 +1256,10 @@ StructuralEquivalenceContext::findUntagg // If the field looks like this: // struct { ... } A; QualType FieldType = F->getType(); +// In case of nested structs. +while (const auto *ElabType = dyn_cast(FieldType)) + FieldType = ElabType->getNamedType(); + if (const auto *RecType = dyn_cast(FieldType)) { const RecordDecl *RecDecl = RecType->getDecl(); if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) { Modified: cfe/trunk/test/ASTMerge/struct/Inputs/struct1.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/struct/Inputs/struct1.c?rev=329301&r1=329300&r2=329301&view=diff == --- cfe/trunk/test/ASTMerge/struct/Inputs/struct1.c (original) +++ cfe/trunk/test/ASTMerge/struct/Inputs/struct1.c Thu Apr 5 08:31:49 2018 @@ -77,3 +77,65 @@ typedef struct { } S13; S13 x13; + +// Matches +struct Unnamed { + union { +struct { + int i; +} S; +struct { + float i; +} R; + } U; +} x14; + +// Matches +struct DeepUnnamed { + union { +union { + struct { +long i; + } S; + struct { +int i; + } R; +} U1; +union { + struct { +long i; + } S; + struct { +float i; + } T; +} U2; + } U; + struct { +long i; + } V; +} x15; + +// Mismatch due to unnamed struct used internally +struct DeepUnnamedError { + union { +union { + struct { +long i; + } S; + struct { +int i; + } R; +} U1; +union { + struct { +long i; // Mismatch here. + } S; + struct { +float i; + } T; +} U2; + } U; + struct { +long i; + } V; +} x16; Modified: cfe/trunk/test/ASTMerge/struct/Inputs/struct2.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/struct/Inputs/struct2.c?rev=329301&r1=329300&r2=329301&view=diff == --- cfe/trunk/test/ASTMerge/struct/Inputs/struct2.c (original) +++ cfe/trunk/test/ASTMerge/struct/Inputs/struct2.c Thu Apr 5 08:31:49 2018 @@ -74,3 +74,65 @@ typedef struct { } S13; S13 x13; + +// Matches +struct Unnamed { + union { +struct { + int i; +} S; +struct { + float i; +} R; + } U; +} x14; + +// Matches +struct DeepUnnamed { + union { +union { + struct { +long i; + } S; + struct { +int i; + } R; +} U1; +union { + struct { +long i; + } S; + struct { +float i; + } T; +} U2; + } U; + struct { +long i; + } V; +} x15; + +// Mismatch due to unnamed struct used internally +struct DeepUnnamedError { + union { +union { + struct { +long i; + } S; + struct { +int i; + } R; +} U1; +union { + struct { +float i; // Mismatch here. + } S; + struct { +float i; + } T; +} U2; + } U; + struct { +long i; + } V; +} x1
r318750 - [Analyzer] Non-determinism: stable iteration on indirect goto LabelDecl's
Author: a.sidorin Date: Tue Nov 21 03:05:28 2017 New Revision: 318750 URL: http://llvm.org/viewvc/llvm-project?rev=318750&view=rev Log: [Analyzer] Non-determinism: stable iteration on indirect goto LabelDecl's CFG wass built in non-deterministic order due to the fact that indirect goto labels' declarations (LabelDecl's) are stored in the llvm::SmallSet container. LabelDecl's are pointers, whose order is not deterministic, and llvm::SmallSet sorts them by their non-deterministic addresses after "small" container is exceeded. This leads to non-deterministic processing of the elements of the container. The fix is to use llvm::SmallSetVector that was designed to have deterministic iteration order. Patch by Ilya Palachev! Differential Revision: https://reviews.llvm.org/D40073 Added: cfe/trunk/test/Analysis/cfg-indirect-goto-determinism.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=318750&r1=318749&r2=318750&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Nov 21 03:05:28 2017 @@ -58,7 +58,7 @@ namespace clang { QualType VisitExtVectorType(const ExtVectorType *T); QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T); QualType VisitFunctionProtoType(const FunctionProtoType *T); -// FIXME: UnresolvedUsingType +QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T); QualType VisitParenType(const ParenType *T); QualType VisitTypedefType(const TypedefType *T); QualType VisitTypeOfExprType(const TypeOfExprType *T); @@ -129,8 +129,8 @@ namespace clang { TemplateParameterList *ImportTemplateParameterList( TemplateParameterList *Params); TemplateArgument ImportTemplateArgument(const TemplateArgument &From); -TemplateArgumentLoc ImportTemplateArgumentLoc( -const TemplateArgumentLoc &TALoc, bool &Error); +Optional ImportTemplateArgumentLoc( +const TemplateArgumentLoc &TALoc); bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); @@ -143,10 +143,12 @@ namespace clang { bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); +Decl *VisitEmptyDecl(EmptyDecl *D); Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); Decl *VisitNamespaceDecl(NamespaceDecl *D); +Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitTypeAliasDecl(TypeAliasDecl *D); @@ -172,6 +174,12 @@ namespace clang { Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D); Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D); Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D); +Decl *VisitUsingDecl(UsingDecl *D); +Decl *VisitUsingShadowDecl(UsingShadowDecl *D); +Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); +Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); +Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); + ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list); Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); @@ -569,6 +577,22 @@ QualType ASTNodeImporter::VisitFunctionP return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI); } +QualType ASTNodeImporter::VisitUnresolvedUsingType( +const UnresolvedUsingType *T) { + UnresolvedUsingTypenameDecl *ToD = cast_or_null( +Importer.Import(T->getDecl())); + if (!ToD) +return QualType(); + + UnresolvedUsingTypenameDecl *ToPrevD = + cast_or_null( +Importer.Import(T->getDecl()->getPreviousDecl())); + if (!ToPrevD && T->getDecl()->getPreviousDecl()) +return QualType(); + + return Importer.getToContext().getTypeDeclType(ToD, ToPrevD); +} + QualType ASTNodeImporter::VisitParenType(const ParenType *T) { QualType ToInnerType = Importer.Import(T->getInnerType()); if (ToInnerType.isNull()) @@ -1183,9 +1207,8 @@ ASTNodeImporter::ImportTemplateArgument( llvm_unreachable("Invalid template argument kind"); } -TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc( -const TemplateArgumentLoc &TALoc, bool &Error) { - Error = false; +Optional +ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) { TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument()); TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo
r318753 - [Analyzer] Revert r318750 because incorrect files were added for commit.
Author: a.sidorin Date: Tue Nov 21 03:20:07 2017 New Revision: 318753 URL: http://llvm.org/viewvc/llvm-project?rev=318753&view=rev Log: [Analyzer] Revert r318750 because incorrect files were added for commit. Sorry for the noise. Removed: cfe/trunk/test/Analysis/cfg-indirect-goto-determinism.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=318753&r1=318752&r2=318753&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Nov 21 03:20:07 2017 @@ -58,7 +58,7 @@ namespace clang { QualType VisitExtVectorType(const ExtVectorType *T); QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T); QualType VisitFunctionProtoType(const FunctionProtoType *T); -QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T); +// FIXME: UnresolvedUsingType QualType VisitParenType(const ParenType *T); QualType VisitTypedefType(const TypedefType *T); QualType VisitTypeOfExprType(const TypeOfExprType *T); @@ -129,8 +129,8 @@ namespace clang { TemplateParameterList *ImportTemplateParameterList( TemplateParameterList *Params); TemplateArgument ImportTemplateArgument(const TemplateArgument &From); -Optional ImportTemplateArgumentLoc( -const TemplateArgumentLoc &TALoc); +TemplateArgumentLoc ImportTemplateArgumentLoc( +const TemplateArgumentLoc &TALoc, bool &Error); bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); @@ -143,12 +143,10 @@ namespace clang { bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); -Decl *VisitEmptyDecl(EmptyDecl *D); Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); Decl *VisitNamespaceDecl(NamespaceDecl *D); -Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitTypeAliasDecl(TypeAliasDecl *D); @@ -174,12 +172,6 @@ namespace clang { Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D); Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D); Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D); -Decl *VisitUsingDecl(UsingDecl *D); -Decl *VisitUsingShadowDecl(UsingShadowDecl *D); -Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); -Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); -Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); - ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list); Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); @@ -577,22 +569,6 @@ QualType ASTNodeImporter::VisitFunctionP return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI); } -QualType ASTNodeImporter::VisitUnresolvedUsingType( -const UnresolvedUsingType *T) { - UnresolvedUsingTypenameDecl *ToD = cast_or_null( -Importer.Import(T->getDecl())); - if (!ToD) -return QualType(); - - UnresolvedUsingTypenameDecl *ToPrevD = - cast_or_null( -Importer.Import(T->getDecl()->getPreviousDecl())); - if (!ToPrevD && T->getDecl()->getPreviousDecl()) -return QualType(); - - return Importer.getToContext().getTypeDeclType(ToD, ToPrevD); -} - QualType ASTNodeImporter::VisitParenType(const ParenType *T) { QualType ToInnerType = Importer.Import(T->getInnerType()); if (ToInnerType.isNull()) @@ -1207,8 +1183,9 @@ ASTNodeImporter::ImportTemplateArgument( llvm_unreachable("Invalid template argument kind"); } -Optional -ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) { +TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc( +const TemplateArgumentLoc &TALoc, bool &Error) { + Error = false; TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument()); TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo(); TemplateArgumentLocInfo ToInfo; @@ -1216,12 +1193,12 @@ ASTNodeImporter::ImportTemplateArgumentL Expr *E = Importer.Import(FromInfo.getAsExpr()); ToInfo = TemplateArgumentLocInfo(E); if (!E) - return None; + Error = true; } else if (Arg.getKind() == TemplateArgument::Type) { if (TypeSourceInfo *TSI = Importer.Import(FromInfo.getAsTypeSourceInfo())) ToInfo = TemplateArgumentLocInfo(TSI); else - return None; + Error = true; } else { ToInfo = TemplateArgumentLocInfo( Impor
r318754 - [Analyzer] Stable iteration on indirect goto LabelDecl's to avoid non-determinism (attempt 2)
Author: a.sidorin Date: Tue Nov 21 03:27:47 2017 New Revision: 318754 URL: http://llvm.org/viewvc/llvm-project?rev=318754&view=rev Log: [Analyzer] Stable iteration on indirect goto LabelDecl's to avoid non-determinism (attempt 2) CFG wass built in non-deterministic order due to the fact that indirect goto labels' declarations (LabelDecl's) are stored in the llvm::SmallSet container. LabelDecl's are pointers, whose order is not deterministic, and llvm::SmallSet sorts them by their non-deterministic addresses after "small" container is exceeded. This leads to non-deterministic processing of the elements of the container. The fix is to use llvm::SmallSetVector that was designed to have deterministic iteration order. Patch by Ilya Palachev! Differential Revision: https://reviews.llvm.org/D40073 Added: cfe/trunk/test/Analysis/cfg-indirect-goto-determinism.cpp Modified: cfe/trunk/lib/Analysis/CFG.cpp Modified: cfe/trunk/lib/Analysis/CFG.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=318754&r1=318753&r2=318754&view=diff == --- cfe/trunk/lib/Analysis/CFG.cpp (original) +++ cfe/trunk/lib/Analysis/CFG.cpp Tue Nov 21 03:27:47 2017 @@ -420,7 +420,7 @@ class CFGBuilder { BackpatchBlocksTy BackpatchBlocks; // A list of labels whose address has been taken (for indirect gotos). - typedef llvm::SmallPtrSet LabelSetTy; + typedef llvm::SmallSetVector LabelSetTy; LabelSetTy AddressTakenLabels; bool badCFG; Added: cfe/trunk/test/Analysis/cfg-indirect-goto-determinism.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cfg-indirect-goto-determinism.cpp?rev=318754&view=auto == --- cfe/trunk/test/Analysis/cfg-indirect-goto-determinism.cpp (added) +++ cfe/trunk/test/Analysis/cfg-indirect-goto-determinism.cpp Tue Nov 21 03:27:47 2017 @@ -0,0 +1,96 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s + +void *target; +int indirectBlockSuccessorDeterminism() { +(void)&&L1; +(void)&&L2; +(void)&&L3; +(void)&&L4; +(void)&&L5; +(void)&&L6; +(void)&&L7; +(void)&&L8; +(void)&&L9; +(void)&&L10; +(void)&&L11; +(void)&&L12; +(void)&&L13; +(void)&&L14; +(void)&&L15; +(void)&&L16; +(void)&&L17; +(void)&&L18; +(void)&&L19; +(void)&&L20; +(void)&&L21; +(void)&&L22; +(void)&&L23; +(void)&&L24; +(void)&&L25; +(void)&&L26; +(void)&&L27; +(void)&&L28; +(void)&&L29; +(void)&&L30; +(void)&&L31; +(void)&&L32; +(void)&&L33; +(void)&&L34; +(void)&&L35; +(void)&&L36; +(void)&&L37; +(void)&&L38; +(void)&&L39; +(void)&&L40; + +goto *target; + L1: + L2: + L3: + L4: + L5: + L6: + L7: + L8: + L9: + L10: + L11: + L12: + L13: + L14: + L15: + L16: + L17: + L18: + L19: + L20: + L21: + L22: + L23: + L24: + L25: + L26: + L27: + L28: + L29: + L30: + L31: + L32: + L33: + L34: + L35: + L36: + L37: + L38: + L39: + L40: +return 0; +} + +// CHECK-LABEL: [B41 (INDIRECT GOTO DISPATCH)] +// CHECK-NEXT: Preds (1): B42 +// CHECK-NEXT: Succs (40): B1 B2 B3 B4 B5 B6 B7 B8 +// CHECK-NEXT: B9 B10 B11 B12 B13 B14 B15 B16 B17 B18 +// CHECK-NEXT: B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 +// CHECK-NEXT: B29 B30 B31 B32 B33 B34 B35 B36 B37 B38 +// CHECK-NEXT: B39 B40 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r318776 - [ASTImporter] Support new AST nodes:
Author: a.sidorin Date: Tue Nov 21 08:08:41 2017 New Revision: 318776 URL: http://llvm.org/viewvc/llvm-project?rev=318776&view=rev Log: [ASTImporter] Support new AST nodes: * UnresolvedUsingType * EmptyDecl * NamespaceAliasDecl * UsingDecl * UsingShadowDecl * UsingDirectiveDecl * UnresolvedUsingValueDecl * UnresolvedUsingTypenameDecl Refactor error handling in ImportTemplateArgumentLoc() method. Add a test for inline namespaces. Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/test/ASTMerge/namespace/Inputs/namespace1.cpp cfe/trunk/test/ASTMerge/namespace/Inputs/namespace2.cpp cfe/trunk/test/ASTMerge/namespace/test.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=318776&r1=318775&r2=318776&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Nov 21 08:08:41 2017 @@ -58,7 +58,7 @@ namespace clang { QualType VisitExtVectorType(const ExtVectorType *T); QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T); QualType VisitFunctionProtoType(const FunctionProtoType *T); -// FIXME: UnresolvedUsingType +QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T); QualType VisitParenType(const ParenType *T); QualType VisitTypedefType(const TypedefType *T); QualType VisitTypeOfExprType(const TypeOfExprType *T); @@ -129,8 +129,8 @@ namespace clang { TemplateParameterList *ImportTemplateParameterList( TemplateParameterList *Params); TemplateArgument ImportTemplateArgument(const TemplateArgument &From); -TemplateArgumentLoc ImportTemplateArgumentLoc( -const TemplateArgumentLoc &TALoc, bool &Error); +Optional ImportTemplateArgumentLoc( +const TemplateArgumentLoc &TALoc); bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, SmallVectorImpl &ToArgs); @@ -143,10 +143,12 @@ namespace clang { bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To); bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To); Decl *VisitDecl(Decl *D); +Decl *VisitEmptyDecl(EmptyDecl *D); Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D); Decl *VisitNamespaceDecl(NamespaceDecl *D); +Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitTypeAliasDecl(TypeAliasDecl *D); @@ -172,6 +174,12 @@ namespace clang { Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D); Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D); Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D); +Decl *VisitUsingDecl(UsingDecl *D); +Decl *VisitUsingShadowDecl(UsingShadowDecl *D); +Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D); +Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); +Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); + ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list); Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); @@ -569,6 +577,22 @@ QualType ASTNodeImporter::VisitFunctionP return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI); } +QualType ASTNodeImporter::VisitUnresolvedUsingType( +const UnresolvedUsingType *T) { + UnresolvedUsingTypenameDecl *ToD = cast_or_null( +Importer.Import(T->getDecl())); + if (!ToD) +return QualType(); + + UnresolvedUsingTypenameDecl *ToPrevD = + cast_or_null( +Importer.Import(T->getDecl()->getPreviousDecl())); + if (!ToPrevD && T->getDecl()->getPreviousDecl()) +return QualType(); + + return Importer.getToContext().getTypeDeclType(ToD, ToPrevD); +} + QualType ASTNodeImporter::VisitParenType(const ParenType *T) { QualType ToInnerType = Importer.Import(T->getInnerType()); if (ToInnerType.isNull()) @@ -1183,9 +1207,8 @@ ASTNodeImporter::ImportTemplateArgument( llvm_unreachable("Invalid template argument kind"); } -TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc( -const TemplateArgumentLoc &TALoc, bool &Error) { - Error = false; +Optional +ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) { TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument()); TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo(); TemplateArgumentLocInfo ToInfo; @@ -1193,12 +1216,12 @@ TemplateArgumentLoc ASTNodeImporter::Imp Expr *E = Importer.Import(FromInfo.getAsExpr()); ToInfo = TemplateArgumentLocInfo(E); if (!E) - Error = true; + return
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin added a comment. Serge, Sean, is this patch OK to commit? https://reviews.llvm.org/D14326 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22090: [analyzer] Add more FileIDs to PlistDiagnostic map
a.sidorin updated this revision to Diff 68987. a.sidorin added a comment. Add plist output; give test files meaningful names. https://reviews.llvm.org/D22090 Files: lib/StaticAnalyzer/Core/PlistDiagnostics.cpp test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h test/Analysis/diagnostics/plist-diagnostics-include-check.cpp Index: test/Analysis/diagnostics/plist-diagnostics-include-check.cpp === --- /dev/null +++ test/Analysis/diagnostics/plist-diagnostics-include-check.cpp @@ -0,0 +1,140 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist +// RUN: FileCheck --input-file=%t.plist %s + +#include "Inputs/include/plist-diagnostics-include-check-macro.h" + +void foo() { + PlistCheckMacro() +#define PLIST_DEF_MACRO .run(); +#include "Inputs/include/plist-diagnostics-include-check-macro.def" +} + +// CHECK: diagnostics +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:path +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line1 +// CHECK-NEXT: col15 +// CHECK-NEXT: file2 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Calling 'PlistCheckMacro::run' +// CHECK-NEXT: message +// CHECK-NEXT: Calling 'PlistCheckMacro::run' +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line6 +// CHECK-NEXT: col3 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: depth1 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Entered call from 'foo' +// CHECK-NEXT: message +// CHECK-NEXT: Entered call from 'foo' +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindcontrol +// CHECK-NEXT: edges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: start +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:line6 +// CHECK-NEXT:col3 +// CHECK-NEXT:file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:line6 +// CHECK-NEXT:col6 +// CHECK-NEXT:file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: end +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:line7 +// CHECK-NEXT:col5 +// CHECK-NEXT:file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:line7 +// CHECK-NEXT:col32 +// CHECK-NEXT:file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col5 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col5 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col34 +// CHECK-NEXT: file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth1 +// CHECK-NEXT: extended_message +// CHECK-NEXT: REACHABLE +// CHECK-NEXT: message +// CHECK-NEXT: REACHABLE +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:descriptionREACHABLE +// CHECK-NEXT:categorydebug +// CHECK-NEXT:typeChecking analyzer assumptions +// CHECK-NEXT:check_namedebug.ExprInspection +// CHECK-NEXT: +// CHECK-NEXT:issue_hash_content_of_line_in_context93b4eab05b21c892c8e31723e5af3f59 +// CHECK-NEXT: issue_context_kindC++ method +// CHECK-NEXT: issue_contextrun +// CHECK-NEXT: issue_hash_function_offset1 +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT:line7 +// CHECK-NEXT:col5 +// CHECK-NEXT:file1 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: Index: test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h === --- /dev/null +++ test/Analysis/diagnostics/Inputs/include/p
r280352 - [analyzer][test commit] ExprEngine.cpp: Remove training whitespace; NFC
Author: a.sidorin Date: Thu Sep 1 06:11:46 2016 New Revision: 280352 URL: http://llvm.org/viewvc/llvm-project?rev=280352&view=rev Log: [analyzer][test commit] ExprEngine.cpp: Remove training whitespace; NFC Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=280352&r1=280351&r2=280352&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Thu Sep 1 06:11:46 2016 @@ -578,9 +578,9 @@ void ExprEngine::VisitLambdaExpr(const L const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion( LE, LocCtxt); SVal V = loc::MemRegionVal(R); - + ProgramStateRef State = Pred->getState(); - + // If we created a new MemRegion for the lambda, we should explicitly bind // the captures. CXXRecordDecl::field_iterator CurField = LE->getLambdaClass()->field_begin(); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r280360 - [analyzer] Add more FileIDs to PlistDiagnostic map to avoid assertion
Author: a.sidorin Date: Thu Sep 1 07:25:16 2016 New Revision: 280360 URL: http://llvm.org/viewvc/llvm-project?rev=280360&view=rev Log: [analyzer] Add more FileIDs to PlistDiagnostic map to avoid assertion Some FileIDs that may be used by PlistDiagnostics were not added while building a list of pieces. This caused assertion violation in GetFID() function. This patch adds some missing FileIDs to avoid the assertion. It also contains small refactoring of PlistDiagnostics::FlushDiagnosticsImpl(). Patch by Aleksei Sidorin, Ilya Palachev. Differential Revision: https://reviews.llvm.org/D22090 Added: cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=280360&r1=280359&r2=280360&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Thu Sep 1 07:25:16 2016 @@ -297,40 +297,42 @@ void PlistDiagnostics::FlushDiagnosticsI SM = &Diags.front()->path.front()->getLocation().getManager(); - for (std::vector::iterator DI = Diags.begin(), - DE = Diags.end(); DI != DE; ++DI) { + auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece *Piece)->void { +AddFID(FM, Fids, *SM, Piece->getLocation().asLocation()); +ArrayRef Ranges = Piece->getRanges(); +for (const SourceRange &Range : Ranges) { + AddFID(FM, Fids, *SM, Range.getBegin()); + AddFID(FM, Fids, *SM, Range.getEnd()); +} + }; -const PathDiagnostic *D = *DI; + for (const PathDiagnostic *D : Diags) { SmallVector WorkList; WorkList.push_back(&D->path); while (!WorkList.empty()) { - const PathPieces &path = *WorkList.pop_back_val(); - - for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E; - ++I) { -const PathDiagnosticPiece *piece = I->get(); -AddFID(FM, Fids, *SM, piece->getLocation().asLocation()); -ArrayRef Ranges = piece->getRanges(); -for (ArrayRef::iterator I = Ranges.begin(), - E = Ranges.end(); I != E; ++I) { - AddFID(FM, Fids, *SM, I->getBegin()); - AddFID(FM, Fids, *SM, I->getEnd()); -} + const PathPieces &Path = *WorkList.pop_back_val(); -if (const PathDiagnosticCallPiece *call = -dyn_cast(piece)) { - IntrusiveRefCntPtr -callEnterWithin = call->getCallEnterWithinCallerEvent(); - if (callEnterWithin) -AddFID(FM, Fids, *SM, callEnterWithin->getLocation().asLocation()); + for (const auto &Iter : Path) { +const PathDiagnosticPiece *Piece = Iter.get(); +AddPieceFID(Piece); + +if (const PathDiagnosticCallPiece *Call = +dyn_cast(Piece)) { + if (IntrusiveRefCntPtr + CallEnterWithin = Call->getCallEnterWithinCallerEvent()) +AddPieceFID(CallEnterWithin.get()); + + if (IntrusiveRefCntPtr + CallEnterEvent = Call->getCallEnterEvent()) +AddPieceFID(CallEnterEvent.get()); - WorkList.push_back(&call->path); + WorkList.push_back(&Call->path); } -else if (const PathDiagnosticMacroPiece *macro = - dyn_cast(piece)) { - WorkList.push_back(¯o->subPieces); +else if (const PathDiagnosticMacroPiece *Macro = + dyn_cast(Piece)) { + WorkList.push_back(&Macro->subPieces); } } } Added: cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def?rev=280360&view=auto == --- cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def (added) +++ cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def Thu Sep 1 07:25:16 2016 @@ -0,0 +1 @@ +PLIST_DEF_MACRO Added: cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h?rev=280360&view=auto == --- cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-m
Re: [PATCH] D22090: [analyzer] Add more FileIDs to PlistDiagnostic map
This revision was automatically updated to reflect the committed changes. Closed by commit rL280360: [analyzer] Add more FileIDs to PlistDiagnostic map to avoid assertion (authored by a.sidorin). Changed prior to commit: https://reviews.llvm.org/D22090?vs=68987&id=69993#toc Repository: rL LLVM https://reviews.llvm.org/D22090 Files: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.def cfe/trunk/test/Analysis/diagnostics/Inputs/include/plist-diagnostics-include-check-macro.h cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp Index: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -297,40 +297,42 @@ SM = &Diags.front()->path.front()->getLocation().getManager(); - for (std::vector::iterator DI = Diags.begin(), - DE = Diags.end(); DI != DE; ++DI) { + auto AddPieceFID = [&FM, &Fids, SM](const PathDiagnosticPiece *Piece)->void { +AddFID(FM, Fids, *SM, Piece->getLocation().asLocation()); +ArrayRef Ranges = Piece->getRanges(); +for (const SourceRange &Range : Ranges) { + AddFID(FM, Fids, *SM, Range.getBegin()); + AddFID(FM, Fids, *SM, Range.getEnd()); +} + }; -const PathDiagnostic *D = *DI; + for (const PathDiagnostic *D : Diags) { SmallVector WorkList; WorkList.push_back(&D->path); while (!WorkList.empty()) { - const PathPieces &path = *WorkList.pop_back_val(); - - for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E; - ++I) { -const PathDiagnosticPiece *piece = I->get(); -AddFID(FM, Fids, *SM, piece->getLocation().asLocation()); -ArrayRef Ranges = piece->getRanges(); -for (ArrayRef::iterator I = Ranges.begin(), - E = Ranges.end(); I != E; ++I) { - AddFID(FM, Fids, *SM, I->getBegin()); - AddFID(FM, Fids, *SM, I->getEnd()); -} + const PathPieces &Path = *WorkList.pop_back_val(); -if (const PathDiagnosticCallPiece *call = -dyn_cast(piece)) { - IntrusiveRefCntPtr -callEnterWithin = call->getCallEnterWithinCallerEvent(); - if (callEnterWithin) -AddFID(FM, Fids, *SM, callEnterWithin->getLocation().asLocation()); + for (const auto &Iter : Path) { +const PathDiagnosticPiece *Piece = Iter.get(); +AddPieceFID(Piece); + +if (const PathDiagnosticCallPiece *Call = +dyn_cast(Piece)) { + if (IntrusiveRefCntPtr + CallEnterWithin = Call->getCallEnterWithinCallerEvent()) +AddPieceFID(CallEnterWithin.get()); + + if (IntrusiveRefCntPtr + CallEnterEvent = Call->getCallEnterEvent()) +AddPieceFID(CallEnterEvent.get()); - WorkList.push_back(&call->path); + WorkList.push_back(&Call->path); } -else if (const PathDiagnosticMacroPiece *macro = - dyn_cast(piece)) { - WorkList.push_back(¯o->subPieces); +else if (const PathDiagnosticMacroPiece *Macro = + dyn_cast(Piece)) { + WorkList.push_back(&Macro->subPieces); } } } Index: cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp === --- cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp +++ cfe/trunk/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp @@ -0,0 +1,140 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist +// RUN: FileCheck --input-file=%t.plist %s + +#include "Inputs/include/plist-diagnostics-include-check-macro.h" + +void foo() { + PlistCheckMacro() +#define PLIST_DEF_MACRO .run(); +#include "Inputs/include/plist-diagnostics-include-check-macro.def" +} + +// CHECK: diagnostics +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT:path +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: kindevent +// CHECK-NEXT: location +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: ranges +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line7 +// CHECK-NEXT: col3 +// CHECK-NEXT: file0 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: line1 +// CHECK-NEXT: col15 +// CHECK-NEXT: file2 +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: depth0 +// CHECK-NEXT: extended_message +// CHECK-NEXT: Calling 'PlistCheckMacro::run' +//
r280367 - [analyzer] ExprEngine: remove second call to PreStmt
Author: a.sidorin Date: Thu Sep 1 08:55:38 2016 New Revision: 280367 URL: http://llvm.org/viewvc/llvm-project?rev=280367&view=rev Log: [analyzer] ExprEngine: remove second call to PreStmt This patch also introduces AnalysisOrderChecker which is intended for testing of callback call correctness. Differential Revision: https://reviews.llvm.org/D23804 Added: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp cfe/trunk/test/Analysis/castexpr-callback.c Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=280367&r1=280366&r2=280367&view=diff == --- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Thu Sep 1 08:55:38 2016 @@ -634,6 +634,10 @@ def LLVMConventionsChecker : Checker<"Co let ParentPackage = Debug in { +def AnalysisOrderChecker : Checker<"AnalysisOrder">, + HelpText<"Print callbacks that are called during analysis in order">, + DescFile<"AnalysisOrder.cpp">; + def DominatorsTreeDumper : Checker<"DumpDominators">, HelpText<"Print the dominance tree for a given CFG">, DescFile<"DebugCheckers.cpp">; Added: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp?rev=280367&view=auto == --- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp (added) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp Thu Sep 1 08:55:38 2016 @@ -0,0 +1,56 @@ +//===- AnalysisOrderChecker - Print callbacks called *- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This checker prints callbacks that are called during analysis. +// This is required to ensure that callbacks are fired in order +// and do not duplicate or get lost. +// Feel free to extend this checker with any callback you need to check. +// +//===--===// + +#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" + +using namespace clang; +using namespace ento; + +namespace { + +class AnalysisOrderChecker : public Checker< check::PreStmt, + check::PostStmt> { + bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const { +AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions(); +return Opts.getBooleanOption("*", false, this) || +Opts.getBooleanOption(CallbackName, false, this); + } + +public: + void checkPreStmt(const CastExpr *CE, CheckerContext &C) const { +if (isCallbackEnabled(C, "PreStmtCastExpr")) + llvm::errs() << "PreStmt (Kind : " << CE->getCastKindName() + << ")\n"; + } + + void checkPostStmt(const CastExpr *CE, CheckerContext &C) const { +if (isCallbackEnabled(C, "PostStmtCastExpr")) + llvm::errs() << "PostStmt (Kind : " << CE->getCastKindName() + << ")\n"; + } +}; +} + +//===--===// +// Registration. +//===--===// + +void ento::registerAnalysisOrderChecker(CheckerManager &mgr) { + mgr.registerChecker(); +} Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=280367&r1=280366&r2=280367&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Thu Sep 1 08:55:38 2016 @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangStaticAnalyzerCheckers AllocationDiagnostics.cpp + AnalysisOrderChecker.cpp AnalyzerStatsChecker.cpp ArrayBoundChecker.cpp ArrayBoundCheckerV2.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=280367&r1=280366&r2=280367&view=diff =
Re: [PATCH] D24278: [analyzer] Extend bug reports with extra notes.
a.sidorin added a comment. This definitely seems to be useful. However, this patch is pretty big. Some of its parts are not directly related with the feature being introduced (for example, changes for copypaste/sub-sequences.cpp). Is it possible to split this patch? Moreover, as I understand, you may not even need a review for refactoring-only changes. Or you can make a review for them which will be done much faster. There is a temporary dump of some stylish comments after brief look. Comment at: lib/StaticAnalyzer/Core/BugReporter.cpp:3449 @@ +3448,3 @@ +// we may optionally convert those to path notes. +for (auto I = exampleReport->getExtraNotes().rbegin(), + E = exampleReport->getExtraNotes().rend(); I != E; ++I) { Reverse iteration on array and push the corresponding element to the front (always O(n)) seems a bit strange to me. I suggest using a combination of resize + move existing elements to the end + copy/transform from start. What do you think? Or am I missing something? Comment at: lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp:230 @@ +229,3 @@ +unsigned NumExtraPieces = 0; +for (auto I = path.begin(), E = path.end(); I != E; ++I) { + if (const auto *P = dyn_cast(I->get())) { const auto &Piece : path? Comment at: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:117 @@ +116,3 @@ + // First, add extra notes, even if paths should not be included. + for (PathPieces::const_iterator PI = PD->path.begin(), + PE = PD->path.end(); PI != PE; ++PI) { Range-for loop may look nicer here. What do you think? Comment at: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:119 @@ +118,3 @@ + PE = PD->path.end(); PI != PE; ++PI) { +if (!isa(PI->get())) + continue; if (isa<...>()) { ... ... } ? https://reviews.llvm.org/D24278 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r292776 - ASTImporter: improve support for C++ templates
Author: a.sidorin Date: Mon Jan 23 03:30:36 2017 New Revision: 292776 URL: http://llvm.org/viewvc/llvm-project?rev=292776&view=rev Log: ASTImporter: improve support for C++ templates * Support template partial specialization * Avoid infinite recursion in IsStructurallyEquivalent for TemplateArgument with implementing IsStructurallyEquivalent for TemplateName Modified: cfe/trunk/include/clang/AST/TemplateBase.h cfe/trunk/lib/AST/ASTImporter.cpp Modified: cfe/trunk/include/clang/AST/TemplateBase.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=292776&r1=292775&r2=292776&view=diff == --- cfe/trunk/include/clang/AST/TemplateBase.h (original) +++ cfe/trunk/include/clang/AST/TemplateBase.h Mon Jan 23 03:30:36 2017 @@ -578,6 +578,7 @@ struct ASTTemplateArgumentListInfo final TemplateArgumentLoc> { private: friend TrailingObjects; + friend class ASTNodeImporter; ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=292776&r1=292775&r2=292776&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jan 23 03:30:36 2017 @@ -72,7 +72,7 @@ namespace clang { QualType VisitEnumType(const EnumType *T); QualType VisitAttributedType(const AttributedType *T); QualType VisitTemplateTypeParmType(const TemplateTypeParmType *T); -// FIXME: SubstTemplateTypeParmType +QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T); QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T); QualType VisitElaboratedType(const ElaboratedType *T); // FIXME: DependentNameType @@ -278,6 +278,8 @@ namespace clang { Expr *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E); Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E); Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E); +Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E); + template void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) { @@ -397,6 +399,9 @@ static bool IsStructurallyEquivalent(Str QualType T1, QualType T2); static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, Decl *D1, Decl *D2); +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const TemplateArgument &Arg1, + const TemplateArgument &Arg2); /// \brief Determine structural equivalence of two expressions. static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, @@ -421,8 +426,103 @@ static bool IsStructurallyEquivalent(con static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, NestedNameSpecifier *NNS1, NestedNameSpecifier *NNS2) { - // FIXME: Implement! - return true; + if (NNS1->getKind() != NNS2->getKind()) +return false; + + NestedNameSpecifier *Prefix1 = NNS1->getPrefix(), + *Prefix2 = NNS2->getPrefix(); + if ((bool)Prefix1 != (bool)Prefix2) +return false; + + if (Prefix1) +if (!IsStructurallyEquivalent(Context, Prefix1, Prefix2)) + return false; + + switch (NNS1->getKind()) { + case NestedNameSpecifier::Identifier: +return IsStructurallyEquivalent(NNS1->getAsIdentifier(), +NNS2->getAsIdentifier()); + case NestedNameSpecifier::Namespace: +return IsStructurallyEquivalent(Context, NNS1->getAsNamespace(), +NNS2->getAsNamespace()); + case NestedNameSpecifier::NamespaceAlias: +return IsStructurallyEquivalent(Context, NNS1->getAsNamespaceAlias(), +NNS2->getAsNamespaceAlias()); + case NestedNameSpecifier::TypeSpec: + case NestedNameSpecifier::TypeSpecWithTemplate: +return IsStructurallyEquivalent(Context, QualType(NNS1->getAsType(), 0), +QualType(NNS2->getAsType(), 0)); + case NestedNameSpecifier::Global: +return true; + case NestedNameSpecifier::Super: +return IsStructurallyEquivalent(Context, NNS1->getAsRecordDecl(), +NNS2->getAsRecordDecl()); + } + return false; +} + +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const TemplateName &N1, + const TemplateName &N2) { + if (N1.getKind() != N2.getKind()) +return false; + switch (N1.getKind()) { + case TemplateName::Template: +return IsStructurallyEq
r292778 - ASTImporter: add forgotten tests for rL292776
Author: a.sidorin Date: Mon Jan 23 03:45:29 2017 New Revision: 292778 URL: http://llvm.org/viewvc/llvm-project?rev=292778&view=rev Log: ASTImporter: add forgotten tests for rL292776 Added: cfe/trunk/test/ASTMerge/class-template-partial-spec/ cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/ cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp Added: cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp?rev=292778&view=auto == --- cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp (added) +++ cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp Mon Jan 23 03:45:29 2017 @@ -0,0 +1,118 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleSource; +TwoOptionTemplate SecondDoubleSource; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + int member; + static constexpr int val = I; +}; + +template +struct IntTemplateSpec { + char member; + static constexpr int val = I; +}; + +IntTemplateSpec<4, wchar_t> Y0; +IntTemplateSpec<5, void *> Y1; +IntTemplateSpec<1, long> Y2; +IntTemplateSpec<3, int> Y3; +//template constexpr int IntTemplateSpec::val; +IntTemplateSpec<42, double> NumberSource; +static_assert(NumberSource.val == 42); + +namespace One { +namespace Two { + // Just an empty namespace to ensure we can deal with multiple namespace decls. +} +} + + +namespace One { +namespace Two { +namespace Three { + +template +class Parent {}; + +} // namespace Three + +} // namespace Two + +template +struct Child1: public Two::Three::Parent { + char member; +}; + +template +struct Child1> { + T member; +}; + +} // namespace One + +One::Child1 Z0Source; + +// Test import of nested namespace specifiers +template +struct Outer { + template class Inner0; +}; + +template +template +class Outer::Inner0 { +public: + void f(X, Y); + template struct Inner1; +}; + +template +template +void Outer::Inner0::f(X, Y) {} + +template +template +template +class Outer::Inner0::Inner1 { +public: + void f(Y, Z); +}; + +template +template +template +void Outer::Inner0::Inner1::f(Y, Z) {} Added: cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp?rev=292778&view=auto == --- cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp (added) +++ cfe/trunk/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp Mon Jan 23 03:45:29 2017 @@ -0,0 +1,79 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleDest; +TwoOptionTemplate SecondDoubleDest; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + double member; + static constexpr int val = I; +}; + +template +struct IntTemplateSpec { + char member; + static constexpr int val = I; +}; + +IntTemplateSpec<4, wchar_t>Y0; +IntTemplateSpec<5, void *> Y1; +IntTemplateSpec<1, int> Y2; +IntTemplateSpec<2, int> Y3; +IntTemplateSpec<43, double> NumberDest; + +namespace One { +namespace Two { +namespace Three { + +template +class Parent {}; + +} // namespace Three + +} // namespace Two + +template +struct Child1: public Two::Three::Parent { + char member; +}; + +template +struct Child1> { + T member; +}; + +} // namespace One + +namespace Dst { One::Child1> Z0Dst; } +One::Child1 Z1; Added: cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp?rev=292778&view=auto =
r292779 - ASTImporter: quick test fix
Author: a.sidorin Date: Mon Jan 23 04:16:30 2017 New Revision: 292779 URL: http://llvm.org/viewvc/llvm-project?rev=292779&view=rev Log: ASTImporter: quick test fix Differential Revision: https://reviews.llvm.org/D26753 Modified: cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp Modified: cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp?rev=292779&r1=292778&r2=292779&view=diff == --- cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp (original) +++ cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp Mon Jan 23 04:16:30 2017 @@ -9,17 +9,17 @@ static_assert(sizeof(Z0Source.member) == static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double)); static_assert(sizeof(One::Child1>::member) == sizeof(double)); -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' +// CHECK: Inputs/class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: Inputs/class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' +// CHECK: Inputs/class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: Inputs/class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here +// CHECK: Inputs/class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units +// CHECK: Inputs/class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here +// CHECK: Inputs/class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') -// CHECK: llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>' +// CHECK: Inputs/class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') +// CHECK: Inputs/class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>' // CHECK-NOT: static_assert ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r292781 - ASTImporter: fix tests on Windows with removing slashed parts of paths
Author: a.sidorin Date: Mon Jan 23 04:39:45 2017 New Revision: 292781 URL: http://llvm.org/viewvc/llvm-project?rev=292781&view=rev Log: ASTImporter: fix tests on Windows with removing slashed parts of paths Differential Revision: https://reviews.llvm.org/D26753 Modified: cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp Modified: cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp?rev=292781&r1=292780&r2=292781&view=diff == --- cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp (original) +++ cfe/trunk/test/ASTMerge/class-template-partial-spec/test.cpp Mon Jan 23 04:39:45 2017 @@ -9,17 +9,17 @@ static_assert(sizeof(Z0Source.member) == static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double)); static_assert(sizeof(One::Child1>::member) == sizeof(double)); -// CHECK: Inputs/class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') -// CHECK: Inputs/class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' +// CHECK: class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' -// CHECK: Inputs/class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') -// CHECK: Inputs/class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' +// CHECK: class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' -// CHECK: Inputs/class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units -// CHECK: Inputs/class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here -// CHECK: Inputs/class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here +// CHECK: class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units +// CHECK: class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here +// CHECK: class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here -// CHECK: Inputs/class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') -// CHECK: Inputs/class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>' +// CHECK: class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') +// CHECK: class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>' // CHECK-NOT: static_assert ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r323519 - [ASTImporter] Support LambdaExprs and improve template support
Author: a.sidorin Date: Fri Jan 26 03:36:54 2018 New Revision: 323519 URL: http://llvm.org/viewvc/llvm-project?rev=323519&view=rev Log: [ASTImporter] Support LambdaExprs and improve template support Also, a number of style and bug fixes was done: * ASTImporterTest: added sanity check for source node * ExternalASTMerger: better lookup for template specializations * ASTImporter: don't add templated declarations into DeclContext * ASTImporter: introduce a helper, ImportTemplateArgumentListInfo getting SourceLocations * ASTImporter: proper set ParmVarDecls for imported FunctionProtoTypeLoc Differential Revision: https://reviews.llvm.org/D42301 Added: cfe/trunk/test/ASTMerge/function-cpp/ cfe/trunk/test/ASTMerge/function-cpp/Inputs/ cfe/trunk/test/ASTMerge/function-cpp/Inputs/function-1.cpp cfe/trunk/test/ASTMerge/function-cpp/test.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp cfe/trunk/lib/AST/ExternalASTMerger.cpp cfe/trunk/test/ASTMerge/class-template/Inputs/class-template1.cpp cfe/trunk/test/ASTMerge/class-template/Inputs/class-template2.cpp cfe/trunk/test/ASTMerge/class-template/test.cpp cfe/trunk/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp cfe/trunk/test/ASTMerge/exprs-cpp/test.cpp cfe/trunk/test/Import/template-specialization/Inputs/T.cpp cfe/trunk/test/Import/template-specialization/test.cpp cfe/trunk/unittests/AST/ASTImporterTest.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=323519&r1=323518&r2=323519&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Fri Jan 26 03:36:54 2018 @@ -97,6 +97,8 @@ namespace clang { typedef DesignatedInitExpr::Designator Designator; Designator ImportDesignator(const Designator &D); +Optional ImportLambdaCapture(const LambdaCapture &From); + /// \brief What we should import from the definition. enum ImportDefinitionKind { @@ -127,16 +129,26 @@ namespace clang { bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To, ImportDefinitionKind Kind = IDK_Default); TemplateParameterList *ImportTemplateParameterList( - TemplateParameterList *Params); +TemplateParameterList *Params); TemplateArgument ImportTemplateArgument(const TemplateArgument &From); Optional ImportTemplateArgumentLoc( const TemplateArgumentLoc &TALoc); bool ImportTemplateArguments(const TemplateArgument *FromArgs, unsigned NumFromArgs, - SmallVectorImpl &ToArgs); + SmallVectorImpl &ToArgs); + template bool ImportTemplateArgumentListInfo(const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo); + +template +bool ImportTemplateArgumentListInfo(SourceLocation FromLAngleLoc, +SourceLocation FromRAngleLoc, +const InContainerTy &Container, +TemplateArgumentListInfo &Result); + +bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD); + bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord, bool Complain = true); bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar, @@ -295,6 +307,7 @@ namespace clang { Expr *VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); +Expr *VisitLambdaExpr(LambdaExpr *LE); Expr *VisitInitListExpr(InitListExpr *E); Expr *VisitArrayInitLoopExpr(ArrayInitLoopExpr *E); Expr *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E); @@ -1045,7 +1058,6 @@ bool ASTNodeImporter::ImportDefinition(R = FromData.HasDeclaredCopyConstructorWithConstParam; ToData.HasDeclaredCopyAssignmentWithConstParam = FromData.HasDeclaredCopyAssignmentWithConstParam; -ToData.IsLambda = FromData.IsLambda; SmallVector Bases; for (const auto &Base1 : FromCXX->bases()) { @@ -1256,6 +1268,9 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } +// We cannot use Optional<> pattern here and below because +// TemplateArgumentListInfo's operator new is declared as deleted so it cannot +// be stored in Optional. template bool ASTNodeImporter::ImportTemplateArgumentListInfo( const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) { @@ -1268,6 +1283,18 @@ bool ASTNodeImporter::ImportTemplateArgu return false; } +template +bool ASTNodeImporter::ImportTemplateArgumentListInfo( +SourceLocation FromLA
r295644 - [analyzer] Do not duplicate call graph nodes for functions that have definition and forward declaration
Author: a.sidorin Date: Mon Feb 20 03:16:48 2017 New Revision: 295644 URL: http://llvm.org/viewvc/llvm-project?rev=295644&view=rev Log: [analyzer] Do not duplicate call graph nodes for functions that have definition and forward declaration Patch by Ivan Sidorenko! Differential Revision: https://reviews.llvm.org/D29643 Modified: cfe/trunk/include/clang/Analysis/CallGraph.h cfe/trunk/test/Analysis/debug-CallGraph.c Modified: cfe/trunk/include/clang/Analysis/CallGraph.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CallGraph.h?rev=295644&r1=295643&r2=295644&view=diff == --- cfe/trunk/include/clang/Analysis/CallGraph.h (original) +++ cfe/trunk/include/clang/Analysis/CallGraph.h Mon Feb 20 03:16:48 2017 @@ -98,7 +98,7 @@ public: bool VisitFunctionDecl(FunctionDecl *FD) { // We skip function template definitions, as their semantics is // only determined when they are instantiated. -if (includeInGraph(FD)) { +if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) { // Add all blocks declared inside this function to the graph. addNodesForBlocks(FD); // If this function has external linkage, anything could call it. Modified: cfe/trunk/test/Analysis/debug-CallGraph.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/debug-CallGraph.c?rev=295644&r1=295643&r2=295644&view=diff == --- cfe/trunk/test/Analysis/debug-CallGraph.c (original) +++ cfe/trunk/test/Analysis/debug-CallGraph.c Mon Feb 20 03:16:48 2017 @@ -43,8 +43,18 @@ void eee(); void eee() {} void fff() { eee(); } +// This test case tests that forward declaration for the top-level function +// does not affect call graph construction. +void do_nothing() {} +void test_single_call(); +void test_single_call() { + do_nothing(); +} + // CHECK:--- Call graph Dump --- -// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ccc ddd eee fff $}} +// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call $}} +// CHECK-NEXT: {{Function: test_single_call calls: do_nothing $}} +// CHECK-NEXT: {{Function: do_nothing calls: $}} // CHECK-NEXT: {{Function: fff calls: eee $}} // CHECK-NEXT: {{Function: eee calls: $}} // CHECK-NEXT: {{Function: ddd calls: ccc $}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r295654 - [ASTImporter] Support default argument initialization of ParmVarDecls
Author: a.sidorin Date: Mon Feb 20 05:57:12 2017 New Revision: 295654 URL: http://llvm.org/viewvc/llvm-project?rev=295654&view=rev Log: [ASTImporter] Support default argument initialization of ParmVarDecls Patch by Peter Szecsi! Differential Revision: https://reviews.llvm.org/D29612 Modified: cfe/trunk/lib/AST/ASTImporter.cpp cfe/trunk/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp cfe/trunk/test/ASTMerge/exprs-cpp/test.cpp Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=295654&r1=295653&r2=295654&view=diff == --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Feb 20 05:57:12 2017 @@ -3859,8 +3859,27 @@ Decl *ASTNodeImporter::VisitParmVarDecl( Importer.Import(D->getInnerLocStart()), Loc, Name.getAsIdentifierInfo(), T, TInfo, D->getStorageClass(), -/*FIXME: Default argument*/nullptr); +/*DefaultArg*/ nullptr); + + // Set the default argument. ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg()); + ToParm->setKNRPromoted(D->isKNRPromoted()); + + Expr *ToDefArg = nullptr; + Expr *FromDefArg = nullptr; + if (D->hasUninstantiatedDefaultArg()) { +FromDefArg = D->getUninstantiatedDefaultArg(); +ToDefArg = Importer.Import(FromDefArg); +ToParm->setUninstantiatedDefaultArg(ToDefArg); + } else if (D->hasUnparsedDefaultArg()) { +ToParm->setUnparsedDefaultArg(); + } else if (D->hasDefaultArg()) { +FromDefArg = D->getDefaultArg(); +ToDefArg = Importer.Import(FromDefArg); +ToParm->setDefaultArg(ToDefArg); + } + if (FromDefArg && !ToDefArg) +return nullptr; if (D->isUsed()) ToParm->setIsUsed(); Modified: cfe/trunk/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp?rev=295654&r1=295653&r2=295654&view=diff == --- cfe/trunk/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp (original) +++ cfe/trunk/test/ASTMerge/exprs-cpp/Inputs/exprs3.cpp Mon Feb 20 05:57:12 2017 @@ -108,6 +108,10 @@ int testDefaultArg(int a = 2*2) { return a; } +int testDefaultArgExpr() { + return testDefaultArg(); +} + template // T has TemplateTypeParmType void testTemplateTypeParmType(int i); Modified: cfe/trunk/test/ASTMerge/exprs-cpp/test.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/exprs-cpp/test.cpp?rev=295654&r1=295653&r2=295654&view=diff == --- cfe/trunk/test/ASTMerge/exprs-cpp/test.cpp (original) +++ cfe/trunk/test/ASTMerge/exprs-cpp/test.cpp Mon Feb 20 05:57:12 2017 @@ -41,5 +41,7 @@ void testImport(int *x, const S1 &cs1, S testScalarInit(42); testOffsetOf(); testDefaultArg(12); + testDefaultArg(); + testDefaultArgExpr(); useTemplateType(); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r296884 - [Analyzer] Terminate analysis on OpenMP code instead of assertion crash
Author: a.sidorin Date: Fri Mar 3 10:58:53 2017 New Revision: 296884 URL: http://llvm.org/viewvc/llvm-project?rev=296884&view=rev Log: [Analyzer] Terminate analysis on OpenMP code instead of assertion crash * ExprEngine assumes that OpenMP statements should never appear in CFG. However, current CFG doesn't know anything about OpenMP and passes such statements as CFG nodes causing "UNREACHABLE executed!" crashes. Since there is no OpenMP implementation in ExprEngine or CFG, we stop the analysis on OpenMP statements to avoid crashes. This fixes PR31835. Differential Revision: https://reviews.llvm.org/D30565 Added: cfe/trunk/test/Analysis/openmp-unsupported.c Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=296884&r1=296883&r2=296884&view=diff == --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Mar 3 10:58:53 2017 @@ -777,7 +777,7 @@ void ExprEngine::Visit(const Stmt *S, Ex assert(!isa(S) || S == cast(S)->IgnoreParens()); switch (S->getStmtClass()) { -// C++ and ARC stuff we don't support yet. +// C++, OpenMP and ARC stuff we don't support yet. case Expr::ObjCIndirectCopyRestoreExprClass: case Stmt::CXXDependentScopeMemberExprClass: case Stmt::CXXInheritedCtorInitExprClass: @@ -805,36 +805,7 @@ void ExprEngine::Visit(const Stmt *S, Ex case Stmt::SEHTryStmtClass: case Stmt::SEHExceptStmtClass: case Stmt::SEHLeaveStmtClass: -case Stmt::SEHFinallyStmtClass: { - const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); - Engine.addAbortedBlock(node, currBldrCtx->getBlock()); - break; -} - -case Stmt::ParenExprClass: - llvm_unreachable("ParenExprs already handled."); -case Stmt::GenericSelectionExprClass: - llvm_unreachable("GenericSelectionExprs already handled."); -// Cases that should never be evaluated simply because they shouldn't -// appear in the CFG. -case Stmt::BreakStmtClass: -case Stmt::CaseStmtClass: -case Stmt::CompoundStmtClass: -case Stmt::ContinueStmtClass: -case Stmt::CXXForRangeStmtClass: -case Stmt::DefaultStmtClass: -case Stmt::DoStmtClass: -case Stmt::ForStmtClass: -case Stmt::GotoStmtClass: -case Stmt::IfStmtClass: -case Stmt::IndirectGotoStmtClass: -case Stmt::LabelStmtClass: -case Stmt::NoStmtClass: -case Stmt::NullStmtClass: -case Stmt::SwitchStmtClass: -case Stmt::WhileStmtClass: -case Expr::MSDependentExistsStmtClass: -case Stmt::CapturedStmtClass: +case Stmt::SEHFinallyStmtClass: case Stmt::OMPParallelDirectiveClass: case Stmt::OMPSimdDirectiveClass: case Stmt::OMPForDirectiveClass: @@ -882,6 +853,36 @@ void ExprEngine::Visit(const Stmt *S, Ex case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: +case Stmt::CapturedStmtClass: +{ + const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState()); + Engine.addAbortedBlock(node, currBldrCtx->getBlock()); + break; +} + +case Stmt::ParenExprClass: + llvm_unreachable("ParenExprs already handled."); +case Stmt::GenericSelectionExprClass: + llvm_unreachable("GenericSelectionExprs already handled."); +// Cases that should never be evaluated simply because they shouldn't +// appear in the CFG. +case Stmt::BreakStmtClass: +case Stmt::CaseStmtClass: +case Stmt::CompoundStmtClass: +case Stmt::ContinueStmtClass: +case Stmt::CXXForRangeStmtClass: +case Stmt::DefaultStmtClass: +case Stmt::DoStmtClass: +case Stmt::ForStmtClass: +case Stmt::GotoStmtClass: +case Stmt::IfStmtClass: +case Stmt::IndirectGotoStmtClass: +case Stmt::LabelStmtClass: +case Stmt::NoStmtClass: +case Stmt::NullStmtClass: +case Stmt::SwitchStmtClass: +case Stmt::WhileStmtClass: +case Expr::MSDependentExistsStmtClass: llvm_unreachable("Stmt should not be in analyzer evaluation loop"); case Stmt::ObjCSubscriptRefExprClass: Added: cfe/trunk/test/Analysis/openmp-unsupported.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/openmp-unsupported.c?rev=296884&view=auto == --- cfe/trunk/test/Analysis/openmp-unsupported.c (added) +++ cfe/trunk/test/Analysis/openmp-unsupported.c Fri Mar 3 10:58:53 2017 @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin -fopenmp -verify %s +// expected-no-diagnostics + +void openmp_parallel_crash_test() { +#
[PATCH] D26571: Clean up layout of ASTMerge tests
a.sidorin added a comment. @spyffe : It seems to be OK. Repository: rL LLVM https://reviews.llvm.org/D26571 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26753: ASTImporter: improve support for C++ templates
a.sidorin created this revision. a.sidorin added reviewers: spyffe, khazem. a.sidorin added a subscriber: cfe-commits. - Support template partial specialization - Avoid infinite recursion in IsStructurallyEquivalent for TemplateArgument with implementing IsStructurallyEquivalent for TemplateName https://reviews.llvm.org/D26753 Files: include/clang/AST/TemplateBase.h lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/class-template-partial-spec1.cpp test/ASTMerge/Inputs/class-template-partial-spec2.cpp test/ASTMerge/class-template-partial-spec.cpp Index: test/ASTMerge/class-template-partial-spec.cpp === --- /dev/null +++ test/ASTMerge/class-template-partial-spec.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/class-template-partial-spec1.cpp +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/class-template-partial-spec2.cpp +// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +static_assert(sizeof(**SingleSource.member) == sizeof(**SingleDest.member)); +static_assert(sizeof(SecondDoubleSource.member) == sizeof(SecondDoubleDest.member)); +static_assert(NumberSource.val == NumberDest.val); + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec2.cpp:47:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/Inputs/class-template-partial-spec1.cpp:47:25: note: declared here with type 'IntTemplateSpec<3, int>' + Index: test/ASTMerge/Inputs/class-template-partial-spec2.cpp === --- /dev/null +++ test/ASTMerge/Inputs/class-template-partial-spec2.cpp @@ -0,0 +1,48 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleDest; +TwoOptionTemplate SecondDoubleDest; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + double member; + const int val = I; +}; + + +IntTemplateSpec<4, wchar_t> Y0; +IntTemplateSpec<5, void *> Y1; +IntTemplateSpec<1, int> Y2; +IntTemplateSpec<2, int> Y3; +IntTemplateSpec<42, void *> NumberDest; Index: test/ASTMerge/Inputs/class-template-partial-spec1.cpp === --- /dev/null +++ test/ASTMerge/Inputs/class-template-partial-spec1.cpp @@ -0,0 +1,48 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleSource; +TwoOptionTemplate SecondDoubleSource; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + int member; + const int val = I; +}; + + +IntTemplateSpec<4, wchar_t> Y0; +IntTemplateSpec<5, void *> Y1; +
[PATCH] D26753: ASTImporter: improve support for C++ templates
a.sidorin updated this revision to Diff 78382. a.sidorin added a comment. Address review comments; fix tests. https://reviews.llvm.org/D26753 Files: include/clang/AST/TemplateBase.h lib/AST/ASTImporter.cpp test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp test/ASTMerge/class-template-partial-spec/test.cpp Index: test/ASTMerge/class-template-partial-spec/test.cpp === --- /dev/null +++ test/ASTMerge/class-template-partial-spec/test.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/class-template-partial-spec1.cpp +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/class-template-partial-spec2.cpp +// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +static_assert(sizeof(**SingleSource.member) == sizeof(**SingleDest.member)); +static_assert(sizeof(SecondDoubleSource.member) == sizeof(SecondDoubleDest.member)); +static_assert(NumberSource.val == 42); +static_assert(sizeof(Z0Source.member) == sizeof(char)); +static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double)); +static_assert(sizeof(One::Child1>::member) == sizeof(double)); + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>' + +// CHECK-NOT: static_assert Index: test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp === --- /dev/null +++ test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp @@ -0,0 +1,79 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleDest; +TwoOptionTemplate SecondDoubleDest; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + double member; + static constexpr int val = I; +}; + +template +struct IntTemplateSpec { + char member; + static constexpr int val = I; +}; + +IntTemplateSpec<4, wchar_t>Y0; +IntTemplateSpec<5, void *> Y1; +IntTemplateSpec<1, int> Y2; +IntTemplateSpec<2, int> Y3; +IntTemplateSpec<43, double> NumberDest; + +namespace One { +namespace Two { +namespace Three { + +template +class Parent {}; + +} // namespace Three + +} // namespace Two + +template +struct Child1: public Two::Three::Parent { + char member; +}; + +template +struct Child1> { + T member; +}; + +} // namespace One + +namespace Dst { One::Child1> Z0Dst; } +One::Child1 Z1; Index: test/ASTMerge/class-template-partial-spec/Inputs
[PATCH] D26753: ASTImporter: improve support for C++ templates
a.sidorin added a comment. Thank you! I'll update this review again when I have a test for NestedNameSpecifierLocs. Comment at: lib/AST/ASTImporter.cpp:458 + } + return true; +} spyffe wrote: > Is this really an appropriate default result? I would argue for `false` here > so that an error would propagate, as is typical in ASTImporter. > Note that this does disagree with the original source's `true` but I think > that was because we knew we didn't handle anything, whereas now the > assumption is we handle everything. Good point. Default `false` will also fail import if a new non-handled property or option will be added in AST and clearly indicate an error so I will change it. https://reviews.llvm.org/D26753 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26837: [analyzer] Litter the SVal/SymExpr/MemRegion class hierarchy with asserts.
a.sidorin added a comment. Personally, I like this change because it makes our assumptions clearer. My comments are below. Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h:54 + : store(st), region(r) { +assert(r->getValueType()->isRecordType() || + r->getValueType()->isArrayType() || Could you extract `r->getValueType()` to a separate variable? Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h:319 public: - SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {} + SymbolVal() = delete; + SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) { assert(sym); } I cannot completely agree with this change. For example, some STL container methods require their type to be default constructible. Yes, it is a very limited usage case but I don't see strong reason to do it because there also may be some another usage scenarios. Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h:478 public: - explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {} + explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) { +assert(Label); By the way, why does this ctor accept a non-constant pointer? Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h:46 + static bool isValidTypeForSymbol(QualType T) { +// FIXME: Depending on wether we choose to deprecate structural symbols, +// this may become much stricter. s/wether/whether https://reviews.llvm.org/D26837 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26838: [analyzer] Enforce super-region classes for various memory regions through compile-time and run-time type checks.
a.sidorin added a comment. Hi Artem! I like this change mostly but I also have some remarks. Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h:1279 /// associated element type, index, and super region. const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx, +const SubRegion *superRegion, I think we should perform a `cast<>` to `SubRegion` internally in order to keep API simple and do not force clients to introduce casts in their code. This will still allow us to keep nice suggestions about SubRegions/MemSpaces in our hierarchy. Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h:1347 private: - template - RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion); + template + RegionTy* getSubRegion(const A1 a1, const SuperTy* superRegion); Maybe we should give types and paramers some more meaningful names as a part of refactoring? At least, the number in `A1` is not needed now. https://reviews.llvm.org/D26838 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26904: [astimporter] Support importing CXXDependentScopeMemberExpr and FunctionTemplateDecl
a.sidorin requested changes to this revision. a.sidorin added a subscriber: aaron.ballman. a.sidorin added a comment. This revision now requires changes to proceed. Hello Kareem, Thank you for working on it! You can find my comments below. Comment at: include/clang/ASTMatchers/ASTMatchers.h:5459 +/// \endcode +const internal::VariadicDynCastAllOfMatcher + cxxDependentScopeMemberExpr; I'd prefer to have a discussion with ASTMatcher developers (@aaron.ballman, @klimek) first. Maybe it is better to place this matcher into ASTImporterTest.cpp - as I understand, it will be used very rarely. Comment at: lib/AST/ASTImporter.cpp:3495 +return nullptr; + if (!DC) +return nullptr; If `DC` is `nullptr`, we should return on the previous line - `ImportDeclParts` returns `true` in this case. We may turn it into an assertion, however. Comment at: lib/AST/ASTImporter.cpp:3509 + + return FunctionTemplateDecl::Create(Importer.getToContext(), DC, Loc, + Name, Params, ToDecl); Seems like we don't attempt to lookup an existing declaration first. This may lead to appearance of multiple definitions of same decl. I'd also prefer to see a functional test for this in test/ASTMerge. You can also refer to https://github.com/haoNoQ/clang/blob/summary-ipa-draft/lib/AST/ASTImporter.cpp#L3594 because some important parts (setting of lexical decl context, adding a decl to the imported map) are missed here. https://reviews.llvm.org/D26904 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D27033: [ASTImporter] Support importing UnresolvedLookupExpr nodes
a.sidorin requested changes to this revision. a.sidorin added a reviewer: a.sidorin. a.sidorin added a comment. This revision now requires changes to proceed. Hi Kareem! I'll be happy to see this changes in upstream. Please see my comments inline. Comment at: lib/AST/ASTImporter.cpp:6492 + UnresolvedSet<8> ToDecls; + for (UnresolvedLookupExpr::decls_iterator S = E->decls_begin(), +F = E->decls_end(); `auto` will look nice here. Comment at: lib/AST/ASTImporter.cpp:6501 + + return UnresolvedLookupExpr::Create(Importer.getToContext(), NamingClass, + E->getQualifierLoc(), NameInfo, UnresolvedLookupExpr::Create is overloaded for different use cases and it seems like some of them are not covered here. You may refer to https://github.com/haoNoQ/clang/blob/summary-ipa-draft/lib/AST/ASTImporter.cpp#L7499 for some implementation details. Comment at: lib/AST/ASTImporter.cpp:6502 + return UnresolvedLookupExpr::Create(Importer.getToContext(), NamingClass, + E->getQualifierLoc(), NameInfo, + E->requiresADL(), E->isOverloaded(), QualifierLoc needs to be imported: it may refer to decls in the "from" context. https://reviews.llvm.org/D27033 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26753: ASTImporter: improve support for C++ templates
a.sidorin updated this revision to Diff 79054. a.sidorin added a comment. Add a simple test for import of complex `NestedNameSpecifierLoc`s. https://reviews.llvm.org/D26753 Files: include/clang/AST/TemplateBase.h lib/AST/ASTImporter.cpp test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp test/ASTMerge/class-template-partial-spec/test.cpp Index: test/ASTMerge/class-template-partial-spec/test.cpp === --- /dev/null +++ test/ASTMerge/class-template-partial-spec/test.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.1.ast %S/Inputs/class-template-partial-spec1.cpp +// RUN: %clang_cc1 -emit-pch -std=c++1z -o %t.2.ast %S/Inputs/class-template-partial-spec2.cpp +// RUN: not %clang_cc1 -std=c++1z -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s + +static_assert(sizeof(**SingleSource.member) == sizeof(**SingleDest.member)); +static_assert(sizeof(SecondDoubleSource.member) == sizeof(SecondDoubleDest.member)); +static_assert(NumberSource.val == 42); +static_assert(sizeof(Z0Source.member) == sizeof(char)); +static_assert(sizeof(Dst::Z0Dst.member) == sizeof(double)); +static_assert(sizeof(One::Child1>::member) == sizeof(double)); + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:21:32: error: external variable 'X1' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:21:31: note: declared here with type 'TwoOptionTemplate' + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:24:29: error: external variable 'X4' declared with incompatible types in different translation units ('TwoOptionTemplate' vs. 'TwoOptionTemplate') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:24:33: note: declared here with type 'TwoOptionTemplate' + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:38:8: warning: type 'IntTemplateSpec<5, void *>' has incompatible definitions in different translation units +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:39:7: note: field 'member' has type 'int' here +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:39:10: note: field 'member' has type 'double' here + +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp:52:25: error: external variable 'Y3' declared with incompatible types in different translation units ('IntTemplateSpec<2, int>' vs. 'IntTemplateSpec<3, int>') +// CHECK: /media/build/smrc-llvm/master/llvm/tools/clang/test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec1.cpp:52:25: note: declared here with type 'IntTemplateSpec<3, int>' + +// CHECK-NOT: static_assert Index: test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp === --- /dev/null +++ test/ASTMerge/class-template-partial-spec/Inputs/class-template-partial-spec2.cpp @@ -0,0 +1,79 @@ +template +struct TwoOptionTemplate {}; + +template +struct TwoOptionTemplate { + int member; +}; + + +template +struct TwoOptionTemplate { + float member; +}; + +template +struct TwoOptionTemplate { + T** member; +}; + +TwoOptionTemplate X0; +TwoOptionTemplate X1; +TwoOptionTemplate X2; +TwoOptionTemplate X3; +TwoOptionTemplate X4; +TwoOptionTemplate SingleDest; +TwoOptionTemplate SecondDoubleDest; + + +template +struct IntTemplateSpec {}; + +template +struct IntTemplateSpec<4, C> { + C member; +}; + +template +struct IntTemplateSpec { + double member; + static constexpr int val = I; +}; + +template +struct IntTemplateSpec { + char member; + static constexpr int val = I; +}; + +IntTemplateSpec<4, wchar_t>Y0; +IntTemplateSpec<5, void *> Y1; +IntTemplateSpec<1, int> Y2; +IntTemplateSpec<2, int> Y3; +IntTemplateSpec<43, double> NumberDest; + +namespace One { +namespace Two { +namespace Three { + +template +class Parent {}; + +} // namespace Three + +} // namespace Two + +template +struct Child1: public Two::Three::Parent { + char member; +}; + +template +struct Child1> { + T member; +}; + +} // namespace One + +namespace Dst { One::Child1> Z0Dst; } +One::Child1 Z1; Index: test/ASTMerge/cla
[PATCH] D25660: [Analyzer] Checker for iterators dereferenced beyond their range.
a.sidorin added inline comments. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:209 + CheckerContext &C) const { + const auto *Func = Call.getDecl()->getAsFunction(); + if (Func->isOverloadedOperator()) { As I remember, `PostCall` is also called for ObjC calls like `ObjCMethodCall` which may not have `FunctionDecl` as their callee. So, `Func` may be a nullptr and needs a check. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:156 +if (isAccessOperator(Func->getOverloadedOperator())) { + if (Func->isCXXInstanceMember()) { +const auto &InstCall = static_cast(Call); This can be written some shorter: `if (const auto *InstCall = dyn_cast(&Call)` Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:219 + + assert(LCtx->getKind() == LocationContext::StackFrame && + "Function does not begin with stack frame context"); `isa(LCtx)`? And `cast<>` below already does the same check with an assertion. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:258 + auto State = C.getState(); + const auto *LCtx = C.getPredecessor()->getLocationContext(); + Just `C.getLocationContext()`? Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:305 + auto RegionMap = State->get(); + for (auto I = RegionMap.begin(), E = RegionMap.end(); I != E; ++I) { +if (!SR.isLiveRegion(I->first)) { This loop may be C++11-fied. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:322 + bool Assumption) const { + const auto *SE = Cond.getAsSymExpr(); + if (!SE) What will happen if we compare two iterators related to different containers? I guess the result will be undefined but I'm not sure if we can track it in this checker without referencing the owning container. Let's leave this code as-is but I think this choice deserves a comment. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:337 + const auto *RPos = getIteratorPosition(State, Right); + if (LPos && !RPos) { +if ((LPos->isInRange() && ((Opc == BO_EQ) == Assumption)) || Maybe we should just swap Rhs and Lhs if LPos is null? So, we can avoid code duplication. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:423 + +void IteratorPastEndChecker::handleComparison(CheckerContext &C, + const SVal &LVal, What will happen if we write something like this: ``` bool Eq1 = it1 == it2; bool Eq2 = it3 == it4; if (Eq1) {...}? ``` As I understand, we'll assume the second condition instead of first. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:454 + if (Pos && Pos->isOutofRange()) { +State = setIteratorPosition(State, Val, IteratorPosition::getInRange()); +C.addTransition(State); I'm not sure it's totally correct. `--` for `begin()` will give us out-of-range iterator. According to header description, we're catching just "past-end" iterators, but this is confusing a bit for me. Moreover, if we're out of end() in multiple positions, a single `--` will not make the iterator valid again. You use a good conservative approach, but could you please add a comment describing it? Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:571 + auto &svalBuilder = C.getSValBuilder(); + const auto *LCtx = C.getPredecessor()->getLocationContext(); + Just `C.getLocationContext()`. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:573 + + auto RetVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); + auto SecondParam = state->getSVal(CE->getArg(1), C.getLocationContext()); You can use overload which does not require the tag. Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:574 + auto RetVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount()); + auto SecondParam = state->getSVal(CE->getArg(1), C.getLocationContext()); + getLocationContext => LCtx Comment at: lib/StaticAnalyzer/Checkers/IteratorPastEndChecker.cpp:605 +static bool isIteratorType(const QualType &Type) { + const auto *CRD = Type->getUnqualifiedDesugaredType()->getAsCXXRecordDecl(); + return isIterator(CRD); A common way of defining iterator types is just their declaration as pointers. I'm not sure this code will work well in such cases. You can see some example in LLVM containers like SmallVector, where iterators are declared in the following way: ``` typedef T *ite
[PATCH] D25660: [Analyzer] Checker for iterators dereferenced beyond their range.
a.sidorin added a comment. Thank you for this patch! I like some solutions used in it but I also have some comments (inline). https://reviews.llvm.org/D25660 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26054: Use `getFileLoc()` instead of `getSpellingLoc()` in the ASTImporter
a.sidorin accepted this revision. a.sidorin added a comment. This revision is now accepted and ready to land. Looks good. But I think it will be good to put the files in Input to a separate directory. https://reviews.llvm.org/D26054 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D19979: [analyzer] ScopeContext - initial implementation
a.sidorin added a comment. Hm. A pretty nice example. But we should check if the initial patch supports `goto`s; afair, it doesn't. https://reviews.llvm.org/D19979 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26054: Use `getFileLoc()` instead of `getSpellingLoc()` in the ASTImporter
a.sidorin added a comment. Hi Sean! I meant that I'd like to have a layout like this: macro-loc.m Inputs/macro-loc/macro.modulemap Inputs/macro-loc/macro1.h Inputs/macro-loc/macro1.m Inputs/macro-loc/macro2.m By the way, I see that we use another workaround for this issue: we use `getDecomposedExpansionLoc()` instead of `getDecomposedLoc()` with removing previous line at all. I wonder if we are incorrect in our suggestion. https://reviews.llvm.org/D26054 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26054: Use `getFileLoc()` instead of `getSpellingLoc()` in the ASTImporter
a.sidorin added a comment. > Do you think it would be reasonable to take this diff the way it currently it > is, and start a new one that pulls all the input fiels into test-specific > subdirectories? > That way the desired layout of the `Inputs` directory will be clear to > future developers touching the source base. I'm totally OK with a new diff. Nice suggestion. Thank you! https://reviews.llvm.org/D26054 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26589: Add static analyzer checker for finding infinite recursion
a.sidorin added a comment. Wow, thank you for such a contribution! Did you evaluate this checker on some real code? I have some minor inline comments below. Comment at: lib/StaticAnalyzer/Checkers/CMakeLists.txt:41 IdenticalExprChecker.cpp +RecursionChecker.cpp IvarInvalidationChecker.cpp Please fix indentation here Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:12 +// This defines TestAfterDivZeroChecker, a builtin check that performs checks +// for division by zero where the division occurs before comparison with zero. +// This description is for other checker, could you update it? Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:21 + +REGISTER_SET_WITH_PROGRAMSTATE(DirtyStackFrames, const clang::StackFrameContext *) + The idea of "dirty stack frames" deserves some explanation. As I understand, it describes function calls where some values may change unexpectedly and we cannot consider this calls later. Am I understanding correctly? Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:49 + void checkPostCall(const CallEvent &Call, + CheckerContext &C) const; +}; Incorrect indentation. Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:68 + +if (ParentLC->getKind() != LocationContext::StackFrame) + continue; We may just use `getParent()->getCurrentStackFrame()` in the loop increment to make the code cleaner. What do you think? Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:79 +const FunctionDecl *PrevFuncDecl = +(const FunctionDecl *)PrevStackFrameCtx->getDecl(); +PrevFuncDecl = PrevFuncDecl->getCanonicalDecl(); We usually prefer LLVM `[dyn_]cast<>` where possible. Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:89 + SVal PrevArg = State->getArgSVal(PrevStackFrameCtx, i); + SameArgs = SameArgs && compareArgs(C, State, CurArg, PrevArg); +} Maybe we can use early return here? Comment at: test/Analysis/recursion.cpp:27 + +void f2(); +void f3(); I'd like to see some more informative function names: for me, it is hard to distinguish between f1-7 here :) It is also hard to determine the function where test starts. https://reviews.llvm.org/D26589 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26571: Clean up layout of ASTMerge tests
a.sidorin accepted this revision. a.sidorin added a comment. This revision is now accepted and ready to land. Looks good, thank you! Repository: rL LLVM https://reviews.llvm.org/D26571 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D26588: Add LocationContext to members of check::RegionChanges
a.sidorin added a comment. Hi Krzysztof! This change seems useful: I can imagine the situation where we want to ask current `LocationContext` in this callback. The change looks pretty intrusive but I mostly agree with it. Initially, I have some questions about the implementation of `getArgSVal()` function (inline comments). I'll add more comments later. Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h:735 + const FunctionDecl *FunctionDecl = SFC->getDecl()->getAsFunction(); + unsigned NumArgs = FunctionDecl->getNumParams(); + assert(ArgIdx < NumArgs && "Arg access out of range!"); Maybe we should put a check that requested StackFrame is our StackFrame or our parent StackFrame here? Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h:741 +// because the call wasn't modeled in the first place. +const VarDecl *ArgDecl = FunctionDecl->parameters()[ArgIdx]; +const Loc ArgLoc = getLValue(ArgDecl, SFC); Unfortunately, this code does not consider the fact that argument values may be overwritten. If we want to get initial values, we should find another way. https://reviews.llvm.org/D26588 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D3967: [Proposal] [Analyzer] Individual options for checkers
a.sidorin abandoned this revision. a.sidorin added a comment. Abandon this change since the patch based on this is committed in http://reviews.llvm.org/D7905 http://reviews.llvm.org/D3967 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D5102: [analyzer][Bugfix/improvement] Fix for PR16833
a.sidorin added a comment. Thank you for reply, Jordan. > I guess the regular pings didn't work, so it was worth trying the gentle one? > Sorry! And it worked :) I'll fix the issues you pointed. http://reviews.llvm.org/D5102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D5102: [analyzer][Bugfix/improvement] Fix for PR16833
a.sidorin added inline comments. Comment at: lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp:215-220 @@ +214,8 @@ + return assumeSymWithinInclusiveRange(State, Sym, From, To, InRange); +return State; + } // end switch + + case nonloc::ConcreteIntKind: { +const llvm::APSInt &IntVal = Value.castAs().getValue(); +bool IsInRange = IntVal >= From && IntVal <= To; +bool isFeasible = (IsInRange == InRange); jordan_rose wrote: > This is still relevant. Both types are equal for CaseStmt. But I'll check this code anyway because I found an interesting issue in CFG for SwitchStmt and I'm still investigating it. http://reviews.llvm.org/D5102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D5102: [analyzer][Bugfix/improvement] Fix for PR16833
a.sidorin updated this revision to Diff 32293. a.sidorin added a comment. - Fix review notes - Add some more tests - Add a fix and a test for incorrect pruning of trivially unreachable case statements in CFG for SwitchStmt (accidentially found while writing a test). http://reviews.llvm.org/D5102 Files: include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h lib/Analysis/CFG.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Core/RangeConstraintManager.cpp lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp lib/StaticAnalyzer/Core/SimpleConstraintManager.h test/Analysis/switch-case.c Index: test/Analysis/switch-case.c === --- /dev/null +++ test/Analysis/switch-case.c @@ -0,0 +1,220 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_eval(int); +void clang_analyzer_warnIfReached(); + +#define INT_MIN 0x8000 +#define INT_MAX 0x7fff + +// PR16833: Analyzer consumes memory until killed by kernel OOM killer +// while analyzing large case ranges. +void PR16833(unsigned op) { + switch (op) { + case 0x02 << 26 ... 0x03 << 26: // Analyzer should not hang here. +return; + } +} + +void testAdjustment(int t) { + switch (t + 1) { + case 2: +clang_analyzer_eval(t == 1); // expected-warning{{TRUE}} +break; + case 3 ... 10: +clang_analyzer_eval(t > 1);// expected-warning{{TRUE}} +clang_analyzer_eval(t + 2 <= 11); // expected-warning{{TRUE}} +clang_analyzer_eval(t > 2);// expected-warning{{UNKNOWN}} +clang_analyzer_eval(t + 1 == 3); // expected-warning{{UNKNOWN}} +clang_analyzer_eval(t + 1 == 10); // expected-warning{{UNKNOWN}} +break; + default: +clang_analyzer_warnIfReached();// expected-warning{{REACHABLE}} + } +} + +void testUnknownVal(int value, int mask) { + // Once ConstraintManager will process '&' and this test will require some changes. + switch (value & mask) { +case 1: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + break; +case 3 ... 10: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + break; +default: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + } +} + +void testSwitchCond(int arg) { + if (arg > 10) { +switch (arg) { +case INT_MIN ... 10: + clang_analyzer_warnIfReached(); // no-warning + break; +case 11 ... 20: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + break; +default: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +} + +switch (arg) { +case INT_MIN ... 9: + clang_analyzer_warnIfReached(); // no-warning + break; +case 10 ... 20: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg > 10); // expected-warning{{TRUE}} + break; +default: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +} + } // arg > 10 +} + +void testDefaultUnreachable(int arg) { + if (arg > 10) { +switch (arg) { +case INT_MIN ... 9: + clang_analyzer_warnIfReached(); // no-warning + break; +case 10 ... INT_MAX: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg > 10);// expected-warning{{TRUE}} + break; +default: + clang_analyzer_warnIfReached(); // no-warning +} + } +} + +void testBranchReachability(int arg) { + if (arg > 10 && arg < 20) { +switch (arg) { +case INT_MIN ... 4: + clang_analyzer_warnIfReached(); // no-warning + break; +case 5 ... 9: + clang_analyzer_warnIfReached(); // no-warning + break; +case 10 ... 15: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg > 10 && arg <= 15); // expected-warning{{TRUE}} + break; +default: + clang_analyzer_warnIfReached(); // no-warning + break; +case 17 ... 25: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg >= 17 && arg < 20); // expected-warning{{TRUE}} + break; +case 26 ... INT_MAX: + clang_analyzer_warnIfReached(); // no-warning + break; +case 16: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg == 16); // expected-warning{{TRUE}} + break; +} + } +} + +void testDefaultBranchRange(int arg) { + switch (arg) { + case INT_MIN ... 9: +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +break; + case 20 ... INT_MAX: +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +clang_analyzer_eval(arg >= 20); // expected-warning{{TRUE}} +break; + default: +c
Re: [PATCH] D5102: [analyzer][Bugfix/improvement] Fix for PR16833
a.sidorin updated this revision to Diff 32664. a.sidorin marked an inline comment as done. a.sidorin added a comment. Remove duplicating assertion. http://reviews.llvm.org/D5102 Files: include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h lib/Analysis/CFG.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp lib/StaticAnalyzer/Core/RangeConstraintManager.cpp lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp lib/StaticAnalyzer/Core/SimpleConstraintManager.h test/Analysis/switch-case.c Index: test/Analysis/switch-case.c === --- /dev/null +++ test/Analysis/switch-case.c @@ -0,0 +1,220 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_eval(int); +void clang_analyzer_warnIfReached(); + +#define INT_MIN 0x8000 +#define INT_MAX 0x7fff + +// PR16833: Analyzer consumes memory until killed by kernel OOM killer +// while analyzing large case ranges. +void PR16833(unsigned op) { + switch (op) { + case 0x02 << 26 ... 0x03 << 26: // Analyzer should not hang here. +return; + } +} + +void testAdjustment(int t) { + switch (t + 1) { + case 2: +clang_analyzer_eval(t == 1); // expected-warning{{TRUE}} +break; + case 3 ... 10: +clang_analyzer_eval(t > 1);// expected-warning{{TRUE}} +clang_analyzer_eval(t + 2 <= 11); // expected-warning{{TRUE}} +clang_analyzer_eval(t > 2);// expected-warning{{UNKNOWN}} +clang_analyzer_eval(t + 1 == 3); // expected-warning{{UNKNOWN}} +clang_analyzer_eval(t + 1 == 10); // expected-warning{{UNKNOWN}} +break; + default: +clang_analyzer_warnIfReached();// expected-warning{{REACHABLE}} + } +} + +void testUnknownVal(int value, int mask) { + // Once ConstraintManager will process '&' and this test will require some changes. + switch (value & mask) { +case 1: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + break; +case 3 ... 10: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + break; +default: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + } +} + +void testSwitchCond(int arg) { + if (arg > 10) { +switch (arg) { +case INT_MIN ... 10: + clang_analyzer_warnIfReached(); // no-warning + break; +case 11 ... 20: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + break; +default: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +} + +switch (arg) { +case INT_MIN ... 9: + clang_analyzer_warnIfReached(); // no-warning + break; +case 10 ... 20: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg > 10); // expected-warning{{TRUE}} + break; +default: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +} + } // arg > 10 +} + +void testDefaultUnreachable(int arg) { + if (arg > 10) { +switch (arg) { +case INT_MIN ... 9: + clang_analyzer_warnIfReached(); // no-warning + break; +case 10 ... INT_MAX: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg > 10);// expected-warning{{TRUE}} + break; +default: + clang_analyzer_warnIfReached(); // no-warning +} + } +} + +void testBranchReachability(int arg) { + if (arg > 10 && arg < 20) { +switch (arg) { +case INT_MIN ... 4: + clang_analyzer_warnIfReached(); // no-warning + break; +case 5 ... 9: + clang_analyzer_warnIfReached(); // no-warning + break; +case 10 ... 15: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg > 10 && arg <= 15); // expected-warning{{TRUE}} + break; +default: + clang_analyzer_warnIfReached(); // no-warning + break; +case 17 ... 25: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg >= 17 && arg < 20); // expected-warning{{TRUE}} + break; +case 26 ... INT_MAX: + clang_analyzer_warnIfReached(); // no-warning + break; +case 16: + clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} + clang_analyzer_eval(arg == 16); // expected-warning{{TRUE}} + break; +} + } +} + +void testDefaultBranchRange(int arg) { + switch (arg) { + case INT_MIN ... 9: +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +break; + case 20 ... INT_MAX: +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +clang_analyzer_eval(arg >= 20); // expected-warning{{TRUE}} +break; + default: +clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} +clang_analyzer_eval(arg == 16); // expected-warni
Re: [PATCH] D5102: [analyzer][Bugfix/improvement] Fix for PR16833
a.sidorin marked 8 inline comments as done. a.sidorin added a comment. http://reviews.llvm.org/D5102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D14014: Checker of proper vfork usage
a.sidorin added a comment. I put some suggestions in inline comments. Comment at: lib/StaticAnalyzer/Checkers/VforkChecker.cpp:47 @@ +46,3 @@ + + bool isChildProcess(const ProgramStateRef State) const; + I think it's a good idea to make some functions static and/or move them out of class definition. Comment at: lib/StaticAnalyzer/Checkers/VforkChecker.cpp:97 @@ +96,3 @@ + +ASTContext &Ctx = C.getASTContext(); +for (const char **id = ids; *id; ++id) What about combination of std::transform + std::sort + std::binary_search? Comment at: lib/StaticAnalyzer/Checkers/VforkChecker.cpp:136 @@ +135,3 @@ +const DeclStmt *PD = dyn_cast_or_null(P); +if (!PD) + break; ``` if (PD && PD->isSingleDecl()) { if (const VarDecl *D = dyn_cast(PD->getSingleDecl()) return D; ``` Comment at: lib/StaticAnalyzer/Checkers/VforkChecker.cpp:149 @@ +148,3 @@ + + // see if it's an ordinary assignment + do { You can use early return to escape do{}. Comment at: lib/StaticAnalyzer/Checkers/VforkChecker.cpp:196 @@ +195,3 @@ + SVal VforkRetVal = Call.getReturnValue(); + SymbolRef Sym = VforkRetVal.getAsSymbol(); + Optional DVal = Is check for non-concrete value is really required? Comment at: lib/StaticAnalyzer/Checkers/VforkChecker.cpp:252 @@ +251,3 @@ + ProgramStateRef State = C.getState(); + if (!isChildProcess(State)) +return; ``` if (is...) report... ``` Repository: rL LLVM http://reviews.llvm.org/D14014 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D14014: Checker of proper vfork usage
a.sidorin added inline comments. Comment at: lib/StaticAnalyzer/Checkers/VforkChecker.cpp:47 @@ +46,3 @@ + + bool isChildProcess(const ProgramStateRef State) const; + ygribov wrote: > a.sidorin wrote: > > I think it's a good idea to make some functions static and/or move them out > > of class definition. > Right. Which one is preferred btw? isChildProcess(), getAssignedVariable() are good candidates since they don't use any class member. Repository: rL LLVM http://reviews.llvm.org/D14014 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D14286: ASTImporter: expressions, pt.1
a.sidorin created this revision. a.sidorin added a reviewer: sepavloff. a.sidorin added a subscriber: cfe-commits. a.sidorin set the repository for this revision to rL LLVM. This patch implements some expression-related AST node import. This is the first patch in a series. Supported nodes: GCCAsmStmt VAArgExpr GNUNullExpr PredefinedExpr InitListExpr DesignatedInitExpr CXXNullPtrLiteralExpr CXXBoolLiteralExpr CompoundLiteralExpr AtomicExpr AddrLabelExpr ParenListExpr StmtExpr ConditionalOperator BinaryConditionalOperator Repository: rL LLVM http://reviews.llvm.org/D14286 Files: lib/AST/ASTImporter.cpp Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -29,7 +29,29 @@ public DeclVisitor, public StmtVisitor { ASTImporter &Importer; - + +template +void ImportMultipleItems(IIter Ibegin, IIter Iend, OIter Obegin) { + ASTImporter &_Importer = Importer; + std::transform(Ibegin, Iend, Obegin, +[&_Importer](ItemT I) -> ItemT { + return _Importer.Import(I); +}); +} + +template +bool checkNull(IIter Ibegin, IIter Iend) { + return std::find(Ibegin, Iend, nullptr) == Iend; +} + +template +bool checkPossibleNull(IIter Ibegin, IIter Iend, OIter Obegin) { + for (; Ibegin != Iend; Ibegin++, Obegin++) +if (*Obegin == nullptr && Ibegin != nullptr) + return false; + return true; +} + public: explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { } @@ -86,6 +108,10 @@ void ImportDeclarationNameLoc(const DeclarationNameInfo &From, DeclarationNameInfo& To); void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); + +typedef DesignatedInitExpr::Designator Designator; +Designator ImportDesignator(const Designator &D); + /// \brief What we should import from the definition. enum ImportDefinitionKind { @@ -174,6 +200,7 @@ DeclGroupRef ImportDeclGroup(DeclGroupRef DG); Stmt *VisitStmt(Stmt *S); +Stmt *VisitGCCAsmStmt(GCCAsmStmt *S); Stmt *VisitDeclStmt(DeclStmt *S); Stmt *VisitNullStmt(NullStmt *S); Stmt *VisitCompoundStmt(CompoundStmt *S); @@ -191,7 +218,6 @@ Stmt *VisitContinueStmt(ContinueStmt *S); Stmt *VisitBreakStmt(BreakStmt *S); Stmt *VisitReturnStmt(ReturnStmt *S); -// FIXME: GCCAsmStmt // FIXME: MSAsmStmt // FIXME: SEHExceptStmt // FIXME: SEHFinallyStmt @@ -212,13 +238,29 @@ // Importing expressions Expr *VisitExpr(Expr *E); +Expr *VisitVAArgExpr(VAArgExpr *E); +Expr *VisitGNUNullExpr(GNUNullExpr *E); +Expr *VisitPredefinedExpr(PredefinedExpr *E); Expr *VisitDeclRefExpr(DeclRefExpr *E); +Expr *VisitInitListExpr(InitListExpr *ILE); +Expr *VisitDesignatedInitExpr(DesignatedInitExpr *E); +Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E); +Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); Expr *VisitIntegerLiteral(IntegerLiteral *E); +Expr *VisitFloatingLiteral(FloatingLiteral *E); Expr *VisitCharacterLiteral(CharacterLiteral *E); +Expr *VisitStringLiteral(StringLiteral *E); +Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E); +Expr *VisitAtomicExpr(AtomicExpr *E); +Expr *VisitAddrLabelExpr(AddrLabelExpr *E); Expr *VisitParenExpr(ParenExpr *E); +Expr *VisitParenListExpr(ParenListExpr *E); +Expr *VisitStmtExpr(StmtExpr *E); Expr *VisitUnaryOperator(UnaryOperator *E); Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); Expr *VisitBinaryOperator(BinaryOperator *E); +Expr *VisitConditionalOperator(ConditionalOperator *E); +Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E); Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); Expr *VisitCStyleCastExpr(CStyleCastExpr *E); @@ -4591,7 +4633,84 @@ << S->getStmtClassName(); return nullptr; } - + + +Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) { + SmallVector Names; + for (unsigned i = 0, e = S->getNumOutputs(); i != e; i++) { +IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(i)); +if (!ToII && S->getOutputIdentifier(i)) + return nullptr; +Names.push_back(ToII); + } + for (unsigned i = 0, e = S->getNumInputs(); i != e; i++) { +IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(i)); +if (!ToII && S->getInputIdentifier(i)) + return nullptr; +Names.push_back(ToII); + } + + SmallVector Clobbers; + for (unsigned i = 0, e = S->getNumClobbers(); i != e; i++) { +StringLiteral *Clobber = cast_or_null( + Importer.Import(S->getClobberStringLiteral(i))); +if (!Clobber) + return nullptr; +
[PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin created this revision. a.sidorin added a reviewer: sepavloff. a.sidorin added a subscriber: cfe-commits. a.sidorin set the repository for this revision to rL LLVM. This patch implements some expression-related AST node import (patch #2). Supported nodes: ArrayTypeTraitExpr ExpressionTraitExpr OpaqueValueExpr ArraySubscriptExpr ExplicitCastExpr ImplicitValueInitExpr OffsetOfExpr CXXThisExpr CXXThrowExpr CXXNoexceptExpr CXXDefaultArgExpr CXXScalarValueInitExpr CXXBindTemporaryExpr CXXTemporaryObjectExpr MaterializeTemporaryExpr Repository: rL LLVM http://reviews.llvm.org/D14326 Files: include/clang/AST/ASTImporter.h lib/AST/ASTImporter.cpp Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -109,6 +109,8 @@ DeclarationNameInfo& To); void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); +bool ImportCastPath(CastExpr *E, CXXCastPath &Path); + typedef DesignatedInitExpr::Designator Designator; Designator ImportDesignator(const Designator &D); @@ -261,9 +263,23 @@ Expr *VisitBinaryOperator(BinaryOperator *E); Expr *VisitConditionalOperator(ConditionalOperator *E); Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E); +Expr *VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E); +Expr *VisitExpressionTraitExpr(ExpressionTraitExpr *E); +Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E); +Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E); Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); -Expr *VisitCStyleCastExpr(CStyleCastExpr *E); +Expr *VisitExplicitCastExpr(ExplicitCastExpr *E); +Expr *VisitImplicitValueInitExpr(ImplicitValueInitExpr *E); +Expr *VisitOffsetOfExpr(OffsetOfExpr *E); +Expr *VisitCXXThisExpr(CXXThisExpr *E); +Expr *VisitCXXThrowExpr(CXXThrowExpr *E); +Expr *VisitCXXNoexceptExpr(CXXNoexceptExpr *E); +Expr *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); +Expr *VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); +Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); +Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE); +Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E); Expr *VisitCXXConstructExpr(CXXConstructExpr *E); Expr *VisitMemberExpr(MemberExpr *E); Expr *VisitCallExpr(CallExpr *E); @@ -5581,6 +5597,70 @@ T, E->getValueKind(), E->getObjectKind()); } +Expr *ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) +return nullptr; + + TypeSourceInfo *ToQueried = Importer.Import(E->getQueriedTypeSourceInfo()); + if (!ToQueried) +return nullptr; + + Expr *Dim = Importer.Import(E->getDimensionExpression()); + if (!Dim && E->getDimensionExpression()) +return nullptr; + + return new (Importer.getToContext()) ArrayTypeTraitExpr( +Importer.Import(E->getExprLoc()), E->getTrait(), ToQueried, +E->getValue(), Dim, Importer.Import(E->getLocEnd()), T); +} + +Expr *ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) +return nullptr; + + Expr *ToQueried = Importer.Import(E->getQueriedExpression()); + if (!ToQueried) +return nullptr; + + return new (Importer.getToContext()) ExpressionTraitExpr( +Importer.Import(E->getExprLoc()), E->getTrait(), ToQueried, +E->getValue(), Importer.Import(E->getLocEnd()), T); +} + +Expr *ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) +return nullptr; + + Expr *SourceExpr = Importer.Import(E->getSourceExpr()); + if (!SourceExpr && E->getSourceExpr()) +return nullptr; + + return new (Importer.getToContext()) OpaqueValueExpr( +Importer.Import(E->getExprLoc()), T, E->getValueKind(), +E->getObjectKind(), SourceExpr); +} + +Expr *ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) { + QualType T = Importer.Import(E->getType()); + if (T.isNull()) +return nullptr; + + Expr *ToLHS = Importer.Import(E->getLHS()); + if (!ToLHS) +return nullptr; + + Expr *ToRHS = Importer.Import(E->getRHS()); + if (!ToRHS) +return nullptr; + + return new (Importer.getToContext()) ArraySubscriptExpr( +ToLHS, ToRHS, T, E->getValueKind(), E->getObjectKind(), +Importer.Import(E->getRBracketLoc())); +} + Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { QualType T = Importer.Import(E->getType()); if (T.isNull()) @@ -5611,11 +5691,14 @@ E->isFPContractable()); } -static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) { - if (E->path_empty()) return
Re: [PATCH] D14277: [Analyzer] Make referenced SymbolMetadata live even if its region is dead
a.sidorin updated this revision to Diff 39198. a.sidorin added a comment. Thank you for you reply! This version contains more radical solution. Also, I took an another look at the CStringChecker and its way of handling checkDeadSymbols. Repository: rL LLVM http://reviews.llvm.org/D14277 Files: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h lib/StaticAnalyzer/Checkers/CStringChecker.cpp lib/StaticAnalyzer/Core/SymbolManager.cpp test/Analysis/string.c Index: test/Analysis/string.c === --- test/Analysis/string.c +++ test/Analysis/string.c @@ -414,6 +414,12 @@ clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} } +void strcat_symbolic_src_length(char *src) { + char dst[8] = "1234"; + strcat(dst, src); + clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{TRUE}} +} + void strcat_symbolic_dst_length_taint(char *dst) { scanf("%s", dst); // Taint data. strcat(dst, "1234"); @@ -520,6 +526,17 @@ clang_analyzer_eval(strlen(x) > 4); // expected-warning{{UNKNOWN}} } +void strncpy_exactly_matching_buffer2(char *y) { +if (strlen(y) >= 4) +return; + +char x[4]; +strncpy(x, y, 4); // no-warning + +// This time, we know that y fits in x anyway. + clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{TRUE}} +} + void strncpy_zero(char *src) { char dst[] = "123"; strncpy(dst, src, 0); // no-warning @@ -1079,30 +1096,3 @@ // character. For now, we just model the invalidation. clang_analyzer_eval(str[1] == 'b'); // expected-warning{{UNKNOWN}} } - -//===--=== -// FIXMEs -//===--=== - -// The analyzer_eval call below should evaluate to true. We are being too -// aggressive in marking the (length of) src symbol dead. The length of dst -// depends on src. This could be explicitely specified in the checker or the -// logic for handling MetadataSymbol in SymbolManager needs to change. -void strcat_symbolic_src_length(char *src) { - char dst[8] = "1234"; - strcat(dst, src); - clang_analyzer_eval(strlen(dst) >= 4); // expected-warning{{UNKNOWN}} -} - -// The analyzer_eval call below should evaluate to true. Most likely the same -// issue as the test above. -void strncpy_exactly_matching_buffer2(char *y) { - if (strlen(y) >= 4) - return; - - char x[4]; - strncpy(x, y, 4); // no-warning - - // This time, we know that y fits in x anyway. - clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}} -} Index: lib/StaticAnalyzer/Core/SymbolManager.cpp === --- lib/StaticAnalyzer/Core/SymbolManager.cpp +++ lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -393,11 +393,6 @@ RegionRoots.insert(region); } -void SymbolReaper::markInUse(SymbolRef sym) { - if (isa(sym)) -MetadataInUse.insert(sym); -} - bool SymbolReaper::maybeDead(SymbolRef sym) { if (isLive(sym)) return false; @@ -459,10 +454,7 @@ KnownLive = isLiveRegion(cast(sym)->getRegion()); break; case SymExpr::MetadataKind: -KnownLive = MetadataInUse.count(sym) && -isLiveRegion(cast(sym)->getRegion()); -if (KnownLive) - MetadataInUse.erase(sym); +KnownLive = isLiveRegion(cast(sym)->getRegion()); break; case SymExpr::SymIntKind: KnownLive = isLive(cast(sym)->getLHS()); Index: lib/StaticAnalyzer/Checkers/CStringChecker.cpp === --- lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -2123,28 +2123,22 @@ for (SymExpr::symbol_iterator si = Len.symbol_begin(), se = Len.symbol_end(); si != se; ++si) - SR.markInUse(*si); + SR.markLive(*si); } } void CStringChecker::checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const { - if (!SR.hasDeadSymbols()) -return; - - ProgramStateRef state = C.getState(); - CStringLengthTy Entries = state->get(); + auto state = C.getState(); + auto Entries = state->get(); if (Entries.isEmpty()) return; - CStringLengthTy::Factory &F = state->get_context(); - for (CStringLengthTy::iterator I = Entries.begin(), E = Entries.end(); - I != E; ++I) { -SVal Len = I.getData(); -if (SymbolRef Sym = Len.getAsSymbol()) { - if (SR.isDead(Sym)) -Entries = F.remove(Entries, I.getKey()); -} + auto &F = state->get_context(); + for (auto I = Entries.begin(), E = Entries.end(); I != E; ++I) { +const MemRegion *MR = I.getKey(); +if (!SR.isLiveRegion(MR)) + Entries = F.remove(Entries, MR); } state = state->set(Entries); Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
Re: [PATCH] D14277: [Analyzer] Make referenced SymbolMetadata live even if its region is dead
a.sidorin added inline comments. Comment at: lib/StaticAnalyzer/Core/SymbolManager.cpp:457 @@ -461,6 +456,3 @@ case SymExpr::MetadataKind: -KnownLive = MetadataInUse.count(sym) && -isLiveRegion(cast(sym)->getRegion()); -if (KnownLive) - MetadataInUse.erase(sym); +KnownLive = isLiveRegion(cast(sym)->getRegion()); break; Maybe we should just return false here? Repository: rL LLVM http://reviews.llvm.org/D14277 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D14286: ASTImporter: expressions, pt.1
a.sidorin marked 7 inline comments as done. a.sidorin added a comment. Thank you for your comments. I leaved some replies and will update revision. Something about lacking tests. 1. We cannot check if expression import is correct until we implement FunctionDecl body import. I was going to upstream Decl-related parts later but maybe it is better to include this small case in the first patch. What do you think? 2. What is the best way to test import of statements? Currently I have no idea how to do this (except of ast-dump). Any suggestions are welcome. Comment at: lib/AST/ASTImporter.cpp:35 @@ +34,3 @@ +void ImportMultipleItems(IIter Ibegin, IIter Iend, OIter Obegin) { + ASTImporter &_Importer = Importer; + std::transform(Ibegin, Iend, Obegin, sepavloff wrote: > A name started with underscore is a reserved identifier (see C++ standard, > [global.names]), so it is better to use something more neutral, like > //TheImporter// or //Imp// or something else. Ouch. I was just trying to unify this with the code already existing in ASTImporter. I'll rename this. // TODO: refactor std::transform usage in ASTImporter. Comment at: lib/AST/ASTImporter.cpp:48 @@ +47,3 @@ +template +bool checkPossibleNull(IIter Ibegin, IIter Iend, OIter Obegin) { + for (; Ibegin != Iend; Ibegin++, Obegin++) sepavloff wrote: > This function is used in one place only, maybe inline its body in that place? I'll use it in later patches so I'd prefer to keep it. Comment at: lib/AST/ASTImporter.cpp:4655 @@ +4654,3 @@ + for (unsigned i = 0, e = S->getNumClobbers(); i != e; i++) { +StringLiteral *Clobber = cast_or_null( + Importer.Import(S->getClobberStringLiteral(i))); sepavloff wrote: > Again, clobber cannot be null, maybe `cast` instead of `cast_or_null`? This guard is here because the return result of import may be null. This cast_or_null (and some others) handles such cases. Repository: rL LLVM http://reviews.llvm.org/D14286 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D14286: ASTImporter: expressions, pt.1
a.sidorin updated this revision to Diff 39517. a.sidorin marked an inline comment as done. a.sidorin added a comment. Some issues pointed on review were fixed. Repository: rL LLVM http://reviews.llvm.org/D14286 Files: lib/AST/ASTImporter.cpp Index: lib/AST/ASTImporter.cpp === --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -29,7 +29,16 @@ public DeclVisitor, public StmtVisitor { ASTImporter &Importer; - + +template +void ImportMultipleItems(IIter Ibegin, IIter Iend, OIter Obegin) { + ASTImporter &ImporterRef = Importer; + std::transform(Ibegin, Iend, Obegin, +[&ImporterRef](ItemT I) -> ItemT { + return ImporterRef.Import(I); +}); +} + public: explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { } @@ -86,6 +95,10 @@ void ImportDeclarationNameLoc(const DeclarationNameInfo &From, DeclarationNameInfo& To); void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false); + +typedef DesignatedInitExpr::Designator Designator; +Designator ImportDesignator(const Designator &D); + /// \brief What we should import from the definition. enum ImportDefinitionKind { @@ -174,6 +187,7 @@ DeclGroupRef ImportDeclGroup(DeclGroupRef DG); Stmt *VisitStmt(Stmt *S); +Stmt *VisitGCCAsmStmt(GCCAsmStmt *S); Stmt *VisitDeclStmt(DeclStmt *S); Stmt *VisitNullStmt(NullStmt *S); Stmt *VisitCompoundStmt(CompoundStmt *S); @@ -191,7 +205,6 @@ Stmt *VisitContinueStmt(ContinueStmt *S); Stmt *VisitBreakStmt(BreakStmt *S); Stmt *VisitReturnStmt(ReturnStmt *S); -// FIXME: GCCAsmStmt // FIXME: MSAsmStmt // FIXME: SEHExceptStmt // FIXME: SEHFinallyStmt @@ -212,13 +225,29 @@ // Importing expressions Expr *VisitExpr(Expr *E); +Expr *VisitVAArgExpr(VAArgExpr *E); +Expr *VisitGNUNullExpr(GNUNullExpr *E); +Expr *VisitPredefinedExpr(PredefinedExpr *E); Expr *VisitDeclRefExpr(DeclRefExpr *E); +Expr *VisitInitListExpr(InitListExpr *ILE); +Expr *VisitDesignatedInitExpr(DesignatedInitExpr *E); +Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E); +Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E); Expr *VisitIntegerLiteral(IntegerLiteral *E); +Expr *VisitFloatingLiteral(FloatingLiteral *E); Expr *VisitCharacterLiteral(CharacterLiteral *E); +Expr *VisitStringLiteral(StringLiteral *E); +Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E); +Expr *VisitAtomicExpr(AtomicExpr *E); +Expr *VisitAddrLabelExpr(AddrLabelExpr *E); Expr *VisitParenExpr(ParenExpr *E); +Expr *VisitParenListExpr(ParenListExpr *E); +Expr *VisitStmtExpr(StmtExpr *E); Expr *VisitUnaryOperator(UnaryOperator *E); Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E); Expr *VisitBinaryOperator(BinaryOperator *E); +Expr *VisitConditionalOperator(ConditionalOperator *E); +Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E); Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E); Expr *VisitImplicitCastExpr(ImplicitCastExpr *E); Expr *VisitCStyleCastExpr(CStyleCastExpr *E); @@ -229,6 +258,28 @@ } using namespace clang; +//-- +// Utilities +//-- + +namespace { + +template +static bool containsNullPtr(IIter Ibegin, IIter Iend) { + return std::find(Ibegin, Iend, nullptr) == Iend; +} + +template +static bool checkPossibleNull(IIter Ibegin, IIter Iend, OIter Obegin) { + for (; Ibegin != Iend; Ibegin++, Obegin++) +if (*Obegin == nullptr && Ibegin != nullptr) + return false; + return true; +} + +} // end anonymous namespace + + // // Structural Equivalence // @@ -4591,7 +4642,84 @@ << S->getStmtClassName(); return nullptr; } - + + +Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) { + SmallVector Names; + for (unsigned i = 0, e = S->getNumOutputs(); i != e; i++) { +IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(i)); +if (!ToII) + return nullptr; +Names.push_back(ToII); + } + for (unsigned i = 0, e = S->getNumInputs(); i != e; i++) { +IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(i)); +if (!ToII) + return nullptr; +Names.push_back(ToII); + } + + SmallVector Clobbers; + for (unsigned i = 0, e = S->getNumClobbers(); i != e; i++) { +StringLiteral *Clobber = cast_or_null( + Importer.Import(S->getClobberStringLiteral(i))); +if (!Clobber) +
Re: [PATCH] D5102: [analyzer][Bugfix/improvement] Fix for PR16833
a.sidorin added a comment. Gentle ping. http://reviews.llvm.org/D5102 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22374: [analyzer] Copy and move constructors - ExprEngine extended for "almost trivial" copy and move constructors
a.sidorin added a comment. Adam, It is not a debug checker. It is UndefinedAssignment checker which correctly tells us that `Inner.y` is assigned with an uninitialized value while copying. So I wonder if we are allowed to skip such warnings because these warnings don't look like false positives. As I understand, these warnings disappeared because `performTrivialCopy()` doesn't run checkers for `check::Bind`event. Not sure but maybe we should fix that? https://reviews.llvm.org/D22374 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin updated this revision to Diff 64663. a.sidorin added a comment. An attempt to fix unit test on Windows. Serge, thank you! Could you please check this patch again? https://reviews.llvm.org/D14326 Files: include/clang/AST/ASTImporter.h include/clang/AST/DeclFriend.h lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/class3.cpp test/ASTMerge/Inputs/exprs3.cpp test/ASTMerge/class2.cpp test/ASTMerge/exprs.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -456,5 +456,30 @@ } +const internal::VariadicDynCastAllOfMatcher vaArgExpr; + +/// \brief Matches the decayed type, whose original type matches \c InnerMatcher +AST_MATCHER_P(DecayedType, hasOriginalType, internal::Matcher, + InnerType) { + return InnerType.matches(Node.getOriginalType(), Finder, Builder); +} + +TEST(ImportExpr, ImportVAArgExpr) { + MatchVerifier Verifier; + EXPECT_TRUE( +testImport( + "void declToImport(__builtin_va_list list, ...) {" + " (void)__builtin_va_arg(list, int); }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl( +hasBody( + compoundStmt( +has( + cStyleCastExpr( +hasSourceExpression( + vaArgExpr(); +} + + } // end namespace ast_matchers } // end namespace clang Index: test/ASTMerge/exprs.cpp === --- /dev/null +++ test/ASTMerge/exprs.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(Ch1 == 'a'); +static_assert(Ch2 == 'b'); +static_assert(Ch3 == 'c'); + +static_assert(Ch4 == L'd'); +static_assert(Ch5 == L'e'); +static_assert(Ch6 == L'f'); + +static_assert(C1 == 12); +static_assert(C2 == 13); + +static_assert(C3 == 12); +static_assert(C4 == 13); + +static_assert(C5 == 22L); +static_assert(C6 == 23L); + +static_assert(C7 == 66LL); +static_assert(C8 == 67ULL); + +static_assert(bval1 == true); +static_assert(bval2 == false); + +static_assert(ExpressionTrait == false); + +static_assert(ArrayRank == 2); +static_assert(ArrayExtent == 20); + +void testImport(int *x, const S1 &cs1, S1 &s1) { + testNewThrowDelete(); + testArrayElement(nullptr, 12); + testTernaryOp(0, 1, 2); + testConstCast(cs1); + testStaticCast(s1); + testReinterpretCast(s1); + testDynamicCast(s1); + testScalarInit(42); + testOffsetOf(); + testDefaultArg(12); + useTemplateType(); +} Index: test/ASTMerge/class2.cpp === --- /dev/null +++ test/ASTMerge/class2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class C3 { + int method_1(C2 *x) { +return x->x; + } +}; Index: test/ASTMerge/Inputs/exprs3.cpp === --- /dev/null +++ test/ASTMerge/Inputs/exprs3.cpp @@ -0,0 +1,131 @@ +// Integer literals +const char Ch1 = 'a'; +const signed char Ch2 = 'b'; +const unsigned char Ch3 = 'c'; + +const wchar_t Ch4 = L'd'; +const signed wchar_t Ch5 = L'e'; +const unsigned wchar_t Ch6 = L'f'; + +const short C1 = 12; +const unsigned short C2 = 13; + +const int C3 = 12; +const unsigned int C4 = 13; + +const long C5 = 22; +const unsigned long C6 = 23; + +const long long C7 = 66; +const unsigned long long C8 = 67; + + +// String literals +const char str1[] = "ABCD"; +const char str2[] = "ABCD" "0123"; + +const wchar_t wstr1[] = L"DEF"; +const wchar_t wstr2[] = L"DEF" L"123"; + + +// Boolean literals +const bool bval1 = true; +const bool bval2 = false; + +// Floating Literals +const float F1 = 12.2F; +const double F2 = 1E4; +const long double F3 = 1.2E-3L; + + +// nullptr literal +const void *vptr = nullptr; + + +int glb_1[4] = { 10, 20, 30, 40 }; + +struct S1 { + int a; + int b[3]; +}; + +struct S2 { + int c; + S1 d; +}; + +S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 }; + +void testNewThrowDelete() { + throw; + char *p = new char[10]; + delete[] p; +} + +int testArrayElement(int *x, int n) { + return x[n]; +} + +int testTernaryOp(int c, int x, int y) { + return c ? x : y; +} + +S1 &testConstCast(const S1 &x) { + return const_cast(x); +} + +S1 &testStaticCast(S1 &x) { + return static_cast(x); +} + +S1 &testReinterpretCast(S1 &x) { + return reinterpret_cast(x); +} + +S1 &testDynamicCast(S1 &x) { + return dynamic_cast(x); +} + +int testScalarInit(int
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin updated this revision to Diff 64676. a.sidorin added a comment. Removed unneeded matcher. https://reviews.llvm.org/D14326 Files: include/clang/AST/ASTImporter.h include/clang/AST/DeclFriend.h lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/class3.cpp test/ASTMerge/Inputs/exprs3.cpp test/ASTMerge/class2.cpp test/ASTMerge/exprs.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -456,5 +456,24 @@ } +const internal::VariadicDynCastAllOfMatcher vaArgExpr; + +TEST(ImportExpr, ImportVAArgExpr) { + MatchVerifier Verifier; + EXPECT_TRUE( +testImport( + "void declToImport(__builtin_va_list list, ...) {" + " (void)__builtin_va_arg(list, int); }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl( +hasBody( + compoundStmt( +has( + cStyleCastExpr( +hasSourceExpression( + vaArgExpr(); +} + + } // end namespace ast_matchers } // end namespace clang Index: test/ASTMerge/exprs.cpp === --- /dev/null +++ test/ASTMerge/exprs.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(Ch1 == 'a'); +static_assert(Ch2 == 'b'); +static_assert(Ch3 == 'c'); + +static_assert(Ch4 == L'd'); +static_assert(Ch5 == L'e'); +static_assert(Ch6 == L'f'); + +static_assert(C1 == 12); +static_assert(C2 == 13); + +static_assert(C3 == 12); +static_assert(C4 == 13); + +static_assert(C5 == 22L); +static_assert(C6 == 23L); + +static_assert(C7 == 66LL); +static_assert(C8 == 67ULL); + +static_assert(bval1 == true); +static_assert(bval2 == false); + +static_assert(ExpressionTrait == false); + +static_assert(ArrayRank == 2); +static_assert(ArrayExtent == 20); + +void testImport(int *x, const S1 &cs1, S1 &s1) { + testNewThrowDelete(); + testArrayElement(nullptr, 12); + testTernaryOp(0, 1, 2); + testConstCast(cs1); + testStaticCast(s1); + testReinterpretCast(s1); + testDynamicCast(s1); + testScalarInit(42); + testOffsetOf(); + testDefaultArg(12); + useTemplateType(); +} Index: test/ASTMerge/class2.cpp === --- /dev/null +++ test/ASTMerge/class2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class C3 { + int method_1(C2 *x) { +return x->x; + } +}; Index: test/ASTMerge/Inputs/exprs3.cpp === --- /dev/null +++ test/ASTMerge/Inputs/exprs3.cpp @@ -0,0 +1,131 @@ +// Integer literals +const char Ch1 = 'a'; +const signed char Ch2 = 'b'; +const unsigned char Ch3 = 'c'; + +const wchar_t Ch4 = L'd'; +const signed wchar_t Ch5 = L'e'; +const unsigned wchar_t Ch6 = L'f'; + +const short C1 = 12; +const unsigned short C2 = 13; + +const int C3 = 12; +const unsigned int C4 = 13; + +const long C5 = 22; +const unsigned long C6 = 23; + +const long long C7 = 66; +const unsigned long long C8 = 67; + + +// String literals +const char str1[] = "ABCD"; +const char str2[] = "ABCD" "0123"; + +const wchar_t wstr1[] = L"DEF"; +const wchar_t wstr2[] = L"DEF" L"123"; + + +// Boolean literals +const bool bval1 = true; +const bool bval2 = false; + +// Floating Literals +const float F1 = 12.2F; +const double F2 = 1E4; +const long double F3 = 1.2E-3L; + + +// nullptr literal +const void *vptr = nullptr; + + +int glb_1[4] = { 10, 20, 30, 40 }; + +struct S1 { + int a; + int b[3]; +}; + +struct S2 { + int c; + S1 d; +}; + +S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 }; + +void testNewThrowDelete() { + throw; + char *p = new char[10]; + delete[] p; +} + +int testArrayElement(int *x, int n) { + return x[n]; +} + +int testTernaryOp(int c, int x, int y) { + return c ? x : y; +} + +S1 &testConstCast(const S1 &x) { + return const_cast(x); +} + +S1 &testStaticCast(S1 &x) { + return static_cast(x); +} + +S1 &testReinterpretCast(S1 &x) { + return reinterpret_cast(x); +} + +S1 &testDynamicCast(S1 &x) { + return dynamic_cast(x); +} + +int testScalarInit(int x) { + return int(x); +} + +struct S { + float f; + double d; +}; +struct T { + int i; + struct S s[10]; +}; + +void testOffsetOf() { + __builtin_offsetof(struct T, s[2].d); +} + + +unsigned char asmFunc(unsigned char a, unsigned char b) { + unsigned int la = a; + unsigned int lb = b; + unsigned int bigres; +
Re: [PATCH] D14326: ASTImporter: expressions, pt.2
a.sidorin updated this revision to Diff 64704. a.sidorin added a comment. Fix signed/unsigned mismatch warning in the loop condition. https://reviews.llvm.org/D14326 Files: include/clang/AST/ASTImporter.h include/clang/AST/DeclFriend.h lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/class3.cpp test/ASTMerge/Inputs/exprs3.cpp test/ASTMerge/class2.cpp test/ASTMerge/exprs.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp === --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -456,5 +456,24 @@ } +const internal::VariadicDynCastAllOfMatcher vaArgExpr; + +TEST(ImportExpr, ImportVAArgExpr) { + MatchVerifier Verifier; + EXPECT_TRUE( +testImport( + "void declToImport(__builtin_va_list list, ...) {" + " (void)__builtin_va_arg(list, int); }", + Lang_CXX, "", Lang_CXX, Verifier, + functionDecl( +hasBody( + compoundStmt( +has( + cStyleCastExpr( +hasSourceExpression( + vaArgExpr(); +} + + } // end namespace ast_matchers } // end namespace clang Index: test/ASTMerge/exprs.cpp === --- /dev/null +++ test/ASTMerge/exprs.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -emit-pch -o %t.1.ast %S/Inputs/exprs3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -fcxx-exceptions -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +static_assert(Ch1 == 'a'); +static_assert(Ch2 == 'b'); +static_assert(Ch3 == 'c'); + +static_assert(Ch4 == L'd'); +static_assert(Ch5 == L'e'); +static_assert(Ch6 == L'f'); + +static_assert(C1 == 12); +static_assert(C2 == 13); + +static_assert(C3 == 12); +static_assert(C4 == 13); + +static_assert(C5 == 22L); +static_assert(C6 == 23L); + +static_assert(C7 == 66LL); +static_assert(C8 == 67ULL); + +static_assert(bval1 == true); +static_assert(bval2 == false); + +static_assert(ExpressionTrait == false); + +static_assert(ArrayRank == 2); +static_assert(ArrayExtent == 20); + +void testImport(int *x, const S1 &cs1, S1 &s1) { + testNewThrowDelete(); + testArrayElement(nullptr, 12); + testTernaryOp(0, 1, 2); + testConstCast(cs1); + testStaticCast(s1); + testReinterpretCast(s1); + testDynamicCast(s1); + testScalarInit(42); + testOffsetOf(); + testDefaultArg(12); + useTemplateType(); +} Index: test/ASTMerge/class2.cpp === --- /dev/null +++ test/ASTMerge/class2.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -emit-pch -o %t.1.ast %S/Inputs/class3.cpp +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++1z -ast-merge %t.1.ast -fsyntax-only -verify %s +// expected-no-diagnostics + +class C3 { + int method_1(C2 *x) { +return x->x; + } +}; Index: test/ASTMerge/Inputs/exprs3.cpp === --- /dev/null +++ test/ASTMerge/Inputs/exprs3.cpp @@ -0,0 +1,131 @@ +// Integer literals +const char Ch1 = 'a'; +const signed char Ch2 = 'b'; +const unsigned char Ch3 = 'c'; + +const wchar_t Ch4 = L'd'; +const signed wchar_t Ch5 = L'e'; +const unsigned wchar_t Ch6 = L'f'; + +const short C1 = 12; +const unsigned short C2 = 13; + +const int C3 = 12; +const unsigned int C4 = 13; + +const long C5 = 22; +const unsigned long C6 = 23; + +const long long C7 = 66; +const unsigned long long C8 = 67; + + +// String literals +const char str1[] = "ABCD"; +const char str2[] = "ABCD" "0123"; + +const wchar_t wstr1[] = L"DEF"; +const wchar_t wstr2[] = L"DEF" L"123"; + + +// Boolean literals +const bool bval1 = true; +const bool bval2 = false; + +// Floating Literals +const float F1 = 12.2F; +const double F2 = 1E4; +const long double F3 = 1.2E-3L; + + +// nullptr literal +const void *vptr = nullptr; + + +int glb_1[4] = { 10, 20, 30, 40 }; + +struct S1 { + int a; + int b[3]; +}; + +struct S2 { + int c; + S1 d; +}; + +S2 glb_2 = { 22, .d.a = 44, .d.b[0] = 55, .d.b[1] = 66 }; + +void testNewThrowDelete() { + throw; + char *p = new char[10]; + delete[] p; +} + +int testArrayElement(int *x, int n) { + return x[n]; +} + +int testTernaryOp(int c, int x, int y) { + return c ? x : y; +} + +S1 &testConstCast(const S1 &x) { + return const_cast(x); +} + +S1 &testStaticCast(S1 &x) { + return static_cast(x); +} + +S1 &testReinterpretCast(S1 &x) { + return reinterpret_cast(x); +} + +S1 &testDynamicCast(S1 &x) { + return dynamic_cast(x); +} + +int testScalarInit(int x) { + return int(x); +} + +struct S { + float f; + double d; +}; +struct T { + int i; + struct S s[10]; +}; + +void testOffsetOf() { + __builtin_offsetof(struct T, s[2].d); +} + + +unsigned char asmFunc(unsigned char a, unsigned char b) { + unsigned int la = a; + unsigned int l
Re: [PATCH] D23272: [analyzer][Rewrite] Fix boxes and shadows in HTML rewrites in Firefox.
a.sidorin added inline comments. Comment at: lib/Rewrite/HTMLRewrite.cpp:304 @@ -303,2 +303,3 @@ + " border-radius:5px; box-shadow:1px 1px 7px #000; " " -webkit-border-radius:5px; -webkit-box-shadow:1px 1px 7px #000; " "position: absolute; top: -1em; left:10em; z-index: 1 } \n" Should we remove '-webkit'-prefixed options as well? AFAIR, non-prefixed options should be supported by Webkit. Could you check with Chrome/Safari? https://reviews.llvm.org/D23272 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D16804: [analyzer] AnalysisConsumer: print fully-qualified function name while displaying progress
a.sidorin created this revision. a.sidorin added reviewers: xazax.hun, zaks.anna, dcoughlin. a.sidorin added a subscriber: cfe-commits. -analyzer-display progress option prints only function names which may be suspicious. This patch forces AnalysisConsumer to print fully-qualified function names. http://reviews.llvm.org/D16804 Files: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp test/Analysis/analyze_display_progress.c test/Analysis/analyze_display_progress.cpp Index: test/Analysis/analyze_display_progress.cpp === --- /dev/null +++ test/Analysis/analyze_display_progress.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s + +void f() {}; +void g() {}; +void h() {} + +struct SomeStruct { + void f() {} +}; + +struct SomeOtherStruct { + void f() {} +}; + +namespace ns { + struct SomeStruct { +void f() {} + }; +} + +// CHECK: analyze_display_progress.cpp f +// CHECK: analyze_display_progress.cpp g +// CHECK: analyze_display_progress.cpp h +// CHECK: analyze_display_progress.cpp SomeStruct::f +// CHECK: analyze_display_progress.cpp SomeOtherStruct::f +// CHECK: analyze_display_progress.cpp ns::SomeStruct::f Index: test/Analysis/analyze_display_progress.c === --- test/Analysis/analyze_display_progress.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s - -void f() {}; -void g() {}; -void h() {} - -// CHECK: analyze_display_progress.c f -// CHECK: analyze_display_progress.c g -// CHECK: analyze_display_progress.c h \ No newline at end of file Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -286,7 +286,7 @@ llvm::errs() << ": " << Loc.getFilename(); if (isa(D) || isa(D)) { const NamedDecl *ND = cast(D); -llvm::errs() << ' ' << *ND << '\n'; +llvm::errs() << ' ' << ND->getQualifiedNameAsString() << '\n'; } else if (isa(D)) { llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:" Index: test/Analysis/analyze_display_progress.cpp === --- /dev/null +++ test/Analysis/analyze_display_progress.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s + +void f() {}; +void g() {}; +void h() {} + +struct SomeStruct { + void f() {} +}; + +struct SomeOtherStruct { + void f() {} +}; + +namespace ns { + struct SomeStruct { +void f() {} + }; +} + +// CHECK: analyze_display_progress.cpp f +// CHECK: analyze_display_progress.cpp g +// CHECK: analyze_display_progress.cpp h +// CHECK: analyze_display_progress.cpp SomeStruct::f +// CHECK: analyze_display_progress.cpp SomeOtherStruct::f +// CHECK: analyze_display_progress.cpp ns::SomeStruct::f Index: test/Analysis/analyze_display_progress.c === --- test/Analysis/analyze_display_progress.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s - -void f() {}; -void g() {}; -void h() {} - -// CHECK: analyze_display_progress.c f -// CHECK: analyze_display_progress.c g -// CHECK: analyze_display_progress.c h \ No newline at end of file Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp === --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -286,7 +286,7 @@ llvm::errs() << ": " << Loc.getFilename(); if (isa(D) || isa(D)) { const NamedDecl *ND = cast(D); -llvm::errs() << ' ' << *ND << '\n'; +llvm::errs() << ' ' << ND->getQualifiedNameAsString() << '\n'; } else if (isa(D)) { llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:" ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D16873: Refactor MemRegionManager::getVarRegion to call two new functions, improving readability
a.sidorin added a subscriber: a.sidorin. a.sidorin added a comment. Thanks ariccio! Some inline comments are below. Comment at: llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h:1186 @@ +1185,3 @@ + /// associated with a specified globally stored, non-static local, VarDecl. + const MemRegion *getMemRegionGloballyStored(const VarDecl *D); + How about make these helper functions return `const MemSpaceRegion *` to make their signatures more meaningful? Comment at: llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp:769 @@ -768,4 +768,3 @@ -const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, -const LocationContext *LC) { - const MemRegion *sReg = nullptr; +const MemRegion* MemRegionManager::getMemRegionGloballyStored(const VarDecl *D) { + assert(D->hasGlobalStorage()); `get[Global/StaticLocal]MemSpaceForVariable`? Comment at: llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp:843 @@ +842,3 @@ +const LocationContext *LC) { + const MemRegion *sReg = nullptr; + `const MemSpaceRegion *StorageSpace?` http://reviews.llvm.org/D16873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D16873: Refactor MemRegionManager::getVarRegion to call two new functions, improving readability
a.sidorin added inline comments. Comment at: llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h:1186 @@ +1185,3 @@ + /// associated with a specified globally stored, non-static local, VarDecl. + const MemRegion *getMemRegionGloballyStored(const VarDecl *D); + ariccio wrote: > a.sidorin wrote: > > How about make these helper functions return `const MemSpaceRegion *` to > > make their signatures more meaningful? > Would that change their behavior functionally? No, it will not change it. You will need to change `static_cast` type to `const MemSpaceRegion *`, however (lines 809-810). There is `const MemSpaceRegion *` and its children classes everywhere in return statements already. Comment at: llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp:843 @@ +842,3 @@ +const LocationContext *LC) { + const MemRegion *sReg = nullptr; + ariccio wrote: > a.sidorin wrote: > > `const MemSpaceRegion *StorageSpace?` > Same question as above: Would that change their behavior functionally? > > > (if not, then I'll happily change it) No, this will not. http://reviews.llvm.org/D16873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D16873: Refactor MemRegionManager::getVarRegion to call two new functions, improving readability
a.sidorin added inline comments. Comment at: llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp:800 @@ -803,1 +799,3 @@ + if (V.is()) +return V.get(); Oops. Lines above should stay in the caller function or be refactored. Otherwise, we'll get the subregion of `V.gethttp://reviews.llvm.org/D16873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D16873: Refactor MemRegionManager::getVarRegion to call two new functions, improving readability
a.sidorin added inline comments. Comment at: llvm/tools/clang/lib/StaticAnalyzer/Core/MemRegion.cpp:792 @@ +791,3 @@ + +const MemRegion* MemRegionManager::getMemSpaceForLocalVariable(const VarDecl *D, llvm::PointerUnion &V) { + const StackFrameContext *STC = V.get(); That needs to be formatted. Also, you may pass `const StackFrameContext *` instead of `PointerUnion` (as Devin pointed) because it is only used once to get SFC. And I still think that making these function return `const MemSpaceRegion *` is a good idea. http://reviews.llvm.org/D16873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D16873: Refactor MemRegionManager::getVarRegion to call two new functions, improving readability
a.sidorin added a comment. Hello Alexander, Yes, types in `static_cast` should be changed. So, you need only to change return type and types in static_cast, and it should work. http://reviews.llvm.org/D16873 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D17376: dump_ast_matchers.py: fix replacement regexps
a.sidorin created this revision. a.sidorin added reviewers: klimek, aaron.ballman. a.sidorin added a subscriber: cfe-commits. a.sidorin set the repository for this revision to rL LLVM. Using re.sub() to replace a sample with '%'s looks strange and causes a format string error if a matcher description contains "%s". This patch resolves this issue. Repository: rL LLVM http://reviews.llvm.org/D17376 Files: docs/tools/dump_ast_matchers.py Index: docs/tools/dump_ast_matchers.py === --- docs/tools/dump_ast_matchers.py +++ docs/tools/dump_ast_matchers.py @@ -363,11 +363,11 @@ reference = open('../LibASTMatchersReference.html').read() reference = re.sub(r'', - '%s', reference, flags=re.S) % node_matcher_table + node_matcher_table, reference, flags=re.S) reference = re.sub(r'', - '%s', reference, flags=re.S) % narrowing_matcher_table + narrowing_matcher_table, reference, flags=re.S) reference = re.sub(r'', - '%s', reference, flags=re.S) % traversal_matcher_table + traversal_matcher_table, reference, flags=re.S) with open('../LibASTMatchersReference.html', 'wb') as output: output.write(reference) Index: docs/tools/dump_ast_matchers.py === --- docs/tools/dump_ast_matchers.py +++ docs/tools/dump_ast_matchers.py @@ -363,11 +363,11 @@ reference = open('../LibASTMatchersReference.html').read() reference = re.sub(r'', - '%s', reference, flags=re.S) % node_matcher_table + node_matcher_table, reference, flags=re.S) reference = re.sub(r'', - '%s', reference, flags=re.S) % narrowing_matcher_table + narrowing_matcher_table, reference, flags=re.S) reference = re.sub(r'', - '%s', reference, flags=re.S) % traversal_matcher_table + traversal_matcher_table, reference, flags=re.S) with open('../LibASTMatchersReference.html', 'wb') as output: output.write(reference) ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D17446: ASTMatchers: add new statement/decl matchers
a.sidorin created this revision. a.sidorin added a reviewer: aaron.ballman. a.sidorin added a subscriber: cfe-commits. a.sidorin set the repository for this revision to rL LLVM. Herald added a subscriber: klimek. Added matchers: addrLabelExpr atomicExpr binaryConditionalOperator designatedInitExpr designatorCountIs hasSyntacticForm implicitValueInitExpr labelDecl opaqueValueExpr parenListExpr predefinedExpr requiresZeroInitialization stmtExpr Enable ConditionOperator-related matchers for BinaryConditionalOperator also Enable hasSourceExpression() for OpaqueValueExpr Repository: rL LLVM http://reviews.llvm.org/D17446 Files: docs/LibASTMatchersReference.html include/clang/ASTMatchers/ASTMatchers.h include/clang/ASTMatchers/ASTMatchersInternal.h lib/ASTMatchers/Dynamic/Registry.cpp unittests/AST/MatchVerifier.h unittests/ASTMatchers/ASTMatchersTest.cpp unittests/ASTMatchers/ASTMatchersTest.h Index: unittests/ASTMatchers/ASTMatchersTest.h === --- unittests/ASTMatchers/ASTMatchersTest.h +++ unittests/ASTMatchers/ASTMatchersTest.h @@ -126,6 +126,13 @@ } template +testing::AssertionResult matchesC99(const std::string &Code, +const T &AMatcher) { + return matchesConditionally(Code, AMatcher, true, "-std=c99", + FileContentMappings(), "input.c"); +} + +template testing::AssertionResult notMatchesC(const std::string &Code, const T &AMatcher) { return matchesConditionally(Code, AMatcher, false, "", FileContentMappings(), Index: unittests/ASTMatchers/ASTMatchersTest.cpp === --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1209,7 +1209,12 @@ EXPECT_TRUE(matches("void f() { while(true) { continue; } }", continueStmt())); EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", gotoStmt())); - EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", labelStmt())); + EXPECT_TRUE(matches("void f() { goto FOO; FOO: ;}", + labelStmt( +hasDeclaration( + labelDecl(hasName("FOO")); + EXPECT_TRUE(matches("void f() { FOO: ; void *ptr = &&FOO; goto *ptr; }", + addrLabelExpr())); EXPECT_TRUE(matches("void f() { return; }", returnStmt())); } @@ -2522,6 +2527,82 @@ EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr())); } +TEST(Matcher, AtomicExpr) { + EXPECT_TRUE(matches("void foo() { int *ptr; __atomic_load_n(ptr, 1); }", + atomicExpr())); +} + +TEST(Matcher, Initializers) { + const char *ToMatch = "void foo() { struct point { double x; double y; };" +" struct point ptarray[10] = " +" { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; }"; + EXPECT_TRUE(matchesConditionally( +ToMatch, +initListExpr( + has( +cxxConstructExpr( + requiresZeroInitialization())), + has( +initListExpr( + hasType(asString("struct point")), + has(floatLiteral(equals(1.0))), + has(implicitValueInitExpr( +hasType(asString("double")), + has( +initListExpr( + hasType(asString("struct point")), + has(floatLiteral(equals(2.0))), + has(floatLiteral(equals(1.0) +), true, "-std=gnu++98")); + + EXPECT_TRUE(matchesC99(ToMatch, + initListExpr( + hasSyntacticForm( + initListExpr( + has( + designatedInitExpr( + designatorCountIs(2), + has(floatLiteral( + equals(1.0))), + has(integerLiteral( + equals(2), + has( + designatedInitExpr( + designatorCountIs(2), + has(floatLiteral( + equals(2.0))), + has(integerLiteral( + equals(2), + has( + designatedInitExpr( + designatorCountIs(2), + has(floatLiteral( + equals(1.0))), + has(integerLiteral( +
Re: [PATCH] D14286: ASTImporter: expressions, pt.1
a.sidorin updated the summary for this revision. a.sidorin set the repository for this revision to rL LLVM. a.sidorin updated this revision to Diff 48487. a.sidorin added a comment. Herald added a subscriber: aemerson. Add AST matcher-based unit tests; add some additional nodes to pass the tests. Repository: rL LLVM http://reviews.llvm.org/D14286 Files: include/clang/AST/Type.h lib/AST/ASTImporter.cpp unittests/AST/ASTImporterTest.cpp unittests/AST/CMakeLists.txt unittests/AST/MatchVerifier.h Index: unittests/AST/MatchVerifier.h === --- unittests/AST/MatchVerifier.h +++ unittests/AST/MatchVerifier.h @@ -62,6 +62,9 @@ std::vector& Args, Language L); + template + testing::AssertionResult match(const Decl *D, const MatcherType &AMatcher); + protected: void run(const MatchFinder::MatchResult &Result) override; virtual void verify(const MatchFinder::MatchResult &Result, @@ -127,6 +130,22 @@ return testing::AssertionSuccess(); } +/// \brief Runs a matcher over some AST, and returns the result of the +/// verifier for the matched node. +template template +testing::AssertionResult MatchVerifier::match( +const Decl *D, const MatcherType &AMatcher) { + MatchFinder Finder; + Finder.addMatcher(AMatcher.bind(""), this); + + setFailure("Could not find match"); + Finder.match(*D, D->getASTContext()); + + if (!Verified) +return testing::AssertionFailure() << VerifyResult; + return testing::AssertionSuccess(); +} + template void MatchVerifier::run(const MatchFinder::MatchResult &Result) { const NodeType *Node = Result.Nodes.getNodeAs(""); Index: unittests/AST/CMakeLists.txt === --- unittests/AST/CMakeLists.txt +++ unittests/AST/CMakeLists.txt @@ -4,6 +4,7 @@ add_clang_unittest(ASTTests ASTContextParentMapTest.cpp + ASTImporterTest.cpp ASTTypeTraitsTest.cpp ASTVectorTest.cpp CommentLexer.cpp Index: unittests/AST/ASTImporterTest.cpp === --- /dev/null +++ unittests/AST/ASTImporterTest.cpp @@ -0,0 +1,461 @@ +//===- unittest/AST/ASTImporterTest.cpp - AST node import test ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// Tests for the correct import of AST nodes from one AST context to another. +// +//===--===// + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTImporter.h" +#include "MatchVerifier.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Tooling/Tooling.h" +#include "gtest/gtest.h" + +namespace clang { +namespace ast_matchers { + +using clang::tooling::newFrontendActionFactory; +using clang::tooling::runToolOnCodeWithArgs; +using clang::tooling::FrontendActionFactory; + +typedef std::vector StringVector; + +void getLangArgs(Language Lang, StringVector &Args) { + switch (Lang) { + case Lang_C: +Args.insert(Args.end(), { "-x", "c", "-std=c99" }); +break; + case Lang_C89: +Args.insert(Args.end(), { "-x", "c", "-std=c89" }); +break; + case Lang_CXX: +Args.push_back("-std=c++98"); +break; + case Lang_CXX11: +Args.push_back("-std=c++11"); +break; + case Lang_OpenCL: + case Lang_OBJCXX: +break; + } +} + +template +testing::AssertionResult +testImport(const std::string &FromCode, Language FromLang, + const std::string &ToCode, Language ToLang, + MatchVerifier &Verifier, + const MatcherType &AMatcher) { + StringVector FromArgs, ToArgs; + getLangArgs(FromLang, FromArgs); + getLangArgs(ToLang, ToArgs); + + const char * const InputFileName = "input.cc"; + const char * const OutputFileName = "output.cc"; + + std::unique_ptr + FromAST = tooling::buildASTFromCodeWithArgs( +FromCode, FromArgs, InputFileName), + ToAST = tooling::buildASTFromCodeWithArgs(ToCode, ToArgs, OutputFileName); + + ASTContext &FromCtx = FromAST->getASTContext(), + &ToCtx = ToAST->getASTContext(); + + // Add input.cc to virtual file system so importer can 'find' it + // while importing SourceLocations. + vfs::OverlayFileSystem *OFS = static_cast( +ToCtx.getSourceManager().getFileManager().getVirtualFileSystem().get()); + vfs::InMemoryFileSystem *MFS = static_cast( +OFS->overlays_begin()->get()); + MFS->addFile(InputFileName, 0, + llvm::MemoryBuffer::getMemBuffer(FromCode.c_str())); + + ASTImporter Importer(ToCtx, ToAST->getFileManager(), + FromCtx, FromAST->getFileManager(), false); + + IdentifierInf