aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/pt.c13
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-conv3.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-conv4.C25
5 files changed, 76 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 17c9aa7..f766f47 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2019-04-05 Marek Polacek <polacek@redhat.com>
+
+ PR c++/87145 - bogus error converting class type in template arg list.
+ * pt.c (convert_nontype_argument): Don't call
+ build_converted_constant_expr if it could involve calling a conversion
+ function with a instantiation-dependent constructor as its argument.
+
2019-04-05 Martin Sebor <msebor@redhat.com>
PR bootstrap/89980
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 40d954d..f800131 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6837,6 +6837,19 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
|| cxx_dialect >= cxx17)
{
+ /* Calling build_converted_constant_expr might create a call to
+ a conversion function with a value-dependent argument, which
+ could invoke taking the address of a temporary representing
+ the result of the conversion. */
+ if (COMPOUND_LITERAL_P (expr)
+ && CONSTRUCTOR_IS_DEPENDENT (expr)
+ && MAYBE_CLASS_TYPE_P (expr_type)
+ && TYPE_HAS_CONVERSION (expr_type))
+ {
+ expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
+ IMPLICIT_CONV_EXPR_NONTYPE_ARG (expr) = true;
+ return expr;
+ }
/* C++17: A template-argument for a non-type template-parameter shall
be a converted constant expression (8.20) of the type of the
template-parameter. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dc6f911..b854b57 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-04-05 Marek Polacek <polacek@redhat.com>
+
+ PR c++/87145 - bogus error converting class type in template arg list.
+ * g++.dg/cpp0x/constexpr-conv3.C: New test.
+ * g++.dg/cpp0x/constexpr-conv4.C: New test.
+
2019-04-05 Martin Sebor <msebor@redhat.com>
PR bootstrap/89980
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-conv3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-conv3.C
new file mode 100644
index 0000000..3f47c58
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-conv3.C
@@ -0,0 +1,25 @@
+// PR c++/87145
+// { dg-do compile { target c++11 } }
+
+template<typename T, T t> struct integral_constant {
+ static constexpr T value = t;
+};
+
+enum class Enum : unsigned {};
+
+struct Pod {
+ unsigned val;
+
+ constexpr operator Enum() const {
+ return static_cast<Enum>(val);
+ }
+};
+
+template<unsigned N>
+constexpr void foo() {
+ using Foo = integral_constant<Enum, Pod{N}>;
+}
+
+int main() {
+ foo<2>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-conv4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-conv4.C
new file mode 100644
index 0000000..f4e3f00
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-conv4.C
@@ -0,0 +1,25 @@
+// PR c++/87145
+// { dg-do compile { target c++11 } }
+
+struct S {
+ int val;
+
+ constexpr operator int() const {
+ return static_cast<int>(val);
+ }
+};
+
+template<int N>
+struct F { };
+
+template<unsigned N>
+constexpr void foo() {
+ F<int{N}> f;
+ F<S{N}> f2;
+}
+
+int
+main()
+{
+ foo<2>();
+}