]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
backends: Support returning lvalue and rvalue references
authorIlya Leoshkevich <iii@linux.ibm.com>
Mon, 13 Feb 2023 16:45:50 +0000 (17:45 +0100)
committerMark Wielaard <mark@klomp.org>
Tue, 14 Feb 2023 14:12:48 +0000 (15:12 +0100)
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>
19 files changed:
backends/aarch64_retval.c
backends/alpha_retval.c
backends/arm_retval.c
backends/i386_retval.c
backends/ia64_retval.c
backends/libebl_CPU.h
backends/m68k_retval.c
backends/ppc64_retval.c
backends/ppc_retval.c
backends/riscv_retval.c
backends/s390_retval.c
backends/sh_retval.c
backends/sparc_retval.c
backends/x86_64_retval.c
configure.ac
tests/.gitignore
tests/Makefile.am
tests/funcretval_test++11.cxx [new file with mode: 0644]
tests/run-funcretval++11.sh [new file with mode: 0755]

index 72d4e8a3a259fac005bf94ccbe4cf89bbb727c94..8eaebaf158342dd28764a3f72760d1c57a8db49c 100644 (file)
@@ -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;
index d9bae3bcce2985357b1a7097976405e5aa7e252f..9d2dd045453f21687e07a0ca357fe7470399afff 100644 (file)
@@ -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;
index 1c28f016b5bc61aa788a1dee9a2c769400590a0f..fa6d391434d0b81df229613283eab38894c128c5 100644 (file)
@@ -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;
index 32fec7281666007dd2020a0536b10d7c6b000686..8a9c2a2b60b812f57edfb38301b0710889da096d 100644 (file)
@@ -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;
index 03ea4d89da492eb1267ed66f5a0b8f03eb53ace9..7e12236d3dcbf38bbc42e37de413586e97713a5f 100644 (file)
@@ -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;
index 0e507bd3924a5dbcf331dcb8d8c240b94a13afa0..2abad76f5b063b47b9328d3479c501b970edc15c 100644 (file)
@@ -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 */
index a653ba3a87e7e80bae3f9d7079303713fe70ef2e..bf41f862dd7283427f5964be19e09e96fc03f029 100644 (file)
@@ -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;
index eb1c11ec6da36a879fa8b1365cfd6c52b91d2108..1c20c89072683f778e874efca9fbe12e70ad94a6 100644 (file)
@@ -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;
index 39b42da12fbd7836e2bfc1578c1c687b05d5e86b..5144712b211358a525a6c83dc588cffcb5dc7f2a 100644 (file)
@@ -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;
index 347614862f1bb643acccc69905ee1ac8c7debf9a..0a1e02f81cd2d697a6dcf7f91f4cba6e38c6be65 100644 (file)
@@ -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;
index 2043f9855c19319e0bbd9e3f0126a95924f0f137..0a01d27f41e91deaa3b0f8c22801ae9e45c43a54 100644 (file)
@@ -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;
index 33d7d964bd7b18887e35abbf5892e52ba5aa7aac..eac83b705e7ad0c7319a4ca73a6537ad1e9b9446 100644 (file)
@@ -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;
index fb81cdceaf34c59436fb5040d8aa81d58b0f9c0b..8b3fb629fc92685b8114ff302625cd7ad6eb8bec 100644 (file)
@@ -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
index f9114cb14858708d4e3fb1fed4887379f11aedf4..c29ee0e17851a577818039499eeb864f3a766197 100644 (file)
@@ -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;
index 62a4c8a7407085204a3a0e0fe979270054c8bba7..4efb2a9c4d86940f43f7f957d91969f58edc7df0 100644 (file)
@@ -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}
index 536a41ec8d8f09fd81aacb8e39b47f88e1c3335a..b9aa22ba08b5dabfc220c3d34d0eda6d0a6d1288 100644 (file)
@@ -66,6 +66,7 @@
 /fillfile
 /find-prologues
 /funcretval
+/funcretval_test++11
 /funcscopes
 /get-aranges
 /get-files
index 36823d94c397d01fc2b7763ae0c6088f26fe202e..efbb4e637397ed7a7bb19b4240462336a943f549 100644 (file)
@@ -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 (file)
index 0000000..69e25bf
--- /dev/null
@@ -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 (executable)
index 0000000..fcfefe1
--- /dev/null
@@ -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