From 2a4030effa436cc4c6a537e633b0b0338b2b3ad4 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 15 Nov 2018 19:54:25 +0000 Subject: [PATCH] [PR c++/86246] ICE tsubst explicit operator call https://gcc.gnu.org/ml/gcc-patches/2018-11/msg01405.html PR c++/86246 PR c++/87989 * typeck.c (finish_class_member_access_expr): Conversion operator to dependent type is dependent. * g++.dg/template/pr86246.C: New. * g++.dg/template/pr87989.C: New. From-SVN: r266193 --- gcc/cp/ChangeLog | 7 +++++ gcc/cp/typeck.c | 7 ++++- gcc/testsuite/ChangeLog | 9 +++++- gcc/testsuite/g++.dg/template/pr86246.C | 38 +++++++++++++++++++++++++ gcc/testsuite/g++.dg/template/pr87989.C | 20 +++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/pr86246.C create mode 100644 gcc/testsuite/g++.dg/template/pr87989.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6d87c293dd6..deec822b924 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2018-11-15 Nathan Sidwell + + PR c++/86246 + PR c++/87989 + * typeck.c (finish_class_member_access_expr): Conversion operator + to dependent type is dependent. + 2018-11-15 Paolo Carlini * constexpr.c (ensure_literal_type_for_constexpr_object): Use diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 7b42d539dfb..81cb4057a5b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2884,7 +2884,12 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, expression is dependent. */ || (TREE_CODE (name) == SCOPE_REF && TYPE_P (TREE_OPERAND (name, 0)) - && dependent_scope_p (TREE_OPERAND (name, 0)))) + && dependent_scope_p (TREE_OPERAND (name, 0))) + /* If NAME is operator T where "T" is dependent, we can't + lookup until we instantiate the T. */ + || (TREE_CODE (name) == IDENTIFIER_NODE + && IDENTIFIER_CONV_OP_P (name) + && dependent_type_p (TREE_TYPE (name)))) { dependent: return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24ea36ec912..dc8625600dc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-11-15 Nathan Sidwell + + PR c++/86246 + PR c++/87989 + * g++.dg/template/pr86246.C: New. + * g++.dg/template/pr87989.C: New. + 2018-11-15 Paolo Carlini * g++.dg/cpp0x/constexpr-diag3.C: Check locations too. @@ -39,7 +46,7 @@ PR tree-optimization/88031 * gcc.dg/pr88031.c: New testcase. -2018-11-15 Wilco Dijkstra +2018-11-15 Wilco Dijkstra * gcc.target/aarch64/pr62178.c: Fix spaces. diff --git a/gcc/testsuite/g++.dg/template/pr86246.C b/gcc/testsuite/g++.dg/template/pr86246.C new file mode 100644 index 00000000000..43ce545c96c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr86246.C @@ -0,0 +1,38 @@ +// { dg-do compile { target c++11 } } +// PR c++/86246 ICE in tsubst + +namespace std { + template struct is_class { + static constexpr bool value = true; + }; + template<> struct is_class { + static constexpr bool value = false; + }; +} + +class MyClass { + public: + operator double() const { + return 1; + } + template + operator T() const { + static_assert(std::is_class::value, "problem"); + return T(); + } +}; + +template +void SetValue(const MyClass& obj, T* value) { + // erroneously dispatched to operator T when T is double + *value = obj.operator T(); +} + +int main() { + MyClass obj; + // works fine + obj.operator double (); + double x; + // error, when operator T is called in SetValue + SetValue(obj, &x); +} diff --git a/gcc/testsuite/g++.dg/template/pr87989.C b/gcc/testsuite/g++.dg/template/pr87989.C new file mode 100644 index 00000000000..34e6e95dd67 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr87989.C @@ -0,0 +1,20 @@ +// PR c++/87989 +// { dg-do link } +// Resolved to template instantiation rather than non-template fn. + +struct X { + template operator T() const; // no definition + operator float() const {return 0.f;} +}; + +template +T f(const X &x) { + // Resoved in error to X::operator float() const` + // instead of correct `X::operator float() const + return x.operator T(); +} + +int main () +{ + return f(X ()); +} -- 2.30.2