[PR,c++/84492] return stmt expr ending with overload

Message ID orfu5lpbcf.fsf@lxoliva.fsfla.org
State New
Headers show
Series
  • [PR,c++/84492] return stmt expr ending with overload
Related show

Commit Message

Alexandre Oliva Feb. 28, 2018, 12:06 p.m.
We ICEd when returning a stmt expr that ends with an overloaded
function.  It's ill-formed when we can't convert the function name to
the return type, but we should say that, not ICE.

The problem was that instantiate_type did not know what to do with
STMT_EXPRs.

Regstrapped on x86_64- and i686-linux-gnu.  Ok to install?

for  gcc/cp/ChangeLog

	PR c++/84492
	* class.c (instantiate_type): Deal with STMT_EXPRs.

for  gcc/testsuite/ChangeLog

	PR c++/84492
	* g++.dg/pr84492.C: New.
---
 gcc/cp/class.c                 |    6 +++++-
 gcc/testsuite/g++.dg/pr84492.C |    7 +++++++
 2 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/pr84492.C


-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer

Comments

Jason Merrill Feb. 28, 2018, 5:42 p.m. | #1
On Wed, Feb 28, 2018 at 7:06 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
> We ICEd when returning a stmt expr that ends with an overloaded

> function.  It's ill-formed when we can't convert the function name to

> the return type, but we should say that, not ICE.


Hmm, what about the case where we could convert the function name to
the return type?  I think it should still be ill-formed for a
statement-expression to have an unresolved overload as its value.  So
finish_stmt_expr_expr should check type_unknown_p.

Jason
Alexandre Oliva March 2, 2018, 7:57 a.m. | #2
On Feb 28, 2018, Jason Merrill <jason@redhat.com> wrote:

> On Wed, Feb 28, 2018 at 7:06 AM, Alexandre Oliva <aoliva@redhat.com> wrote:

>> We ICEd when returning a stmt expr that ends with an overloaded

>> function.  It's ill-formed when we can't convert the function name to

>> the return type, but we should say that, not ICE.


> Hmm, what about the case where we could convert the function name to

> the return type?  I think it should still be ill-formed for a

> statement-expression to have an unresolved overload as its value.


I was (not :-) thinking in those terms; I suppose one might wish ({x;})
to be equivalent to (x), but one might also wish for stmt exprs to be
self-contained, and I suppose you prefer the latter, or that there's
consensus about how the stmt expr extension should be handled in this
regard, so...

> So finish_stmt_expr_expr should check type_unknown_p.


[PR c++/84492] stmt expr ending with overload

We ICEd when returning a stmt expr that ends with an overloaded
function, because instantiate_type did not know what to do with
STMT_EXPRs.  And it shouldn't have to: the expected type of a stmt
expr cannot be used to resolve its value: an unresolved overload
cannot supply the result of a stmt expr.  Catch that and report the
error in the stmt expr before we have a chance to instantiate it.

Regstrapped on i686- and x86_64-linux-gnu.  Ok?

for  gcc/cp/ChangeLog

	PR c++/84492
	* semantics.c (finish_stmt_expr_expr): Reject unresolved
	overloads used as stmt expr values.

for  gcc/testsuite/ChangeLog

	PR c++/84492
	* g++.dg/pr84492.C: New.
