Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
If the result of build_stub_object gets printed by %E it looks something
like '(A&&)1', which seems confusing. Let's instead print it as
'std::declval<A>()' since that's how the library writes the same idea.
gcc/cp/ChangeLog:
* method.cc (is_stub_object): New.
* cp-tree.h (is_stub_object): Declare.
* error.cc (dump_expr): Use it.
---
gcc/cp/cp-tree.h | 1 +
gcc/cp/error.cc | 9 +++++++++
gcc/cp/method.cc | 12 ++++++++++++
gcc/testsuite/g++.dg/gomp/declare-variant-3.C | 4 ++--
gcc/testsuite/g++.dg/gomp/declare-variant-5.C | 4 ++--
5 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1d741ecedc3..6184d99f4af 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7456,6 +7456,7 @@ extern tree get_copy_assign (tree);
extern tree get_default_ctor (tree);
extern tree get_dtor (tree, tsubst_flags_t);
extern tree build_stub_object (tree);
+extern bool is_stub_object (tree);
extern tree build_invoke (tree, const_tree,
tsubst_flags_t);
extern tree strip_inheriting_ctors (tree);
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index feb6853b4f7..cc4cc4a7eb4 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -2604,6 +2604,15 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
dump_call_expr_args (pp, t, flags, true);
}
+ else if (is_stub_object (t))
+ {
+ pp_string (pp, "std::declval<");
+ if (lvalue_p (t)) /* T& */
+ dump_type (pp, TREE_TYPE (STRIP_REFERENCE_REF (t)), flags);
+ else /* T */
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_string (pp, ">()");
+ }
else
{
if (TREE_OPERAND (t,0) != NULL_TREE
diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index 0f9f23ae93a..64535f52019 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -1914,6 +1914,18 @@ build_stub_object (tree reftype)
return convert_from_reference (stub);
}
+/* True iff EXPR is the result of build_stub_object. */
+
+bool
+is_stub_object (tree expr)
+{
+ if (!REFERENCE_REF_P (expr))
+ return false;
+ expr = TREE_OPERAND (expr, 0);
+ return (TREE_CODE (expr) == CONVERT_EXPR
+ && TREE_OPERAND (expr, 0) == integer_one_node);
+}
+
/* Build a std::declval<TYPE>() expression and return it. */
tree
diff --git a/gcc/testsuite/g++.dg/gomp/declare-variant-3.C
b/gcc/testsuite/g++.dg/gomp/declare-variant-3.C
index 376eefc2dc1..8c0cfd218ad 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-variant-3.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-variant-3.C
@@ -86,7 +86,7 @@ struct E { int e; };
void fn19 (E, int);
-#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error
{could not convert '[^']*' from 'int' to 'E'} }
+#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error
{could not convert 'std::declval<int>\(\)' from 'int' to 'E'} }
void fn20 (int, E);
struct F { operator int () const { return 42; } int f; };
@@ -95,7 +95,7 @@ void fn21 (int, F);
#pragma omp declare variant ( fn21 ) match (user = { condition ( 1 - 1 ) } )
// { dg-error "variant 'void fn21\\\(int, F\\\)' and base 'void fn22\\\(F,
F\\\)' have incompatible types" }
void fn22 (F, F);
-#pragma omp declare variant (fn19) match (user={condition(0)}) // {
dg-error {could not convert '[^']*' from 'F' to 'E'} }
+#pragma omp declare variant (fn19) match (user={condition(0)}) // {
dg-error {could not convert 'std::declval<F>\(\)' from 'F' to 'E'} }
void fn23 (F, int);
void fn24 (int);
diff --git a/gcc/testsuite/g++.dg/gomp/declare-variant-5.C
b/gcc/testsuite/g++.dg/gomp/declare-variant-5.C
index a52fa528e1f..a4747ac030b 100644
--- a/gcc/testsuite/g++.dg/gomp/declare-variant-5.C
+++ b/gcc/testsuite/g++.dg/gomp/declare-variant-5.C
@@ -74,7 +74,7 @@ struct E { int e; };
void fn19 (E, int) {}
-#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error
{could not convert '[^']*' from 'int' to 'E'} }
+#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error
{could not convert 'std::declval<int>\(\)' from 'int' to 'E'} }
void fn20 (int, E) {}
struct F { operator int () const { return 42; } int f; };
@@ -83,7 +83,7 @@ void fn21 (int, F) {}
#pragma omp declare variant ( fn21 ) match (user = { condition ( 1 - 1 ) } )
// { dg-error "variant 'void fn21\\\(int, F\\\)' and base 'void fn22\\\(F,
F\\\)' have incompatible types" }
void fn22 (F, F) {}
-#pragma omp declare variant (fn19) match (user={condition(0)}) // {
dg-error {could not convert '[^']*' from 'F' to 'E'} }
+#pragma omp declare variant (fn19) match (user={condition(0)}) // {
dg-error {could not convert 'std::declval<F>\(\)' from 'F' to 'E'} }
void fn23 (F, int) {}
void fn24 (int);
--
2.47.1