[v3,3/4] backends: Support returning lvalue and rvalue references

Message ID 20230213164551.550400-4-iii@linux.ibm.com
State Committed
Headers
Series Add Memory Sanitizer support |

Commit Message

Ilya Leoshkevich Feb. 13, 2023, 4:45 p.m. UTC
  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>
---
 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             |  8 +++++++-
 tests/funcretval_test++11.cxx | 37 +++++++++++++++++++++++++++++++++++
 tests/run-funcretval++11.sh   | 21 ++++++++++++++++++++
 19 files changed, 117 insertions(+), 43 deletions(-)
 create mode 100644 tests/funcretval_test++11.cxx
 create mode 100755 tests/run-funcretval++11.sh
  

Comments

Mark Wielaard Feb. 14, 2023, 2:16 p.m. UTC | #1
Hi Ilya,

On Mon, 2023-02-13 at 17:45 +0100, Ilya Leoshkevich wrote:
> 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.

I love everything about this patch (except for missing a ChangeLog
entry, but lets ignore that). The way you abstracted the pointer type
for the backends, the new test and the configure addition are all very
nice.

There is one small issue with the test. In case there is a C++11
compiler available run-funcretval++11.sh is added to TESTS twice, and
it is never added to EXTRA_DIST. So I pushed it with this small change:

diff --git a/tests/Makefile.am b/tests/Makefile.am
index bfc03061..efbb4e63 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -203,7 +203,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
        $(asm_TESTS) run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \
        run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \
        run-readelf-dw-form-indirect.sh run-strip-largealign.sh \
-       run-readelf-Dd.sh run-funcretval++11.sh
+       run-readelf-Dd.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -610,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

Thanks,

Mark
  

Patch

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..bfc03061 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -203,7 +203,7 @@  TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
 	$(asm_TESTS) run-disasm-bpf.sh run-low_high_pc-dw-form-indirect.sh \
 	run-nvidia-extended-linemap-libdw.sh run-nvidia-extended-linemap-readelf.sh \
 	run-readelf-dw-form-indirect.sh run-strip-largealign.sh \
-	run-readelf-Dd.sh
+	run-readelf-Dd.sh run-funcretval++11.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -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 \
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