---
 gcc/cp/semantics.c             |    9 ++++++++-
 gcc/testsuite/g++.dg/pr84492.C |   40 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/pr84492.C

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 1ac1d23e7610..af401866b569 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2115,7 +2115,14 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr)
     {
       tree type = TREE_TYPE (expr);
 
-      if (processing_template_decl)
+      if (type && type_unknown_p (type))
+	{
+	  error ("a statement expression is an insufficient context"
+		 " for overload resolution");
+	  TREE_TYPE (stmt_expr) = error_mark_node;
+	  return error_mark_node;
+	}
+      else if (processing_template_decl)
 	{
 	  expr = build_stmt (input_location, EXPR_STMT, expr);
 	  expr = add_stmt (expr);
diff --git a/gcc/testsuite/g++.dg/pr84492.C b/gcc/testsuite/g++.dg/pr84492.C
new file mode 100644
index 000000000000..1a2922096d19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr84492.C
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-fpermissive" }
+
+template<int> int foo()
+{
+  return ({ foo; }); // { dg-error "insufficient context" }
+}
+
+int bar()
+{
+  return ({ foo; }); // { dg-error "insufficient context" }
+}
+
+void bar(int);
+
+typedef void (*bart)(int);
+
+bart barf()
+{
+  return ({ bar; }); // { dg-error "insufficient context" }
+}
+
+bool bark()
+{
+  return ({ barf; }); // ok, no overload
+}
+
+template <typename T>
+class C
+{
+  static int f();
+  bool g()
+  {
+    return ({ f; }); // ok, no overload
+  }
+  bool g(int)
+  {
+    return ({ g; }); // { dg-error "insufficient context" }
+  }
+};


-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer
Jason Merrill March 2, 2018, 7:02 p.m. | #3
OK.

On Fri, Mar 2, 2018 at 2:57 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
> On Feb 28, 2018, Jason Merrill <jason@redhat.com> wrote:

>

>> On Wed, Feb 28, 2018 at 7:06 AM, Alexandre Oliva <aoliva@redhat.com> wrote:

>>> We ICEd when returning a stmt expr that ends with an overloaded

>>> function.  It's ill-formed when we can't convert the function name to

>>> the return type, but we should say that, not ICE.

>

>> Hmm, what about the case where we could convert the function name to

>> the return type?  I think it should still be ill-formed for a

>> statement-expression to have an unresolved overload as its value.

>

> I was (not :-) thinking in those terms; I suppose one might wish ({x;})

> to be equivalent to (x), but one might also wish for stmt exprs to be

> self-contained, and I suppose you prefer the latter, or that there's

> consensus about how the stmt expr extension should be handled in this

> regard, so...

>

>> So finish_stmt_expr_expr should check type_unknown_p.

>

> [PR c++/84492] stmt expr ending with overload

>

> We ICEd when returning a stmt expr that ends with an overloaded

> function, because instantiate_type did not know what to do with

> STMT_EXPRs.  And it shouldn't have to: the expected type of a stmt

> expr cannot be used to resolve its value: an unresolved overload

> cannot supply the result of a stmt expr.  Catch that and report the

> error in the stmt expr before we have a chance to instantiate it.

>

> Regstrapped on i686- and x86_64-linux-gnu.  Ok?

>

> for  gcc/cp/ChangeLog

>

>         PR c++/84492

>         * semantics.c (finish_stmt_expr_expr): Reject unresolved

>         overloads used as stmt expr values.

>

> for  gcc/testsuite/ChangeLog

>

>         PR c++/84492

>         * g++.dg/pr84492.C: New.

> ---

>  gcc/cp/semantics.c             |    9 ++++++++-

>  gcc/testsuite/g++.dg/pr84492.C |   40 ++++++++++++++++++++++++++++++++++++++++

>  2 files changed, 48 insertions(+), 1 deletion(-)

>  create mode 100644 gcc/testsuite/g++.dg/pr84492.C

>

> diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c

> index 1ac1d23e7610..af401866b569 100644

> --- a/gcc/cp/semantics.c

> +++ b/gcc/cp/semantics.c

> @@ -2115,7 +2115,14 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr)

>      {

>        tree type = TREE_TYPE (expr);

>

> -      if (processing_template_decl)

> +      if (type && type_unknown_p (type))

> +       {

> +         error ("a statement expression is an insufficient context"

> +                " for overload resolution");

> +         TREE_TYPE (stmt_expr) = error_mark_node;

> +         return error_mark_node;

> +       }

> +      else if (processing_template_decl)

>         {

>           expr = build_stmt (input_location, EXPR_STMT, expr);

>           expr = add_stmt (expr);

> diff --git a/gcc/testsuite/g++.dg/pr84492.C b/gcc/testsuite/g++.dg/pr84492.C

> new file mode 100644

> index 000000000000..1a2922096d19

> --- /dev/null

> +++ b/gcc/testsuite/g++.dg/pr84492.C

> @@ -0,0 +1,40 @@

> +// { dg-do compile }

> +// { dg-options "-fpermissive" }

> +

> +template<int> int foo()

> +{

> +  return ({ foo; }); // { dg-error "insufficient context" }

> +}

> +

> +int bar()

> +{

> +  return ({ foo; }); // { dg-error "insufficient context" }

> +}

> +

> +void bar(int);

> +

> +typedef void (*bart)(int);

> +

> +bart barf()

> +{

> +  return ({ bar; }); // { dg-error "insufficient context" }

> +}

> +

> +bool bark()

> +{

> +  return ({ barf; }); // ok, no overload

> +}

> +

> +template <typename T>

> +class C

> +{

> +  static int f();

> +  bool g()

> +  {

> +    return ({ f; }); // ok, no overload

> +  }

> +  bool g(int)

> +  {

> +    return ({ g; }); // { dg-error "insufficient context" }

> +  }

> +};

>

>

> --

> Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/

> You must be the change you wish to see in the world. -- Gandhi

> Be Free! -- http://FSFLA.org/   FSF Latin America board member

> Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer

Patch

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 8348552a05b6..06630dc165d0 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -8013,7 +8013,8 @@  instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
   gcc_assert (TREE_CODE (rhs) == ADDR_EXPR
 	      || TREE_CODE (rhs) == COMPONENT_REF
 	      || is_overloaded_fn (rhs)
-	      || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL));
+	      || (flag_ms_extensions && TREE_CODE (rhs) == FUNCTION_DECL)
+	      || TREE_CODE (rhs) == STMT_EXPR);
 
   /* This should really only be used when attempting to distinguish
      what sort of a pointer to function we have.  For now, any
@@ -8073,6 +8074,9 @@  instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
       return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
     }
 
+    case STMT_EXPR:
+      return instantiate_type (lhstype, stmt_expr_value_expr (rhs), complain);
+
     case ERROR_MARK:
       return error_mark_node;
 
diff --git a/gcc/testsuite/g++.dg/pr84492.C b/gcc/testsuite/g++.dg/pr84492.C
new file mode 100644
index 000000000000..51fbd883a990
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr84492.C
@@ -0,0 +1,7 @@ 
+// { dg-do compile }
+// { dg-options "-fpermissive" }
+
+template<int> int foo()
+{
+  return ({ foo; }); // { dg-error "cannot resolve overloaded function" }
+}