diff options
author | Marek Polacek <polacek@redhat.com> | 2019-03-28 18:23:18 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-03-28 18:23:18 +0000 |
commit | c91b27155288e9869fc8345c689f7f6b90b0ee7e (patch) | |
tree | f27feea1b40cd6810496a8e21ebfb9e94cd223ab | |
parent | bb15c8b7f76f90ebcf234e4c772a0e21346ef301 (diff) | |
download | gcc-c91b27155288e9869fc8345c689f7f6b90b0ee7e.zip gcc-c91b27155288e9869fc8345c689f7f6b90b0ee7e.tar.gz gcc-c91b27155288e9869fc8345c689f7f6b90b0ee7e.tar.bz2 |
PR c++/89836 - bool constant expression and explicit conversions.
* call.c (build_converted_constant_expr_internal): New function,
renamed from...
(build_converted_constant_expr): ...this. New.
(build_converted_constant_bool_expr): New.
* cp-tree.h (build_converted_constant_bool_expr): Declare.
* decl.c (build_explicit_specifier): Call
build_converted_constant_bool_expr.
* g++.dg/cpp2a/explicit15.C: New test.
From-SVN: r270002
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/call.c | 50 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/explicit15.C | 10 |
6 files changed, 65 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b7c6c35..075e977 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2019-03-28 Marek Polacek <polacek@redhat.com> + + PR c++/89836 - bool constant expression and explicit conversions. + * call.c (build_converted_constant_expr_internal): New function, + renamed from... + (build_converted_constant_expr): ...this. New. + (build_converted_constant_bool_expr): New. + * cp-tree.h (build_converted_constant_bool_expr): Declare. + * decl.c (build_explicit_specifier): Call + build_converted_constant_bool_expr. + 2019-03-28 Jakub Jelinek <jakub@redhat.com> PR c++/89785 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 9efca73..bc51794 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4175,18 +4175,11 @@ build_user_type_conversion (tree totype, tree expr, int flags, return ret; } -/* Subroutine of convert_nontype_argument. - - EXPR is an expression used in a context that requires a converted - constant-expression, such as a template non-type parameter. Do any - necessary conversions (that are permitted for converted - constant-expressions) to convert it to the desired type. - - If conversion is successful, returns the converted expression; - otherwise, returns error_mark_node. */ +/* Worker for build_converted_constant_expr. */ -tree -build_converted_constant_expr (tree type, tree expr, tsubst_flags_t complain) +static tree +build_converted_constant_expr_internal (tree type, tree expr, + int flags, tsubst_flags_t complain) { conversion *conv; void *p; @@ -4200,8 +4193,7 @@ build_converted_constant_expr (tree type, tree expr, tsubst_flags_t complain) p = conversion_obstack_alloc (0); conv = implicit_conversion (type, TREE_TYPE (expr), expr, - /*c_cast_p=*/false, - LOOKUP_IMPLICIT, complain); + /*c_cast_p=*/false, flags, complain); /* A converted constant expression of type T is an expression, implicitly converted to type T, where the converted expression is a constant @@ -4304,6 +4296,38 @@ build_converted_constant_expr (tree type, tree expr, tsubst_flags_t complain) return expr; } +/* Subroutine of convert_nontype_argument. + + EXPR is an expression used in a context that requires a converted + constant-expression, such as a template non-type parameter. Do any + necessary conversions (that are permitted for converted + constant-expressions) to convert it to the desired type. + + This function doesn't consider explicit conversion functions. If + you mean to use "a contextually converted constant expression of type + bool", use build_converted_constant_bool_expr. + + If conversion is successful, returns the converted expression; + otherwise, returns error_mark_node. */ + +tree +build_converted_constant_expr (tree type, tree expr, tsubst_flags_t complain) +{ + return build_converted_constant_expr_internal (type, expr, LOOKUP_IMPLICIT, + complain); +} + +/* Used to create "a contextually converted constant expression of type + bool". This differs from build_converted_constant_expr in that it + also considers explicit conversion functions. */ + +tree +build_converted_constant_bool_expr (tree expr, tsubst_flags_t complain) +{ + return build_converted_constant_expr_internal (boolean_type_node, expr, + LOOKUP_NORMAL, complain); +} + /* Do any initial processing on the arguments to a function call. */ static vec<tree, va_gc> * diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3fe91ad..fd612b0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6233,6 +6233,7 @@ extern int remaining_arguments (tree); extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t); extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int); extern tree build_converted_constant_expr (tree, tree, tsubst_flags_t); +extern tree build_converted_constant_bool_expr (tree, tsubst_flags_t); extern tree perform_direct_initialization_if_possible (tree, tree, bool, tsubst_flags_t); extern tree in_charge_arg_for_name (tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c8435e2..c46a3966 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -16700,7 +16700,7 @@ build_explicit_specifier (tree expr, tsubst_flags_t complain) expr = instantiate_non_dependent_expr_sfinae (expr, complain); /* Don't let convert_like_real create more template codes. */ processing_template_decl_sentinel s; - expr = build_converted_constant_expr (boolean_type_node, expr, complain); + expr = build_converted_constant_bool_expr (expr, complain); expr = cxx_constant_value (expr); return expr; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9c98973..0210cd7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-03-28 Marek Polacek <polacek@redhat.com> + + PR c++/89836 - bool constant expression and explicit conversions. + * g++.dg/cpp2a/explicit15.C: New test. + 2019-03-28 Jakub Jelinek <jakub@redhat.com> PR c/89812 diff --git a/gcc/testsuite/g++.dg/cpp2a/explicit15.C b/gcc/testsuite/g++.dg/cpp2a/explicit15.C new file mode 100644 index 0000000..e0058f6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/explicit15.C @@ -0,0 +1,10 @@ +// PR c++/89836 +// { dg-do compile { target c++2a } } + +struct W { + constexpr explicit operator bool() { return true; }; +}; + +struct U { + explicit(W()) U(int); +}; |