From 2ea2a74dceda4b4ddf7433f2c1d9ab72aa2bd0b0 Mon Sep 17 00:00:00 2001
From: Marek Polacek <polacek@redhat.com>
Date: Wed, 16 Jan 2019 15:58:34 +0000
Subject: [PATCH] PR c++/78244 - narrowing conversion in template not detected.

* call.c (perform_implicit_conversion_flags): Set
	IMPLICIT_CONV_EXPR_BRACED_INIT.
	* cp-tree.h (IMPLICIT_CONV_EXPR_BRACED_INIT): New.
	* pt.c (tsubst_copy_and_build): Use it.

	* g++.dg/cpp0x/Wnarrowing13.C: New test.
	* g++.dg/cpp0x/Wnarrowing14.C: New test.

From-SVN: r267976
---
 gcc/cp/ChangeLog                          |  8 ++++++++
 gcc/cp/call.c                             |  2 ++
 gcc/cp/cp-tree.h                          |  6 ++++++
 gcc/cp/pt.c                               |  2 ++
 gcc/testsuite/ChangeLog                   |  6 ++++++
 gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C |  8 ++++++++
 gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C | 17 +++++++++++++++++
 7 files changed, 49 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7cf0ffb..6adb0e4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2019-01-16  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/78244 - narrowing conversion in template not detected.
+	* call.c (perform_implicit_conversion_flags): Set
+	IMPLICIT_CONV_EXPR_BRACED_INIT.
+	* cp-tree.h (IMPLICIT_CONV_EXPR_BRACED_INIT): New.
+	* pt.c (tsubst_copy_and_build): Use it.
+
 2019-01-15  David Malcolm  <dmalcolm@redhat.com>
 
 	PR c++/88795
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8bc8566..4f04b61 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -11018,6 +11018,8 @@ perform_implicit_conversion_flags (tree type, tree expr,
       expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
       if (!(flags & LOOKUP_ONLYCONVERTING))
 	IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true;
+      if (flags & LOOKUP_NO_NARROWING)
+	IMPLICIT_CONV_EXPR_BRACED_INIT (expr) = true;
     }
   else
     expr = convert_like (conv, expr, complain);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6a20043..1c85b37 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -442,6 +442,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
       OVL_HIDDEN_P (in OVERLOAD)
       SWITCH_STMT_NO_BREAK_P (in SWITCH_STMT)
       LAMBDA_EXPR_CAPTURE_OPTIMIZED (in LAMBDA_EXPR)
+      IMPLICIT_CONV_EXPR_BRACED_INIT (in IMPLICIT_CONV_EXPR)
    3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
       ICS_BAD_FLAG (in _CONV)
       FN_TRY_BLOCK_P (in TRY_BLOCK)
@@ -4229,6 +4230,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define IMPLICIT_CONV_EXPR_NONTYPE_ARG(NODE) \
   (TREE_LANG_FLAG_1 (IMPLICIT_CONV_EXPR_CHECK (NODE)))
 
+/* True if NODE represents a conversion for braced-init-list in a
+   template.  Set by perform_implicit_conversion_flags.  */
+#define IMPLICIT_CONV_EXPR_BRACED_INIT(NODE) \
+  (TREE_LANG_FLAG_2 (IMPLICIT_CONV_EXPR_CHECK (NODE)))
+
 /* Nonzero means that an object of this type cannot be initialized using
    an initializer list.  */
 #define CLASSTYPE_NON_AGGREGATE(NODE) \
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c6fc1cf..83bceb2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18210,6 +18210,8 @@ tsubst_copy_and_build (tree t,
 	int flags = LOOKUP_IMPLICIT;
 	if (IMPLICIT_CONV_EXPR_DIRECT_INIT (t))
 	  flags = LOOKUP_NORMAL;
+	if (IMPLICIT_CONV_EXPR_BRACED_INIT (t))
+	  flags |= LOOKUP_NO_NARROWING;
 	RETURN (perform_implicit_conversion_flags (type, expr, complain,
 						  flags));
       }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d8f46a0..df36f5e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-16  Marek Polacek  <polacek@redhat.com>
+
+	PR c++/78244 - narrowing conversion in template not detected.
+	* g++.dg/cpp0x/Wnarrowing13.C: New test.
+	* g++.dg/cpp0x/Wnarrowing14.C: New test.
+
 2019-01-16  Jakub Jelinek  <jakub@redhat.com>
 
 	PR c/51628
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C
new file mode 100644
index 0000000..3750f29
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing13.C
@@ -0,0 +1,8 @@
+// PR c++/78244
+// { dg-do compile { target c++11 } }
+
+template<typename>
+struct S {
+  static const int i{1.1}; // { dg-error "narrowing conversion" }
+  static const int i2 = {1.1}; // { dg-error "narrowing conversion" }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C
new file mode 100644
index 0000000..1aa2219
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing14.C
@@ -0,0 +1,17 @@
+// PR c++/78244
+// { dg-do compile { target c++11 } }
+
+using Number = unsigned int;
+
+template <int>
+struct S {
+  S() {
+    const Number x = {-1}; // { dg-error "narrowing conversion" }
+    (void)x;
+  }
+};
+
+int main()
+{
+  S<1> s;
+}
--
libgit2 0.26.0