aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-01-27 20:19:41 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-01-27 20:19:41 +0000
commitf8ec35c322fefe5609439a0dcfff0da0acbc9f72 (patch)
tree303d78bfca602c2ab5f6769b662b99ffebfb6f37 /gcc
parent73a54a61930af1aa355fdfb566c7a07af3a60cf8 (diff)
downloadgcc-f8ec35c322fefe5609439a0dcfff0da0acbc9f72.zip
gcc-f8ec35c322fefe5609439a0dcfff0da0acbc9f72.tar.gz
gcc-f8ec35c322fefe5609439a0dcfff0da0acbc9f72.tar.bz2
PR c++/88815 - narrowing conversion lost in decltype.
PR c++/78244 - narrowing conversion in template not detected. * cp-tree.h (CONSTRUCTOR_IS_DEPENDENT): New. * pt.c (instantiation_dependent_r): Consider a CONSTRUCTOR with CONSTRUCTOR_IS_DEPENDENT instantiation-dependent. * semantics.c (finish_compound_literal): When the compound literal isn't instantiation-dependent and the type isn't type-dependent, fall back to the normal processing. Set CONSTRUCTOR_IS_DEPENDENT. * g++.dg/cpp0x/Wnarrowing15.C: New test. * g++.dg/cpp0x/Wnarrowing16.C: New test. * g++.dg/cpp0x/constexpr-decltype3.C: New test. * g++.dg/cpp1y/Wnarrowing1.C: New test. From-SVN: r268321
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/cp/semantics.c5
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/Wnarrowing16.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C5
9 files changed, 91 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c2993db..dcac8e7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,14 @@
2019-01-27 Marek Polacek <polacek@redhat.com>
+ PR c++/88815 - narrowing conversion lost in decltype.
+ PR c++/78244 - narrowing conversion in template not detected.
+ * cp-tree.h (CONSTRUCTOR_IS_DEPENDENT): New.
+ * pt.c (instantiation_dependent_r): Consider a CONSTRUCTOR with
+ CONSTRUCTOR_IS_DEPENDENT instantiation-dependent.
+ * semantics.c (finish_compound_literal): When the compound literal
+ isn't instantiation-dependent and the type isn't type-dependent,
+ fall back to the normal processing. Set CONSTRUCTOR_IS_DEPENDENT.
+
PR c++/89024 - ICE with incomplete enum type.
* call.c (standard_conversion): When converting an
ARITHMETIC_TYPE_P to an incomplete type, return NULL.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index cd902ce..77e1425 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -424,6 +424,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
DECL_FINAL_P (in FUNCTION_DECL)
QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF)
DECLTYPE_FOR_INIT_CAPTURE (in DECLTYPE_TYPE)
+ CONSTRUCTOR_IS_DEPENDENT (in CONSTRUCTOR)
TINFO_USED_TEMPLATE_ID (in TEMPLATE_INFO)
PACK_EXPANSION_SIZEOF_P (in *_PACK_EXPANSION)
OVL_USING_P (in OVERLOAD)
@@ -4205,6 +4206,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
B b{1,2}, not B b({1,2}) or B b = {1,2}. */
#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE)))
+/* True if this CONSTRUCTOR is instantiation-dependent and needs to be
+ substituted. */
+#define CONSTRUCTOR_IS_DEPENDENT(NODE) \
+ (TREE_LANG_FLAG_1 (CONSTRUCTOR_CHECK (NODE)))
+
/* True if this CONSTRUCTOR should not be used as a variable initializer
because it was loaded from a constexpr variable with mutable fields. */
#define CONSTRUCTOR_MUTABLE_POISON(NODE) \
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 48c180c..f8b3054 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -25815,6 +25815,11 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
return *tp;
break;
+ case CONSTRUCTOR:
+ if (CONSTRUCTOR_IS_DEPENDENT (*tp))
+ return *tp;
+ break;
+
default:
break;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7219139..786f18a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2795,11 +2795,14 @@ finish_compound_literal (tree type, tree compound_literal,
return error_mark_node;
}
- if (processing_template_decl)
+ if (instantiation_dependent_expression_p (compound_literal)
+ || dependent_type_p (type))
{
TREE_TYPE (compound_literal) = type;
/* Mark the expression as a compound literal. */
TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
+ /* And as instantiation-dependent. */
+ CONSTRUCTOR_IS_DEPENDENT (compound_literal) = true;
if (fcl_context == fcl_c99)
CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1;
return compound_literal;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5438d4f..9149664 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
2019-01-27 Marek Polacek <polacek@redhat.com>
+ PR c++/88815 - narrowing conversion lost in decltype.
+ PR c++/78244 - narrowing conversion in template not detected.
+ * g++.dg/cpp0x/Wnarrowing15.C: New test.
+ * g++.dg/cpp0x/Wnarrowing16.C: New test.
+ * g++.dg/cpp0x/constexpr-decltype3.C: New test.
+ * g++.dg/cpp1y/Wnarrowing1.C: New test.
+
PR c++/89024 - ICE with incomplete enum type.
* g++.dg/cpp0x/enum37.C: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C
new file mode 100644
index 0000000..4e7c17d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C
@@ -0,0 +1,14 @@
+// PR c++/78244
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+auto f1() -> decltype(int{2.0}, void()) { } // { dg-error "narrowing conversion" }
+
+template <typename T>
+auto f2() -> decltype(int{2.0}) { return 1; } // { dg-error "narrowing conversion" }
+
+template <typename T>
+auto f3() -> decltype(void(), int{2.0}) { return 1; } // { dg-error "narrowing conversion" }
+
+template <typename T>
+auto f4() -> decltype((int{2.0})) { return 1; } // { dg-error "narrowing conversion" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing16.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing16.C
new file mode 100644
index 0000000..21394be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing16.C
@@ -0,0 +1,16 @@
+// PR c++/78244
+// { dg-do compile { target c++11 } }
+
+struct S { int d; };
+
+template <typename T>
+auto f1() -> decltype(S{2.0}, void()) { } // { dg-error "narrowing conversion" }
+
+template <typename T>
+auto f2() -> decltype(S{2.0}, 1) { return 1; } // { dg-error "narrowing conversion" }
+
+template <typename T>
+auto f3() -> decltype(void(), S{2.0}, 1) { return 1; } // { dg-error "narrowing conversion" }
+
+template <typename T>
+auto f4() -> decltype((S{2.0}, 1)) { return 1; } // { dg-error "narrowing conversion" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C
new file mode 100644
index 0000000..fd05366
--- /dev/null
+++ b/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>(), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C b/gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C
new file mode 100644
index 0000000..e1e4995
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C
@@ -0,0 +1,5 @@
+// PR c++/78244
+// { dg-do compile { target c++14 } }
+
+template<typename>
+decltype(int{1.1}) v; // { dg-error "narrowing conversion" }