From a4fafb7722c9950dacd5689f1ce8e31f8fa94ed5 Mon Sep 17 00:00:00 2001 From: Ilya Leoshkevich Date: Mon, 13 Feb 2023 17:45:50 +0100 Subject: 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 --- backends/aarch64_retval.c | 5 ++--- backends/alpha_retval.c | 5 ++--- backends/arm_retval.c | 5 ++--- backends/i386_retval.c | 5 ++--- backends/ia64_retval.c | 5 ++--- backends/libebl_CPU.h | 15 +++++++++++++++ backends/m68k_retval.c | 5 ++--- backends/ppc64_retval.c | 5 ++--- backends/ppc_retval.c | 5 ++--- backends/riscv_retval.c | 5 ++--- backends/s390_retval.c | 5 ++--- backends/sh_retval.c | 5 ++--- backends/sparc_retval.c | 5 ++--- backends/x86_64_retval.c | 7 +++---- configure.ac | 11 +++++++++-- tests/.gitignore | 1 + tests/Makefile.am | 9 ++++++++- tests/funcretval_test++11.cxx | 37 +++++++++++++++++++++++++++++++++++++ tests/run-funcretval++11.sh | 21 +++++++++++++++++++++ 19 files changed, 118 insertions(+), 43 deletions(-) create mode 100644 tests/funcretval_test++11.cxx create mode 100755 tests/run-funcretval++11.sh 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 . */ + +#include + +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 . + +. $srcdir/test-subr.sh + +testrun $abs_builddir/funcretval -e $abs_builddir/funcretval_test++11 \ + > /dev/null -- cgit v1.2.1