On Fri, Apr 6, 2018 at 2:17 PM, Marek Polacek <pola...@redhat.com> wrote:
> On Mon, Mar 26, 2018 at 01:17:22PM -0400, Jason Merrill wrote:
>> On Sat, Mar 24, 2018 at 6:59 AM, Marek Polacek <pola...@redhat.com> wrote:
>> > Recently the code in finish_static_assert was changed to use
>> > perform_implicit_conversion_flags followed by fold_non_dependent_expr.  
>> > That
>> > broke this test becase when in a template, p_i_c_f merely wraps the expr in
>> > an IMPLICIT_CONV_EXPR.  fold_non_dependent_expr should be able to fold it 
>> > to
>> > a constant but it gave up because is_nondependent_constant_expression 
>> > returned
>> > false.  Jason suggested to fix this roughly like the following, i.e. 
>> > consider
>> > conversions from classes to literal types potentially constant.
>> >
>> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
>> >
>> > 2018-03-24  Marek Polacek  <pola...@redhat.com>
>> >
>> >         PR c++/85032
>> >         * constexpr.c (potential_constant_expression_1): Consider 
>> > conversions
>> >         from classes to literal types potentially constant.
>> >
>> >         * g++.dg/cpp0x/pr51225.C: Adjust error message.
>> >         * g++.dg/cpp1z/constexpr-if17.C: New test.
>> >
>> > diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
>> > index bebd9f5b5d0..c4b5afe90a2 100644
>> > --- gcc/cp/constexpr.c
>> > +++ gcc/cp/constexpr.c
>> > @@ -5768,6 +5768,23 @@ potential_constant_expression_1 (tree t, bool 
>> > want_rval, bool strict, bool now,
>> >                       TREE_TYPE (t));
>> >           return false;
>> >         }
>> > +      /* This might be a conversion from a class to a literal type.  Let's
>> > +        consider it potentially constant since the conversion might be
>> > +        a constexpr user-defined conversion.  */
>> > +      else if (cxx_dialect >= cxx11
>> > +              && COMPLETE_TYPE_P (TREE_TYPE (t))
>> > +              && literal_type_p (TREE_TYPE (t))
>>
>> We probably need to allow dependent types here, too.  And incomplete
>> classes, which might turn out to be literal later.
>
> Ok, I've allowed incomplete types, too.  And I think the patch also allows
> dependent types.  Or did you mean using
>    && (TREE_TYPE (t) == NULL_TREE
>        || !COMPLETE_TYPE_P (TREE_TYPE (t))
>        || literal_type_p (TREE_TYPE (t)))
> ?  That doesn't seem to be needed.

I meant dependent_type_p (TREE_TYPE (t)).  I suppose checking
COMPLETE_TYPE_P will cover that by accident, but I'd prefer to make it
explicit.

> +         /* If this is a dependent type, it could end up being a class
> +            with conversions.  */
> +         if (type == NULL_TREE || WILDCARD_TYPE_P (type))
> +           return true;
> +         /* Or a non-dependent class which has conversions.  */
> +         else if (CLASS_TYPE_P (type) && TYPE_HAS_CONVERSION (type))
> +           return true;

And here, a dependent class type like A<T*> could fail both of these
tests and still end up with conversions when instantiated.  We should
check dependent_scope_p as well as TYPE_HAS_CONVERSION.

Jason

Reply via email to