Message ID | orfu5lpbcf.fsf@lxoliva.fsfla.org |
---|---|
State | New |
Headers | show |
Series | [PR,c++/84492] return stmt expr ending with overload | expand |
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
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" } + } +};
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
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" } +}