Browse Source

CppParser: fix memory corruption issue

There are multiple places in the parser which do something similar to
this:

Foo *ptr = 0;

if (...) {
    Foo val = ...;
    ptr = &val;
}

func(ptr);

In other words, the code takes a pointer to a local variable, and the
pointer is used even after the local variable's scope has ended.

This causes a crash on Linux. For some reason this works fine on Windows
+ Visual studio.

This patchs moves the variable ("val" in the above example) to outer
scopes, so that its life time is extended to cover the use.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@iki.fi>
pull/261/head
Tomi Valkeinen 11 years ago
parent
commit
f5412c2d67
  1. 30
      src/CppParser/Parser.cpp

30
src/CppParser/Parser.cpp

@ -894,10 +894,11 @@ Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL,
for (size_t i = 0, e = TAL->size(); i < e; i++) for (size_t i = 0, e = TAL->size(); i < e; i++)
{ {
auto TA = TAL->get(i); auto TA = TAL->get(i);
TemplateArgumentLoc TAL;
TemplateArgumentLoc *ArgLoc = 0; TemplateArgumentLoc *ArgLoc = 0;
if (TSTL && i < TSTL->getNumArgs()) if (TSTL && i < TSTL->getNumArgs())
{ {
auto TAL = TSTL->getArgLoc(i); TAL = TSTL->getArgLoc(i);
ArgLoc = &TAL; ArgLoc = &TAL;
} }
auto Arg = WalkTemplateArgument(TA, ArgLoc); auto Arg = WalkTemplateArgument(TA, ArgLoc);
@ -1630,11 +1631,12 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
FunctionProtoTypeLoc FTL; FunctionProtoTypeLoc FTL;
TypeLoc RL; TypeLoc RL;
TypeLoc Next;
if (TL && !TL->isNull()) if (TL && !TL->isNull())
{ {
while (TL->getTypeLocClass() != TypeLoc::FunctionProto) while (TL->getTypeLocClass() != TypeLoc::FunctionProto)
{ {
auto Next = TL->getNextTypeLoc(); Next = TL->getNextTypeLoc();
TL = &Next; TL = &Next;
} }
@ -1712,29 +1714,32 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
if (TS->isSugared()) if (TS->isSugared())
TST->Desugared = WalkType(TS->desugar()); TST->Desugared = WalkType(TS->desugar());
TypeLoc UTL, ETL, ITL;
if (TL && !TL->isNull()) if (TL && !TL->isNull())
{ {
auto TypeLocClass = TL->getTypeLocClass(); auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified) if (TypeLocClass == TypeLoc::Qualified)
{ {
auto UTL = TL->getUnqualifiedLoc(); UTL = TL->getUnqualifiedLoc();
TL = &UTL; TL = &UTL;
} }
else if (TypeLocClass == TypeLoc::Elaborated) else if (TypeLocClass == TypeLoc::Elaborated)
{ {
auto ETL = TL->getAs<ElaboratedTypeLoc>(); ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc(); ITL = ETL.getNextTypeLoc();
TL = &ITL; TL = &ITL;
} }
assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization); assert(TL->getTypeLocClass() == TypeLoc::TemplateSpecialization);
} }
TemplateSpecializationTypeLoc TSpecTL;
TemplateSpecializationTypeLoc *TSTL = 0; TemplateSpecializationTypeLoc *TSTL = 0;
if (TL && !TL->isNull()) if (TL && !TL->isNull())
{ {
auto TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>(); TSpecTL = TL->getAs<TemplateSpecializationTypeLoc>();
TSTL = &TSpecTL; TSTL = &TSpecTL;
} }
TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->getArgs(), TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->getArgs(),
@ -1752,24 +1757,27 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
if (auto Ident = TP->getIdentifier()) if (auto Ident = TP->getIdentifier())
TPT->Parameter.Name = Ident->getName(); TPT->Parameter.Name = Ident->getName();
TypeLoc UTL, ETL, ITL, Next;
if (TL && !TL->isNull()) if (TL && !TL->isNull())
{ {
auto TypeLocClass = TL->getTypeLocClass(); auto TypeLocClass = TL->getTypeLocClass();
if (TypeLocClass == TypeLoc::Qualified) if (TypeLocClass == TypeLoc::Qualified)
{ {
auto UTL = TL->getUnqualifiedLoc(); UTL = TL->getUnqualifiedLoc();
TL = &UTL; TL = &UTL;
} }
else if (TypeLocClass == TypeLoc::Elaborated) else if (TypeLocClass == TypeLoc::Elaborated)
{ {
auto ETL = TL->getAs<ElaboratedTypeLoc>(); ETL = TL->getAs<ElaboratedTypeLoc>();
auto ITL = ETL.getNextTypeLoc(); ITL = ETL.getNextTypeLoc();
TL = &ITL; TL = &ITL;
} }
while (TL->getTypeLocClass() != TypeLoc::TemplateTypeParm) while (TL->getTypeLocClass() != TypeLoc::TemplateTypeParm)
{ {
auto Next = TL->getNextTypeLoc(); Next = TL->getNextTypeLoc();
TL = &Next; TL = &Next;
} }

Loading…
Cancel
Save