diff options
author | Marek Polacek <polacek@redhat.com> | 2019-01-27 20:19:41 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-01-27 20:19:41 +0000 |
commit | f8ec35c322fefe5609439a0dcfff0da0acbc9f72 (patch) | |
tree | 303d78bfca602c2ab5f6769b662b99ffebfb6f37 | |
parent | 73a54a61930af1aa355fdfb566c7a07af3a60cf8 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 5 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wnarrowing15.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/Wnarrowing16.C | 16 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-decltype3.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/Wnarrowing1.C | 5 |
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" } |