From 55ba7264c0722c9519c0fdfacdf2363ad1c59e94 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Mon, 2 May 2022 03:25:32 +0900 Subject: [PATCH] Cxx: use a trashbox for deleteing tokens allocated for anonymous parameters Partially close #3372. The original code assumed tokens allocated in cxxParserTokenChainLooksLikeFunctionParameterList() for tagging anonymous parameters were deleted on its caller side (cxxParserEmitFunctionParameterTags()). However, in some conditions, cxxParserEmitFunctionParameterTags() are not called. As a result, the allocated tokens are not deleted. To avoid the memory leaking, the deletion cannot depend on cxxParserEmitFunctionParameterTags(). This change uses per-parsing trashbox for deleting the anonymous tokens. The objects linked to the trashbox are destroyed at the end of parsing the current input file. Signed-off-by: Masatake YAMATO --- .../anonymous-param-in-broken-paramlist.d/README | 1 + .../args.ctags | 2 ++ .../input-0.c | 16 ++++++++++++++++ .../input-1.c | 1 + .../input.c | 1 + parsers/cxx/cxx_parser_function.c | 5 ++++- 6 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 Units/parser-c.r/anonymous-param-in-broken-paramlist.d/README create mode 100644 Units/parser-c.r/anonymous-param-in-broken-paramlist.d/args.ctags create mode 100644 Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-0.c create mode 100644 Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-1.c create mode 100644 Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input.c diff --git a/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/README b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/README new file mode 100644 index 0000000000..24882b9add --- /dev/null +++ b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/README @@ -0,0 +1 @@ +This is a test case for detecting memory leaking. diff --git a/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/args.ctags b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/args.ctags new file mode 100644 index 0000000000..a4b0fd6af2 --- /dev/null +++ b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/args.ctags @@ -0,0 +1,2 @@ +--kinds-C=+z +--extras=+{anonymous} diff --git a/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-0.c b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-0.c new file mode 100644 index 0000000000..6e7908ef44 --- /dev/null +++ b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-0.c @@ -0,0 +1,16 @@ +/* https://gitlab.gnome.org/GNOME/glib/-/blob/main/gio/gdummyproxyresolver.c */ +G_DEFINE_TYPE_WITH_CODE (GDummyProxyResolver, g_dummy_proxy_resolver, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER, + g_dummy_proxy_resolver_iface_init) + _g_io_modules_ensure_extension_points_registered (); + g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME, + g_define_type_id, + "dummy", + -100)) + +static void +g_dummy_proxy_resolver_finalize (GObject *object) +{ + /* must chain up */ + G_OBJECT_CLASS (g_dummy_proxy_resolver_parent_class)->finalize (object); +} diff --git a/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-1.c b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-1.c new file mode 100644 index 0000000000..96c0733db1 --- /dev/null +++ b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input-1.c @@ -0,0 +1 @@ +G (f () g ()) h (void) { diff --git a/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input.c b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input.c new file mode 100644 index 0000000000..2758cf120a --- /dev/null +++ b/Units/parser-c.r/anonymous-param-in-broken-paramlist.d/input.c @@ -0,0 +1 @@ +f(a,){ diff --git a/parsers/cxx/cxx_parser_function.c b/parsers/cxx/cxx_parser_function.c index a087780fbc..30e7a4cc55 100644 --- a/parsers/cxx/cxx_parser_function.c +++ b/parsers/cxx/cxx_parser_function.c @@ -1889,6 +1889,8 @@ void cxxParserEmitFunctionParameterTags(CXXTypedVariableSet * pInfo) if(pTypeName) { + if (pInfo->uAnonymous & (0x1u << i)) + PARSER_TRASH_BOX_TAKE_BACK (pInfo->aIdentifiers[i]); cxxTokenDestroy(pInfo->aIdentifiers[i]); cxxTokenDestroy(pTypeName); } @@ -2180,6 +2182,7 @@ bool cxxParserTokenChainLooksLikeFunctionParameterList( pIdentifier->iLineNumber = t->pPrev->iLineNumber; pIdentifier->oFilePosition = t->pPrev->oFilePosition; pParamInfo->uAnonymous |= (0x1u << pParamInfo->uCount); + PARSER_TRASH_BOX (pIdentifier, cxxTokenDestroy); } pParamInfo->aIdentifiers[pParamInfo->uCount] = pIdentifier; pParamInfo->uCount++; @@ -2233,7 +2236,7 @@ bool cxxParserTokenChainLooksLikeFunctionParameterList( pParamInfo->uCount++; PARSER_TRASH_BOX (pFakeStart, cxxTokenDestroy); - /* pFakeId may be destroyed via pParamInfo->aIdentifiers[i]. */ + PARSER_TRASH_BOX (pFakeId, cxxTokenDestroy); } if(cxxTokenTypeIs(t,CXXTokenTypeClosingParenthesis))