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
