PR c++/89836 - bool constant expression and explicit conversions.
authorMarek Polacek <polacek@redhat.com>
Thu, 28 Mar 2019 18:23:18 +0000 (18:23 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 28 Mar 2019 18:23:18 +0000 (18:23 +0000)
* 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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/explicit15.C [new file with mode: 0644]

index b7c6c35a16035cdae5faccc1e60a4cf73a4e5f70..075e977b70b3c59059a3fc2636d26e96f4816008 100644 (file)
@@ -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
index 9efca735b16205cbadc9ffe840a9175ee638bc0f..bc5179416a54d882e82956c5f83ca303eb9c23a0 100644 (file)
@@ -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> *
index 3fe91ad216089f12fce8e2b5499b4644186c8709..fd612b0dbb1bc4d4b7d96c9177cce4987f6eb763 100644 (file)
@@ -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);
index c8435e29491e029e7999455cf5082384608e3060..c46a39665bd9bb441eb2671acb2c3d909c05302b 100644 (file)
@@ -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;
 }
index 9c98973f76447bbc6d77e18d11eb588a06c81da3..0210cd72935049a295b79367c3489d12d4a2a444 100644 (file)
@@ -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 (file)
index 0000000..e0058f6
--- /dev/null
@@ -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);
+};