Skip to content

Commit b4574f0

Browse files
authored
CXX: Avoid accessing token after it has been destroyed (#2586)
Fixes #2554 Replaces #2559
1 parent 1cae951 commit b4574f0

File tree

4 files changed

+47
-21
lines changed

4 files changed

+47
-21
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--sort=no
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__anonbbb2b4710108 input.c /^{$/;" s file:
2+
n input.c /^ int*n;$/;" m struct:__anonbbb2b4710108 typeref:typename:int * file:
3+
S input.c /^} S;$/;" t typeref:struct:__anonbbb2b4710108 file:
4+
foo input.c /^struct foo {$/;" s file:
5+
bar input.c /^ int bar;$/;" m struct:foo typeref:typename:int file:
6+
v input.c /^} v = {$/;" v typeref:struct:foo
7+
w input.c /^struct foo w = {$/;" v typeref:struct:foo

Units/parser-c.r/bug2554.c.d/input.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* valgrind reported an error when ctags built with
2+
* --enable-debugging configure option.
3+
*
4+
* To reproduce:
5+
*
6+
* $ make units LANGUAGES=C VG=1
7+
*
8+
*/
9+
typedef struct
10+
{
11+
int*n;
12+
} S;
13+
14+
struct foo {
15+
int bar;
16+
} v = {
17+
.bar = 1,
18+
};
19+
20+
struct foo w = {
21+
.bar = 2,
22+
};

parsers/cxx/cxx_parser.c

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,11 @@ static bool cxxParserParseEnumStructClassOrUnionFullDeclarationTrailer(
494494
MIOPos oFilePosition = getInputFilePosition();
495495
int iFileLine = getInputLineNumber();
496496

497-
if(!cxxParserParseUpToOneOf(CXXTokenTypeEOF | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket
498-
| CXXTokenTypeAssignment, false))
497+
if(!cxxParserParseUpToOneOf(
498+
CXXTokenTypeEOF | CXXTokenTypeSemicolon |
499+
CXXTokenTypeOpeningBracket | CXXTokenTypeAssignment,
500+
false
501+
))
499502
{
500503
CXX_DEBUG_LEAVE_TEXT("Failed to parse up to EOF/semicolon");
501504
return false;
@@ -556,30 +559,23 @@ static bool cxxParserParseEnumStructClassOrUnionFullDeclarationTrailer(
556559
return true;
557560
}
558561

562+
if(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeAssignment))
563+
{
564+
if(!cxxParserParseUpToOneOf(
565+
CXXTokenTypeEOF | CXXTokenTypeSemicolon,
566+
false
567+
))
568+
{
569+
CXX_DEBUG_LEAVE_TEXT("Failed to parse up to EOF/semicolon");
570+
return false;
571+
}
572+
}
573+
559574
if(uKeywordState & CXXParserKeywordStateSeenTypedef)
560575
cxxParserExtractTypedef(g_cxx.pTokenChain,true);
561576
else
562577
cxxParserExtractVariableDeclarations(g_cxx.pTokenChain,0);
563578

564-
/*
565-
Skip initializer in
566-
567-
struct foo { ... } x = { ... };
568-
569-
if we are at --------^.
570-
we go to ---------------------^.
571-
572-
The above example is known case.
573-
To be tolerant and handle unrecognized case, we
574-
put the code for skipping here. */
575-
if(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeAssignment) &&
576-
(!cxxParserParseUpToOneOf(CXXTokenTypeEOF | CXXTokenTypeSemicolon, true)))
577-
{
578-
CXX_DEBUG_LEAVE_TEXT("Failed to parse up to EOF/semicolon");
579-
return false;
580-
}
581-
582-
583579
CXX_DEBUG_LEAVE();
584580
return true;
585581
}

0 commit comments

Comments
 (0)