diff mbox series

C++ PATCH for c++/88815 - narrowing conversion lost in decltype.

Message ID 20190117190817.GL19569@redhat.com
State New
Headers show
Series C++ PATCH for c++/88815 - narrowing conversion lost in decltype. | expand

Commit Message

Marek Polacek Jan. 17, 2019, 7:08 p.m. UTC
When r265789 changed instantiation_dependent_r in such a way that
TEMPLATE_PARM_INDEXes are instantiation-dependent only when their
types are dependent, it broke this test.  The test uses a combination
of SFINAE and narrow conversions to detect if an expression is constexpr.
"p" is a template parameter whose type is not dependent, so now it's not
considered instantiation-dependent.

The problem is that when finish_decltype_type sees something that isn't
instantiation_dependent_uneval_expression_p, it just looks at the type
of the expression and lets it go.  But it misses a narrowing conversion in

  decltype(int{(p(), 0U)})

which is narrowing or not depending on if p() is constant.  To figure that
out we need to create a DECLTYPE_TYPE so that we actually instantiate the
expression.

The question is what, specifically, should we check in
instantiation_dependent_r.  I went with checking if a compound literal has
something value dependent, then we need to instantion so as not to lose
a possible narrowing conversion.

In a non-SFINAE context we don't give any narrowing warnings, that's a bug
I have another patch for, but it's not dependent on this patch.  Though I
can imagine there's a patch fixing both these cases.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2019-01-17  Marek Polacek  <polacek@redhat.com>

	PR c++/88815 - narrowing conversion lost in decltype.
	* pt.c (instantiation_dependent_r): Consider a compound literal
	with a value-dependent expression dependent.

	* g++.dg/cpp0x/constexpr-decltype3.C: New test.
diff mbox series

Patch

diff --git gcc/cp/pt.c gcc/cp/pt.c
index e4f76478f54..d0f5dbeec8e 100644
--- gcc/cp/pt.c
+++ gcc/cp/pt.c
@@ -25800,6 +25800,14 @@  instantiation_dependent_r (tree *tp, int *walk_subtrees,
 	return *tp;
       break;
 
+    case CONSTRUCTOR:
+      /* A compound literal with a value-dependent expression
+	 might contain narrowing conversion.  */
+      if (TREE_HAS_CONSTRUCTOR (*tp)
+	  && value_dependent_expression_p (*tp))
+	return *tp;
+      break;
+
     default:
       break;
     }
diff --git gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C
new file mode 100644
index 00000000000..fd05366de50
--- /dev/null
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C
@@ -0,0 +1,25 @@ 
+// PR c++/88815
+// { dg-do compile { target c++11 } }
+
+struct true_type {
+    constexpr operator bool() const { return true; }
+};
+
+struct false_type {
+    constexpr operator bool() const { return false; }
+};
+
+template<int (*p)()>
+true_type is_constexpr_impl(decltype(int{(p(), 0U)}));
+
+template<int (*p)()>
+false_type is_constexpr_impl(...);
+
+template<int (*p)()>
+using is_constexpr = decltype(is_constexpr_impl<p>(0));
+
+constexpr int f() { return 0; }
+int g() { return 0; }
+
+static_assert(is_constexpr<f>(), "");
+static_assert(!is_constexpr<g>(), "");