diff mbox series

C++ PATCH for c++/85695, rejects-valid with constexpr if

Message ID 20180508183254.GT8673@redhat.com
State New
Headers show
Series C++ PATCH for c++/85695, rejects-valid with constexpr if | expand

Commit Message

Marek Polacek May 8, 2018, 6:33 p.m. UTC
Here we were confused by a typedef so the "== boolean_type_node" check didn't
work as intended.  We can use TYPE_MAIN_VARIANT to see the real type.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-05-08  Marek Polacek  <polacek@redhat.com>

	PR c++/85695
	* semantics.c (finish_if_stmt_cond): See through typedefs.

	* g++.dg/cpp1z/constexpr-if22.C: New test.

Comments

Jason Merrill May 8, 2018, 7:22 p.m. UTC | #1
OK for trunk and 8.

On Tue, May 8, 2018 at 2:33 PM, Marek Polacek <polacek@redhat.com> wrote:
> Here we were confused by a typedef so the "== boolean_type_node" check didn't
> work as intended.  We can use TYPE_MAIN_VARIANT to see the real type.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-05-08  Marek Polacek  <polacek@redhat.com>
>
>         PR c++/85695
>         * semantics.c (finish_if_stmt_cond): See through typedefs.
>
>         * g++.dg/cpp1z/constexpr-if22.C: New test.
>
> diff --git gcc/cp/semantics.c gcc/cp/semantics.c
> index 2b2b51b2a7e..195286ca751 100644
> --- gcc/cp/semantics.c
> +++ gcc/cp/semantics.c
> @@ -736,7 +736,7 @@ finish_if_stmt_cond (tree cond, tree if_stmt)
>        && !instantiation_dependent_expression_p (cond)
>        /* Wait until instantiation time, since only then COND has been
>          converted to bool.  */
> -      && TREE_TYPE (cond) == boolean_type_node)
> +      && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
>      {
>        cond = instantiate_non_dependent_expr (cond);
>        cond = cxx_constant_value (cond, NULL_TREE);
> diff --git gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C
> index e69de29bb2d..76f0c73476b 100644
> --- gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C
> +++ gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C
> @@ -0,0 +1,21 @@
> +// PR c++/85695
> +// { dg-options -std=c++17 }
> +
> +template <typename T, T v>
> +struct integral_constant {
> +    using value_type = T;
> +    static constexpr const value_type value = v;
> +    constexpr operator value_type (void) const { return value; }
> +};
> +template <typename T> struct is_trivial
> +    : public integral_constant<bool, __is_trivial(T)> {};
> +
> +template <typename T>
> +T clone_object (const T& p)
> +{
> +    if constexpr (is_trivial<T>::value)
> +        return p;
> +    else
> +        return p.clone();
> +}
> +int main (void) { return clone_object(0); }
diff mbox series

Patch

diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index 2b2b51b2a7e..195286ca751 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -736,7 +736,7 @@  finish_if_stmt_cond (tree cond, tree if_stmt)
       && !instantiation_dependent_expression_p (cond)
       /* Wait until instantiation time, since only then COND has been
 	 converted to bool.  */
-      && TREE_TYPE (cond) == boolean_type_node)
+      && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
     {
       cond = instantiate_non_dependent_expr (cond);
       cond = cxx_constant_value (cond, NULL_TREE);
diff --git gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C
index e69de29bb2d..76f0c73476b 100644
--- gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C
+++ gcc/testsuite/g++.dg/cpp1z/constexpr-if22.C
@@ -0,0 +1,21 @@ 
+// PR c++/85695
+// { dg-options -std=c++17 }
+
+template <typename T, T v>
+struct integral_constant {
+    using value_type = T;
+    static constexpr const value_type value = v;
+    constexpr operator value_type (void) const { return value; }
+};
+template <typename T> struct is_trivial
+    : public integral_constant<bool, __is_trivial(T)> {};
+
+template <typename T>
+T clone_object (const T& p)
+{
+    if constexpr (is_trivial<T>::value)
+        return p;
+    else
+        return p.clone();
+}
+int main (void) { return clone_object(0); }