Message ID | 20180508183254.GT8673@redhat.com |
---|---|
State | New |
Headers | show |
Series | C++ PATCH for c++/85695, rejects-valid with constexpr if | expand |
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 --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); }