From 30c2d8e3a6505ed6699216833441eccaeedf02ad Mon Sep 17 00:00:00 2001 From: Yang Chen Date: Sat, 14 Jan 2017 02:08:05 -0800 Subject: [PATCH] Fixed a crash due to overwriting the same location In some cases (most likely for ill-declared templates), we may rewrite the same location multiple times, and hence trigger an ICE. This is now fixed. Upstream-Commit: https://github.com/csmith-project/creduce/commit/30c2d8e3a6505ed6699216833441eccaeedf02ad --- clang_delta/RemoveUnusedFunction.cpp | 23 ++++++++++++++++++++++- clang_delta/RemoveUnusedFunction.h | 7 ++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/clang_delta/RemoveUnusedFunction.cpp b/clang_delta/RemoveUnusedFunction.cpp index f9be26f..b38fe51 100644 --- a/clang_delta/RemoveUnusedFunction.cpp +++ b/clang_delta/RemoveUnusedFunction.cpp @@ -388,6 +388,8 @@ SourceLocation RemoveUnusedFunction::getFunctionOuterLocStart( const FunctionDecl *FD) { SourceLocation LocStart = FD->getLocStart(); + bool RecordLoc = false; + // check if FD is from a function template if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) { // get FTD->getLocStart() only if it is less than FD->getLocStart, @@ -396,8 +398,10 @@ SourceLocation RemoveUnusedFunction::getFunctionOuterLocStart( // template template void S::foo() { } // where // FTD->getLocStart() points to the begining of "template" - if (hasValidOuterLocStart(FTD, FD)) + if (hasValidOuterLocStart(FTD, FD)) { LocStart = FTD->getLocStart(); + RecordLoc = true; + } } if (LocStart.isMacroID()) @@ -406,6 +410,17 @@ SourceLocation RemoveUnusedFunction::getFunctionOuterLocStart( // this is ugly, but how do we get the location of __extension__? e.g.: // __extension__ void foo(); LocStart = getExtensionLocStart(LocStart); + + // In some cases where the given input is not well-formed, we may + // end up with duplicate locations for the FunctionTemplateDecl + // case. In such cases, we simply return an invalid SourceLocation, + // which will ben skipped by the caller of getFunctionOuterLocStart. + if (RecordLoc) { + if (VisitedLocations.count(LocStart)) + return SourceLocation(); + VisitedLocations.insert(LocStart); + } + return LocStart; } @@ -468,6 +483,8 @@ void RemoveUnusedFunction::removeOneFunctionDecl(const FunctionDecl *FD) LocEnd = SrcManager->getExpansionLoc(LocEnd); if (!FD->isInExternCContext() && !FD->isInExternCXXContext()) { SourceLocation FuncLocStart = getFunctionOuterLocStart(FD); + if (FuncLocStart.isInvalid()) + return; LocEnd = getFunctionLocEnd(FuncLocStart, LocEnd, FD); if (SrcManager->isWrittenInMainFile(FuncLocStart) && SrcManager->isWrittenInMainFile(LocEnd)) @@ -479,6 +496,8 @@ void RemoveUnusedFunction::removeOneFunctionDecl(const FunctionDecl *FD) const LinkageSpecDecl *Linkage = dyn_cast(Ctx); if (!Linkage) { SourceLocation FuncLocStart = getFunctionOuterLocStart(FD); + if (FuncLocStart.isInvalid()) + return; LocEnd = getFunctionLocEnd(FuncLocStart, LocEnd, FD); TheRewriter.RemoveText(SourceRange(FuncLocStart, LocEnd)); return; @@ -488,6 +507,8 @@ void RemoveUnusedFunction::removeOneFunctionDecl(const FunctionDecl *FD) // namespace { using ::foo; } if (Linkage->hasBraces()) { SourceLocation FuncLocStart = getFunctionOuterLocStart(FD); + if (FuncLocStart.isInvalid()) + return; TheRewriter.RemoveText(SourceRange(FuncLocStart, LocEnd)); return; } diff --git a/clang_delta/RemoveUnusedFunction.h b/clang_delta/RemoveUnusedFunction.h index d724aeb..ded12d7 100644 --- a/clang_delta/RemoveUnusedFunction.h +++ b/clang_delta/RemoveUnusedFunction.h @@ -14,8 +14,9 @@ #include #include #include -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h" #include "Transformation.h" #include "clang/Basic/SourceLocation.h" @@ -98,6 +99,8 @@ friend class ExtraReferenceVisitorWrapper; typedef std::set SystemFunctionsSet; + typedef llvm::SmallSet LocSet; + virtual void Initialize(clang::ASTContext &context); virtual void HandleTranslationUnit(clang::ASTContext &Ctx); @@ -188,6 +191,8 @@ friend class ExtraReferenceVisitorWrapper; SystemFunctionsSet ExistingSystemFunctions; + LocSet VisitedLocations; + FunctionDeclVector AllValidFunctionDecls; RUFAnalysisVisitor *AnalysisVisitor;