From 070d649eefeeb17cce3afaeebe9f825024284854 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 27 Nov 2013 05:50:55 +0000 Subject: [PATCH] [libclang] Make sure we don't access past the tokens buffer while token annotation. Also disable crash recovery using 'LIBCLANG_DISABLE_CRASH_RECOVERY' environment variable. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195819 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/Index/annotate-tokens.cpp | 12 ++++++++++++ test/Index/crash-recovery.c | 1 + tools/libclang/CIndex.cpp | 36 +++++++++++++++++++++++++++------- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/test/Index/annotate-tokens.cpp b/test/Index/annotate-tokens.cpp index 16726547a2..8f2cdeb564 100644 --- a/test/Index/annotate-tokens.cpp +++ b/test/Index/annotate-tokens.cpp @@ -28,6 +28,11 @@ struct TS { template void TS::foo() {} +void test4() { + if (int p = 0) + return; +} + // RUN: c-index-test -test-annotate-tokens=%s:1:1:30:1 %s -fno-delayed-template-parsing | FileCheck %s // CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition) // CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition) @@ -173,3 +178,10 @@ void TS::foo() {} // CHECK: Punctuation: ")" [29:19 - 29:20] CXXMethod=foo:29:15 (Definition) // CHECK: Punctuation: "{" [29:21 - 29:22] CompoundStmt= // CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt= + +// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 c-index-test -test-annotate-tokens=%s:32:1:32:13 %s | FileCheck %s -check-prefix=CHECK2 +// CHECK2: Keyword: "if" [32:3 - 32:5] IfStmt= +// CHECK2: Punctuation: "(" [32:6 - 32:7] IfStmt= +// CHECK2: Keyword: "int" [32:7 - 32:10] VarDecl=p:32:11 (Definition) +// CHECK2: Identifier: "p" [32:11 - 32:12] VarDecl=p:32:11 (Definition) +// CHECK2: Punctuation: "=" [32:13 - 32:14] VarDecl=p:32:11 (Definition) diff --git a/test/Index/crash-recovery.c b/test/Index/crash-recovery.c index b7f6e0b2b9..e8e84bc504 100644 --- a/test/Index/crash-recovery.c +++ b/test/Index/crash-recovery.c @@ -1,6 +1,7 @@ // RUN: not c-index-test -test-load-source all %s 2> %t.err // RUN: FileCheck < %t.err -check-prefix=CHECK-LOAD-SOURCE-CRASH %s // CHECK-LOAD-SOURCE-CRASH: Unable to load translation unit +// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 not --crash c-index-test -test-load-source all %s // // REQUIRES: crash-recovery diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index f53e5c1c49..be29939b62 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -5075,18 +5075,26 @@ class AnnotateTokensWorker { unsigned BeforeChildrenTokenIdx; }; SmallVector PostChildrenInfos; - + + CXToken &getTok(unsigned Idx) { + assert(Idx < NumTokens); + return Tokens[Idx]; + } + const CXToken &getTok(unsigned Idx) const { + assert(Idx < NumTokens); + return Tokens[Idx]; + } bool MoreTokens() const { return TokIdx < NumTokens; } unsigned NextToken() const { return TokIdx; } void AdvanceToken() { ++TokIdx; } SourceLocation GetTokenLoc(unsigned tokI) { - return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); + return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]); } bool isFunctionMacroToken(unsigned tokI) const { - return Tokens[tokI].int_data[3] != 0; + return getTok(tokI).int_data[3] != 0; } SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const { - return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]); + return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]); } void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange); @@ -5333,7 +5341,7 @@ AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) { // This can happen for C++ constructor expressions whose range generally // include the variable declaration, e.g.: // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor. - if (clang_isExpression(cursorK)) { + if (clang_isExpression(cursorK) && MoreTokens()) { const Expr *E = getCursorExpr(cursor); if (const Decl *D = getCursorParentDecl(cursor)) { const unsigned I = NextToken(); @@ -5455,14 +5463,23 @@ public: } private: + CXToken &getTok(unsigned Idx) { + assert(Idx < NumTokens); + return Tokens[Idx]; + } + const CXToken &getTok(unsigned Idx) const { + assert(Idx < NumTokens); + return Tokens[Idx]; + } + SourceLocation getTokenLoc(unsigned tokI) { - return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]); + return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]); } void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) { // The third field is reserved and currently not used. Use it here // to mark macro arg expanded tokens with their expanded locations. - Tokens[tokI].int_data[3] = loc.getRawEncoding(); + getTok(tokI).int_data[3] = loc.getRawEncoding(); } }; @@ -6498,6 +6515,11 @@ bool RunSafely(llvm::CrashRecoveryContext &CRC, unsigned Size) { if (!Size) Size = GetSafetyThreadStackSize(); + if (getenv("LIBCLANG_DISABLE_CRASH_RECOVERY")) { + // Don't use crash recovery. + llvm::llvm_execute_on_thread(Fn, UserData, Size); + return true; + } if (Size) return CRC.RunSafelyOnThread(Fn, UserData, Size); return CRC.RunSafely(Fn, UserData); -- 2.40.0