kadircet created this revision. kadircet added reviewers: sammccall, ilya-biryukov. Herald added a project: All. kadircet requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This prevents further parsing of tokens (that'll be freed) inside method body by propagating EOF emitted by reaching code completion token up the parsing stack. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D158269 Files: clang/lib/Parse/ParseObjc.cpp clang/test/Parser/objc-delayed-method-use-after-free.m Index: clang/test/Parser/objc-delayed-method-use-after-free.m =================================================================== --- /dev/null +++ clang/test/Parser/objc-delayed-method-use-after-free.m @@ -0,0 +1,13 @@ +// Make sure we don't trigger use-after-free when we encounter a code completion +// token inside a objc method. +@interface Foo +@end + +@implementation Foo +- (void)foo { + +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -code-completion-at=%s:%(line-1):1 %s | FileCheck %s +// CHECK: COMPLETION: self : [#Foo *#]self + [self foo]; +} +@end Index: clang/lib/Parse/ParseObjc.cpp =================================================================== --- clang/lib/Parse/ParseObjc.cpp +++ clang/lib/Parse/ParseObjc.cpp @@ -3764,6 +3764,8 @@ while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) ConsumeAnyToken(); } - // Clean up the remaining EOF token. - ConsumeAnyToken(); + // Clean up the remaining EOF token, only if it's inserted by us. Otherwise + // this might be code-completion token, so leave it. + if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl) + ConsumeAnyToken(); }
Index: clang/test/Parser/objc-delayed-method-use-after-free.m =================================================================== --- /dev/null +++ clang/test/Parser/objc-delayed-method-use-after-free.m @@ -0,0 +1,13 @@ +// Make sure we don't trigger use-after-free when we encounter a code completion +// token inside a objc method. +@interface Foo +@end + +@implementation Foo +- (void)foo { + +// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -code-completion-at=%s:%(line-1):1 %s | FileCheck %s +// CHECK: COMPLETION: self : [#Foo *#]self + [self foo]; +} +@end Index: clang/lib/Parse/ParseObjc.cpp =================================================================== --- clang/lib/Parse/ParseObjc.cpp +++ clang/lib/Parse/ParseObjc.cpp @@ -3764,6 +3764,8 @@ while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) ConsumeAnyToken(); } - // Clean up the remaining EOF token. - ConsumeAnyToken(); + // Clean up the remaining EOF token, only if it's inserted by us. Otherwise + // this might be code-completion token, so leave it. + if (Tok.is(tok::eof) && Tok.getEofData() == MCDecl) + ConsumeAnyToken(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits