aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@gcc.gnu.org>2018-11-15 19:54:25 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2018-11-15 19:54:25 +0000
commit2a4030effa436cc4c6a537e633b0b0338b2b3ad4 (patch)
tree838ffd8472ee6e696bbb7f993e0daf1e708a05a8 /gcc
parentf2935576e990ec5e383138622515d393f7227500 (diff)
downloadgcc-2a4030effa436cc4c6a537e633b0b0338b2b3ad4.zip
gcc-2a4030effa436cc4c6a537e633b0b0338b2b3ad4.tar.gz
gcc-2a4030effa436cc4c6a537e633b0b0338b2b3ad4.tar.bz2
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/template/pr86246.C38
-rw-r--r--gcc/testsuite/g++.dg/template/pr87989.C20
5 files changed, 79 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6d87c29..deec822 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-15 Nathan Sidwell <nathan@acm.org>
+
+ 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 <paolo.carlini@oracle.com>
* constexpr.c (ensure_literal_type_for_constexpr_object): Use
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7b42d53..81cb405 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 24ea36e..dc86256 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2018-11-15 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/86246
+ PR c++/87989
+ * g++.dg/template/pr86246.C: New.
+ * g++.dg/template/pr87989.C: New.
+
2018-11-15 Paolo Carlini <paolo.carlini@oracle.com>
* 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 <wdijkstr@arm.com>
+2018-11-15 Wilco Dijkstra <wdijkstr@arm.com>
* 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 0000000..43ce545
--- /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<typename T> struct is_class {
+ static constexpr bool value = true;
+ };
+ template<> struct is_class<double> {
+ static constexpr bool value = false;
+ };
+}
+
+class MyClass {
+ public:
+ operator double() const {
+ return 1;
+ }
+ template<typename T>
+ operator T() const {
+ static_assert(std::is_class<T>::value, "problem");
+ return T();
+ }
+};
+
+template<typename T>
+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 0000000..34e6e95
--- /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 <class T> operator T() const; // no definition
+ operator float() const {return 0.f;}
+};
+
+template <class T>
+T f(const X &x) {
+ // Resoved in error to X::operator float<float>() const`
+ // instead of correct `X::operator float() const
+ return x.operator T();
+}
+
+int main ()
+{
+ return f<float>(X ());
+}