diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2016-07-15 19:22:34 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2016-07-15 19:22:34 +0000 |
commit | 88737a5aa5cca893b47206cd048fa781fa3fc4d7 (patch) | |
tree | 851cbadcee48f73d071d799811e5b05543e8f0cb /clang/lib/ARCMigrate/ObjCMT.cpp | |
parent | 7f6484448121dc82f8080b0c95a675a2317ca32c (diff) | |
download | bcm5719-llvm-88737a5aa5cca893b47206cd048fa781fa3fc4d7.tar.gz bcm5719-llvm-88737a5aa5cca893b47206cd048fa781fa3fc4d7.zip |
[objcmt] Fix a buffer overflow crash than can occur while modernizing enums.
Note that due to the nature of the crash it requires libgmalloc or asan for it to crash consistently.
rdar://19932927
llvm-svn: 275600
Diffstat (limited to 'clang/lib/ARCMigrate/ObjCMT.cpp')
-rw-r--r-- | clang/lib/ARCMigrate/ObjCMT.cpp | 44 |
1 files changed, 17 insertions, 27 deletions
diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 940a9c95f28..241a7246b62 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -771,23 +771,11 @@ static void rewriteToNSMacroDecl(ASTContext &Ctx, ClassString += ", "; ClassString += TypedefDcl->getIdentifier()->getName(); - ClassString += ')'; - SourceLocation EndLoc; - if (EnumDcl->getIntegerTypeSourceInfo()) { - TypeSourceInfo *TSourceInfo = EnumDcl->getIntegerTypeSourceInfo(); - TypeLoc TLoc = TSourceInfo->getTypeLoc(); - EndLoc = TLoc.getLocEnd(); - const char *lbrace = Ctx.getSourceManager().getCharacterData(EndLoc); - unsigned count = 0; - if (lbrace) - while (lbrace[count] != '{') - ++count; - if (count > 0) - EndLoc = EndLoc.getLocWithOffset(count-1); - } - else - EndLoc = EnumDcl->getLocStart(); - SourceRange R(EnumDcl->getLocStart(), EndLoc); + ClassString += ") "; + SourceLocation EndLoc = EnumDcl->getBraceRange().getBegin(); + if (EndLoc.isInvalid()) + return; + CharSourceRange R = CharSourceRange::getCharRange(EnumDcl->getLocStart(), EndLoc); commit.replace(R, ClassString); // This is to remove spaces between '}' and typedef name. SourceLocation StartTypedefLoc = EnumDcl->getLocEnd(); @@ -1900,18 +1888,20 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { if (++N == DEnd) continue; if (const EnumDecl *ED = dyn_cast<EnumDecl>(*N)) { - if (++N != DEnd) - if (const TypedefDecl *TDF = dyn_cast<TypedefDecl>(*N)) { - // prefer typedef-follows-enum to enum-follows-typedef pattern. - if (migrateNSEnumDecl(Ctx, ED, TDF)) { - ++D; ++D; - CacheObjCNSIntegerTypedefed(TD); - continue; + if (canModify(ED)) { + if (++N != DEnd) + if (const TypedefDecl *TDF = dyn_cast<TypedefDecl>(*N)) { + // prefer typedef-follows-enum to enum-follows-typedef pattern. + if (migrateNSEnumDecl(Ctx, ED, TDF)) { + ++D; ++D; + CacheObjCNSIntegerTypedefed(TD); + continue; + } } + if (migrateNSEnumDecl(Ctx, ED, TD)) { + ++D; + continue; } - if (migrateNSEnumDecl(Ctx, ED, TD)) { - ++D; - continue; } } CacheObjCNSIntegerTypedefed(TD); |