aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-03-28 18:23:18 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-03-28 18:23:18 +0000
commitc91b27155288e9869fc8345c689f7f6b90b0ee7e (patch)
treef27feea1b40cd6810496a8e21ebfb9e94cd223ab
parentbb15c8b7f76f90ebcf234e4c772a0e21346ef301 (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/cp/call.c50
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/explicit15.C10
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);
+};