forked from OSchip/llvm-project
[AST][ObjC] Fix crash when printing invalid objc categories
Summary: If no valid interface definition was found previously we would crash. With this change instead we just print `<<error-type>>` in place of the NULL interface. In the future this could be improved by saving the invalid interface's name and using that. Reviewers: sammccall, gribozavr Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D83513
This commit is contained in:
parent
9bf6354301
commit
ea201e83e2
|
@ -1374,7 +1374,12 @@ void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
|
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);
|
VisitDeclContext(PID, false);
|
||||||
Out << "@end";
|
Out << "@end";
|
||||||
|
@ -1382,7 +1387,11 @@ void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
|
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()) {
|
if (auto TypeParams = PID->getTypeParamList()) {
|
||||||
PrintObjCTypeParams(TypeParams);
|
PrintObjCTypeParams(TypeParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,14 +76,16 @@ public:
|
||||||
PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
|
PrintedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
|
||||||
const DeclarationMatcher &NodeMatch,
|
const DeclarationMatcher &NodeMatch,
|
||||||
StringRef ExpectedPrinted, StringRef FileName,
|
StringRef ExpectedPrinted, StringRef FileName,
|
||||||
PrintingPolicyModifier PolicyModifier = nullptr) {
|
PrintingPolicyModifier PolicyModifier = nullptr,
|
||||||
|
bool AllowError = false) {
|
||||||
PrintMatch Printer(PolicyModifier);
|
PrintMatch Printer(PolicyModifier);
|
||||||
MatchFinder Finder;
|
MatchFinder Finder;
|
||||||
Finder.addMatcher(NodeMatch, &Printer);
|
Finder.addMatcher(NodeMatch, &Printer);
|
||||||
std::unique_ptr<FrontendActionFactory> Factory(
|
std::unique_ptr<FrontendActionFactory> Factory(
|
||||||
newFrontendActionFactory(&Finder));
|
newFrontendActionFactory(&Finder));
|
||||||
|
|
||||||
if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
|
if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName) &&
|
||||||
|
!AllowError)
|
||||||
return testing::AssertionFailure()
|
return testing::AssertionFailure()
|
||||||
<< "Parsing error in \"" << Code.str() << "\"";
|
<< "Parsing error in \"" << Code.str() << "\"";
|
||||||
|
|
||||||
|
@ -170,16 +172,12 @@ PrintedDeclCXX1ZMatches(StringRef Code, const DeclarationMatcher &NodeMatch,
|
||||||
"input.cc");
|
"input.cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
::testing::AssertionResult PrintedDeclObjCMatches(
|
::testing::AssertionResult
|
||||||
StringRef Code,
|
PrintedDeclObjCMatches(StringRef Code, const DeclarationMatcher &NodeMatch,
|
||||||
const DeclarationMatcher &NodeMatch,
|
StringRef ExpectedPrinted, bool AllowError = false) {
|
||||||
StringRef ExpectedPrinted) {
|
|
||||||
std::vector<std::string> Args(1, "");
|
std::vector<std::string> Args(1, "");
|
||||||
return PrintedDeclMatches(Code,
|
return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, "input.m",
|
||||||
Args,
|
/*PolicyModifier=*/nullptr, AllowError);
|
||||||
NodeMatch,
|
|
||||||
ExpectedPrinted,
|
|
||||||
"input.m");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
@ -1321,3 +1319,17 @@ TEST(DeclPrinter, TestObjCProtocol2) {
|
||||||
namedDecl(hasName("P1")).bind("id"),
|
namedDecl(hasName("P1")).bind("id"),
|
||||||
"@protocol P1<P2>\n@end"));
|
"@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));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue