This revision was automatically updated to reflect the committed changes. Closed by commit rGea201e83e292: [AST][ObjC] Fix crash when printing invalid objc categories (authored by dgoldman).
Changed prior to commit: https://reviews.llvm.org/D83513?vs=276841&id=277126#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D83513/new/ https://reviews.llvm.org/D83513 Files: clang/lib/AST/DeclPrinter.cpp clang/unittests/AST/DeclPrinterTest.cpp Index: clang/unittests/AST/DeclPrinterTest.cpp =================================================================== --- clang/unittests/AST/DeclPrinterTest.cpp +++ clang/unittests/AST/DeclPrinterTest.cpp @@ -76,14 +76,16 @@ PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args, const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted, StringRef FileName, - PrintingPolicyModifier PolicyModifier = nullptr) { + PrintingPolicyModifier PolicyModifier = nullptr, + bool AllowError = false) { PrintMatch Printer(PolicyModifier); MatchFinder Finder; Finder.addMatcher(NodeMatch, &Printer); std::unique_ptr<FrontendActionFactory> Factory( newFrontendActionFactory(&Finder)); - if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName)) + if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName) && + !AllowError) return testing::AssertionFailure() << "Parsing error in \"" << Code.str() << "\""; @@ -170,16 +172,12 @@ "input.cc"); } -::testing::AssertionResult PrintedDeclObjCMatches( - StringRef Code, - const DeclarationMatcher &NodeMatch, - StringRef ExpectedPrinted) { +::testing::AssertionResult +PrintedDeclObjCMatches(StringRef Code, const DeclarationMatcher &NodeMatch, + StringRef ExpectedPrinted, bool AllowError = false) { std::vector<std::string> Args(1, ""); - return PrintedDeclMatches(Code, - Args, - NodeMatch, - ExpectedPrinted, - "input.m"); + return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.m", + /*PolicyModifier=*/nullptr, AllowError); } } // unnamed namespace @@ -1321,3 +1319,17 @@ namedDecl(hasName("P1")).bind("id"), "@protocol P1<P2>\n@end")); } + +TEST(DeclPrinter, TestObjCCategoryInvalidInterface) { + ASSERT_TRUE(PrintedDeclObjCMatches( + "@interface I (Extension) @end", + namedDecl(hasName("Extension")).bind("id"), + "@interface <<error-type>>(Extension)\n@end", /*AllowError=*/true)); +} + +TEST(DeclPrinter, TestObjCCategoryImplInvalidInterface) { + ASSERT_TRUE(PrintedDeclObjCMatches( + "@implementation I (Extension) @end", + namedDecl(hasName("Extension")).bind("id"), + "@implementation <<error-type>>(Extension)\n@end", /*AllowError=*/true)); +} Index: clang/lib/AST/DeclPrinter.cpp =================================================================== --- clang/lib/AST/DeclPrinter.cpp +++ clang/lib/AST/DeclPrinter.cpp @@ -1374,7 +1374,12 @@ } void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { - Out << "@implementation " << *PID->getClassInterface() << '(' << *PID <<")\n"; + Out << "@implementation "; + if (const auto *CID = PID->getClassInterface()) + Out << *CID; + else + Out << "<<error-type>>"; + Out << '(' << *PID << ")\n"; VisitDeclContext(PID, false); Out << "@end"; @@ -1382,7 +1387,11 @@ } void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { - Out << "@interface " << *PID->getClassInterface(); + Out << "@interface "; + if (const auto *CID = PID->getClassInterface()) + Out << *CID; + else + Out << "<<error-type>>"; if (auto TypeParams = PID->getTypeParamList()) { PrintObjCTypeParams(TypeParams); }
Index: clang/unittests/AST/DeclPrinterTest.cpp =================================================================== --- clang/unittests/AST/DeclPrinterTest.cpp +++ clang/unittests/AST/DeclPrinterTest.cpp @@ -76,14 +76,16 @@ PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args, const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted, StringRef FileName, - PrintingPolicyModifier PolicyModifier = nullptr) { + PrintingPolicyModifier PolicyModifier = nullptr, + bool AllowError = false) { PrintMatch Printer(PolicyModifier); MatchFinder Finder; Finder.addMatcher(NodeMatch, &Printer); std::unique_ptr<FrontendActionFactory> Factory( newFrontendActionFactory(&Finder)); - if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName)) + if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName) && + !AllowError) return testing::AssertionFailure() << "Parsing error in \"" << Code.str() << "\""; @@ -170,16 +172,12 @@ "input.cc"); } -::testing::AssertionResult PrintedDeclObjCMatches( - StringRef Code, - const DeclarationMatcher &NodeMatch, - StringRef ExpectedPrinted) { +::testing::AssertionResult +PrintedDeclObjCMatches(StringRef Code, const DeclarationMatcher &NodeMatch, + StringRef ExpectedPrinted, bool AllowError = false) { std::vector<std::string> Args(1, ""); - return PrintedDeclMatches(Code, - Args, - NodeMatch, - ExpectedPrinted, - "input.m"); + return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.m", + /*PolicyModifier=*/nullptr, AllowError); } } // unnamed namespace @@ -1321,3 +1319,17 @@ namedDecl(hasName("P1")).bind("id"), "@protocol P1<P2>\n@end")); } + +TEST(DeclPrinter, TestObjCCategoryInvalidInterface) { + ASSERT_TRUE(PrintedDeclObjCMatches( + "@interface I (Extension) @end", + namedDecl(hasName("Extension")).bind("id"), + "@interface <<error-type>>(Extension)\n@end", /*AllowError=*/true)); +} + +TEST(DeclPrinter, TestObjCCategoryImplInvalidInterface) { + ASSERT_TRUE(PrintedDeclObjCMatches( + "@implementation I (Extension) @end", + namedDecl(hasName("Extension")).bind("id"), + "@implementation <<error-type>>(Extension)\n@end", /*AllowError=*/true)); +} Index: clang/lib/AST/DeclPrinter.cpp =================================================================== --- clang/lib/AST/DeclPrinter.cpp +++ clang/lib/AST/DeclPrinter.cpp @@ -1374,7 +1374,12 @@ } void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { - Out << "@implementation " << *PID->getClassInterface() << '(' << *PID <<")\n"; + Out << "@implementation "; + if (const auto *CID = PID->getClassInterface()) + Out << *CID; + else + Out << "<<error-type>>"; + Out << '(' << *PID << ")\n"; VisitDeclContext(PID, false); Out << "@end"; @@ -1382,7 +1387,11 @@ } void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { - Out << "@interface " << *PID->getClassInterface(); + Out << "@interface "; + if (const auto *CID = PID->getClassInterface()) + Out << *CID; + else + Out << "<<error-type>>"; if (auto TypeParams = PID->getTypeParamList()) { PrintObjCTypeParams(TypeParams); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits