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