From 97e24602c365cf3f2aada2e44c92e3a859d421f4 Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Wed, 29 Nov 2017 01:06:07 +0200 Subject: [PATCH] Fixed a possible crash when instantiating template functions in the parser. Signed-off-by: Dimitar Dobrev --- src/CppParser/Parser.cpp | 27 +++++++++++++++++++++++++++ src/CppParser/Parser.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index fec1f63d..820b29b3 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -3013,6 +3013,29 @@ static bool IsInvalid(clang::Stmt* Body, std::unordered_set& Bodie return false; } +std::stack Parser::GetScopesFor(clang::FunctionDecl* FD) +{ + using namespace clang; + + std::stack Contexts; + DeclContext* DC = FD; + while (DC) + { + Contexts.push(DC); + DC = DC->getParent(); + } + std::stack Scopes; + while (!Contexts.empty()) + { + Scope S(Scopes.empty() ? 0 : &Scopes.top(), + Scope::ScopeFlags::DeclScope, c->getDiagnostics()); + S.setEntity(Contexts.top()); + Scopes.push(S); + Contexts.pop(); + } + return Scopes; +} + void Parser::MarkValidity(Function* F) { using namespace clang; @@ -3028,8 +3051,12 @@ void Parser::MarkValidity(Function* F) auto Diagnostics = c->getSema().getDiagnostics().getClient(); auto SemaDiagnostics = static_cast<::DiagnosticConsumer*>(Diagnostics); SemaDiagnostics->Decl = FD; + auto TUScope = c->getSema().TUScope; + std::stack Scopes = GetScopesFor(FD); + c->getSema().TUScope = &Scopes.top(); c->getSema().InstantiateFunctionDefinition(FD->getLocStart(), FD, /*Recursive*/true); + c->getSema().TUScope = TUScope; F->isInvalid = FD->isInvalidDecl(); if (!F->isInvalid) { diff --git a/src/CppParser/Parser.h b/src/CppParser/Parser.h index ab1676c8..998102c4 100644 --- a/src/CppParser/Parser.h +++ b/src/CppParser/Parser.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "CXXABI.h" #include "CppParser.h" @@ -120,6 +121,7 @@ private: Parameter* WalkParameter(const clang::ParmVarDecl* PVD, const clang::SourceLocation& ParamStartLoc); void SetBody(const clang::FunctionDecl* FD, Function* F); + std::stack GetScopesFor(clang::FunctionDecl* FD); void MarkValidity(Function* F); void WalkFunction(const clang::FunctionDecl* FD, Function* F, bool IsDependent = false);