summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2023-02-13 17:45:50 +0100
committerMark Wielaard <mark@klomp.org>2023-02-14 15:12:48 +0100
commita4fafb7722c9950dacd5689f1ce8e31f8fa94ed5 (patch)
treefa3a53dc2e4297e8200c90e0a3ac4bdb90c9c412
parent47297d8bf2f516b66b6d45934849137ab7658a99 (diff)
downloadelfutils-a4fafb7722c9950dacd5689f1ce8e31f8fa94ed5.tar.gz
backends: Support returning lvalue and rvalue references
On the low level, they are the same as pointers. The change needs to be done for all backends, so define a function and a macro to avoid repetition. Also add a native test, which has to be implemented in C++. Add the configure check for it. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
-rw-r--r--backends/aarch64_retval.c5
-rw-r--r--backends/alpha_retval.c5
-rw-r--r--backends/arm_retval.c5
-rw-r--r--backends/i386_retval.c5
-rw-r--r--backends/ia64_retval.c5
-rw-r--r--backends/libebl_CPU.h15
-rw-r--r--backends/m68k_retval.c5
-rw-r--r--backends/ppc64_retval.c5
-rw-r--r--backends/ppc_retval.c5
-rw-r--r--backends/riscv_retval.c5
-rw-r--r--backends/s390_retval.c5
-rw-r--r--backends/sh_retval.c5
-rw-r--r--backends/sparc_retval.c5
-rw-r--r--backends/x86_64_retval.c7
-rw-r--r--configure.ac11
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.am9
-rw-r--r--tests/funcretval_test++11.cxx37
-rwxr-xr-xtests/run-funcretval++11.sh21
19 files changed, 118 insertions, 43 deletions
diff --git a/backends/aarch64_retval.c b/backends/aarch64_retval.c
index 72d4e8a3..8eaebaf1 100644
--- a/backends/aarch64_retval.c
+++ b/backends/aarch64_retval.c
@@ -303,12 +303,11 @@ aarch64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
}
}
- if (tag == DW_TAG_base_type
- || tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (tag == DW_TAG_base_type || dwarf_is_pointer (tag))
{
if (dwarf_bytesize_aux (&typedie, &size) < 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 8;
else
return -1;
diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c
index d9bae3bc..9d2dd045 100644
--- a/backends/alpha_retval.c
+++ b/backends/alpha_retval.c
@@ -89,15 +89,14 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
Dwarf_Word size;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 8;
else
return -1;
diff --git a/backends/arm_retval.c b/backends/arm_retval.c
index 1c28f016..fa6d3914 100644
--- a/backends/arm_retval.c
+++ b/backends/arm_retval.c
@@ -86,14 +86,13 @@ arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 4;
else
return -1;
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index 32fec728..8a9c2a2b 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -89,15 +89,14 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Word size;
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 4;
else
return -1;
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index 03ea4d89..7e12236d 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -264,14 +264,13 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 8;
else
return -1;
diff --git a/backends/libebl_CPU.h b/backends/libebl_CPU.h
index 0e507bd3..2abad76f 100644
--- a/backends/libebl_CPU.h
+++ b/backends/libebl_CPU.h
@@ -72,4 +72,19 @@ dwarf_peeled_die_type (Dwarf_Die *die, Dwarf_Die *result)
return DWARF_TAG_OR_RETURN (result);
}
+static inline bool
+dwarf_is_pointer (int tag)
+{
+ return tag == DW_TAG_pointer_type
+ || tag == DW_TAG_ptr_to_member_type
+ || tag == DW_TAG_reference_type
+ || tag == DW_TAG_rvalue_reference_type;
+}
+
+#define CASE_POINTER \
+ case DW_TAG_pointer_type: \
+ case DW_TAG_ptr_to_member_type: \
+ case DW_TAG_reference_type: \
+ case DW_TAG_rvalue_reference_type
+
#endif /* libebl_CPU.h */
diff --git a/backends/m68k_retval.c b/backends/m68k_retval.c
index a653ba3a..bf41f862 100644
--- a/backends/m68k_retval.c
+++ b/backends/m68k_retval.c
@@ -96,15 +96,14 @@ m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Word size;
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 4;
else
return -1;
diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c
index eb1c11ec..1c20c890 100644
--- a/backends/ppc64_retval.c
+++ b/backends/ppc64_retval.c
@@ -100,14 +100,13 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 8;
else
return -1;
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
index 39b42da1..5144712b 100644
--- a/backends/ppc_retval.c
+++ b/backends/ppc_retval.c
@@ -112,14 +112,13 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 4;
else
return -1;
diff --git a/backends/riscv_retval.c b/backends/riscv_retval.c
index 34761486..0a1e02f8 100644
--- a/backends/riscv_retval.c
+++ b/backends/riscv_retval.c
@@ -170,12 +170,11 @@ riscv_return_value_location_lp64ifd (int fp, Dwarf_Die *functypedie,
return pass_in_gpr_lp64 (locp, size);
}
- if (tag == DW_TAG_base_type
- || tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (tag == DW_TAG_base_type || dwarf_is_pointer (tag))
{
if (dwarf_bytesize_aux (&typedie, &size) < 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 8;
else
return -1;
diff --git a/backends/s390_retval.c b/backends/s390_retval.c
index 2043f985..0a01d27f 100644
--- a/backends/s390_retval.c
+++ b/backends/s390_retval.c
@@ -91,8 +91,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Die cudie;
uint8_t asize;
@@ -103,7 +102,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = asize;
else
return -1;
diff --git a/backends/sh_retval.c b/backends/sh_retval.c
index 33d7d964..eac83b70 100644
--- a/backends/sh_retval.c
+++ b/backends/sh_retval.c
@@ -88,14 +88,13 @@ sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
{
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag))
size = 4;
else
return -1;
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
index fb81cdce..8b3fb629 100644
--- a/backends/sparc_retval.c
+++ b/backends/sparc_retval.c
@@ -95,8 +95,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
@@ -104,7 +103,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
{
uint8_t asize;
Dwarf_Die cudie;
- if ((tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ if (dwarf_is_pointer (tag)
&& dwarf_diecu (typedie, &cudie, &asize, NULL) != NULL)
size = asize;
else
diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c
index f9114cb1..c29ee0e1 100644
--- a/backends/x86_64_retval.c
+++ b/backends/x86_64_retval.c
@@ -104,14 +104,13 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
case DW_TAG_base_type:
case DW_TAG_enumeration_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
+ CASE_POINTER:
{
Dwarf_Attribute attr_mem;
if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
&attr_mem), &size) != 0)
- {
- if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+ {
+ if (dwarf_is_pointer (tag))
size = 8;
else
return -1;
diff --git a/configure.ac b/configure.ac
index 62a4c8a7..4efb2a9c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -776,6 +776,11 @@ fi
AC_CHECK_PROG(HAVE_ZSTD, zstd, yes, no)
AM_CONDITIONAL([HAVE_ZSTD],[test "x$HAVE_ZSTD" = "xyes"])
+# For tests that need to use C++11
+AX_CXX_COMPILE_STDCXX(11, noext, optional)
+AS_IF([test "x$HAVE_CXX11" = "x1"], [HAVE_CXX11=yes], [HAVE_CXX11=no])
+AM_CONDITIONAL([HAVE_CXX11],[test "x$HAVE_CXX11" = "xyes"])
+
# Look for libcurl for libdebuginfod minimum version as per rhel7.
AC_ARG_ENABLE([libdebuginfod],AS_HELP_STRING([--enable-libdebuginfod], [Build debuginfod client library (can be =dummy)]))
AS_IF([test "x$enable_libdebuginfod" != "xno"], [
@@ -806,8 +811,9 @@ AM_CONDITIONAL([DUMMY_LIBDEBUGINFOD],[test "x$enable_libdebuginfod" = "xdummy"])
# minimum versions as per rhel7.
AC_ARG_ENABLE([debuginfod],AS_HELP_STRING([--enable-debuginfod], [Build debuginfod server]))
AS_IF([test "x$enable_debuginfod" != "xno"], [
- AC_MSG_NOTICE([checking debuginfod C++11 support, --disable-debuginfod to skip])
- AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
+ if test "x$HAVE_CXX11" = "xno"; then
+ AC_MSG_ERROR([the compiler does not support C++11, use --disable-debuginfod to disable.])
+ fi
AC_MSG_NOTICE([checking debuginfod dependencies, --disable-debuginfod to skip])
if test "x$enable_libdebuginfod" = "xno"; then
AC_MSG_ERROR([need libdebuginfod (or dummy), use --disable-debuginfod to disable.])
@@ -881,6 +887,7 @@ AC_MSG_NOTICE([
EXTRA TEST FEATURES (used with make check)
have bunzip2 installed (required) : ${HAVE_BUNZIP2}
have zstd installed : ${HAVE_ZSTD}
+ C++11 : ${HAVE_CXX11}
debug branch prediction : ${use_debugpred}
gprof support : ${use_gprof}
gcov support : ${use_gcov}
diff --git a/tests/.gitignore b/tests/.gitignore
index 536a41ec..b9aa22ba 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -66,6 +66,7 @@
/fillfile
/find-prologues
/funcretval
+/funcretval_test++11
/funcscopes
/get-aranges
/get-files
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 36823d94..efbb4e63 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -262,6 +262,12 @@ TESTS += run-debuginfod-federation-metrics.sh
endif
endif
+if HAVE_CXX11
+check_PROGRAMS += funcretval_test++11
+funcretval_test__11_SOURCES = funcretval_test++11.cxx
+TESTS += run-funcretval++11.sh
+endif
+
EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
run-ar-N.sh \
run-show-die-info.sh run-get-files.sh run-get-lines.sh \
@@ -604,7 +610,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
run-readelf-dw-form-indirect.sh testfile-dw-form-indirect.bz2 \
run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \
testfile_nvidia_linemap.bz2 \
- testfile-largealign.o.bz2 run-strip-largealign.sh
+ testfile-largealign.o.bz2 run-strip-largealign.sh \
+ run-funcretval++11.sh
if USE_VALGRIND
diff --git a/tests/funcretval_test++11.cxx b/tests/funcretval_test++11.cxx
new file mode 100644
index 00000000..69e25bfb
--- /dev/null
+++ b/tests/funcretval_test++11.cxx
@@ -0,0 +1,37 @@
+/* Copyright (C) 2023 IBM Corporation
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <utility>
+
+int &
+foo ()
+{
+ static int tmp;
+ return tmp;
+}
+
+int &&
+bar ()
+{
+ static int tmp;
+ return std::move(tmp);
+}
+
+int
+main ()
+{
+ return 0;
+}
diff --git a/tests/run-funcretval++11.sh b/tests/run-funcretval++11.sh
new file mode 100755
index 00000000..fcfefe19
--- /dev/null
+++ b/tests/run-funcretval++11.sh
@@ -0,0 +1,21 @@
+#! /bin/sh
+# Copyright (C) 2023 IBM Corporation
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testrun $abs_builddir/funcretval -e $abs_builddir/funcretval_test++11 \
+ > /dev/null