Find the name of the inlined function through a DW_AT_specification

The name is not necessarily found in the abstract origin, it can be
in a referred to specification.

If both a name and a DW_AT_specification is found in the abstract origin,
the name will have priority over the name of the specification.
(unclear if that can happen)



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14076
This commit is contained in:
Philippe Waroquiers 2014-06-21 12:41:48 +00:00
parent cdfd3be6b7
commit a2ea737046
6 changed files with 58 additions and 4 deletions

View File

@ -2425,7 +2425,6 @@ static HChar* get_inlFnName (Int absori, CUConst* cc, Bool td3)
abbv_code = get_ULEB128( &c );
abbv = get_abbv ( cc, abbv_code);
atag = abbv->atag;
TRACE_D3("\n");
TRACE_D3(" <get_inlFnName><%lx>: Abbrev Number: %llu (%s)\n",
posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
@ -2454,14 +2453,28 @@ static HChar* get_inlFnName (Int absori, CUConst* cc, Bool td3)
"get_inlFnName.1" );
ret = ML_(addStr)(cc->di, fnname, -1);
ML_(dinfo_free) (fnname);
break;
break; /* Name found, get out of the loop, as this has priority over
DW_AT_specification. */
}
if (attr == DW_AT_specification) {
if (cts.szB == 0)
cc->barf("get_inlFnName: AT specification missing");
/* hoping that there is no loop */
ret = get_inlFnName (cts.u.val, cc, td3);
/*
Unclear if having both DW_AT_specification and DW_AT_name is
possible but in any case, we do not break here.
If we find later on a DW_AT_name, it will override the name found
in the DW_AT_specification.*/
}
}
if (ret)
return ret;
else
else {
TRACE_D3("AbsOriFnNameNotFound");
return ML_(addStr)(cc->di, "AbsOriFnNameNotFound", -1);
}
}
/* Returns True if the (possibly) childrens of the current DIE are interesting

View File

@ -120,6 +120,7 @@ EXTRA_DIST = \
inlinfo.stderr.exp inlinfo.stdout.exp inlinfo.vgtest \
inlinfosupp.stderr.exp inlinfosupp.stdout.exp inlinfosupp.supp inlinfosupp.vgtest \
inlinfosuppobj.stderr.exp inlinfosuppobj.stdout.exp inlinfosuppobj.supp inlinfosuppobj.vgtest \
inltemplate.stderr.exp inltemplate.stdout.exp inltemplate.vgtest \
leak-0.vgtest leak-0.stderr.exp \
leak-cases-full.vgtest leak-cases-full.stderr.exp \
leak-cases-possible.vgtest leak-cases-possible.stderr.exp \
@ -302,7 +303,7 @@ check_PROGRAMS = \
err_disable1 err_disable2 err_disable3 err_disable4 \
err_disable_arange1 \
file_locking \
fprw fwrite inits inline inlinfo \
fprw fwrite inits inline inlinfo inltemplate \
holey_buffer_too_small \
leak-0 \
leak-cases \
@ -411,6 +412,9 @@ inits_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@
inlinfo_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@
inltemplate_SOURCES = inltemplate.cpp
inltemplate_CXXFLAGS = $(AM_CXXFLAGS) @FLAG_W_NO_UNINITIALIZED@
long_namespace_xml_SOURCES = long_namespace_xml.cpp
manuel1_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@

View File

@ -0,0 +1,30 @@
#include <stdio.h>
#include <valgrind.h>
#define INLINE inline __attribute__((always_inline))
class X
{
public:
template <typename T>
static INLINE T temp_member_func_b(T argb) {
static T locb = 0;
if (argb > 0)
locb += argb;
return locb;
}
template <typename T>
static /*INLINE*/ T temp_member_func_noinline(T arga) {
return temp_member_func_b(arga);
}
};
int main() {
int result;
result = X::temp_member_func_noinline(result);
return 0;
}

View File

@ -0,0 +1,5 @@
Conditional jump or move depends on uninitialised value(s)
at 0x........: temp_member_func_b<int> (inltemplate.cpp:12)
by 0x........: int X::temp_member_func_noinline<int>(int) (inltemplate.cpp:19)
by 0x........: main (inltemplate.cpp:27)

View File

View File

@ -0,0 +1,2 @@
prog: inltemplate
vgopts: -q --read-inline-info=yes