On Wed, Feb 26, 2020 at 09:41:14PM -0500, Jason Merrill wrote:
> On 2/26/20 9:31 PM, Marek Polacek wrote:
> > On Wed, Feb 26, 2020 at 05:54:03PM -0500, Jason Merrill wrote:
> > > On 2/26/20 3:44 PM, Marek Polacek wrote:
> > > > r7-2111 introduced maybe_constant_value in cp_fully_fold.
> > > > maybe_constant_value uses cxx_eval_outermost_constant_expr, which
> > > > can clear TREE_CONSTANT:
> > > > 6510   else if (non_constant_p && TREE_CONSTANT (r))
> > > > [...]
> > > > 6529       TREE_CONSTANT (r) = false;
> > > > 
> > > > In this test the array size is '(long int) "h"'.  This used to be
> > > > TREE_CONSTANT but given the change above, the flag will be cleared
> > > > when we cp_fully_fold the array size in compute_array_index_type_loc.
> > > 
> > > I wonder about giving an error at that point; if size is TREE_CONSTANT and
> > > folded is not, we're in a strange situation already.
> > 
> > That works as well; how about the attached patch?
> 
> OK.

Thanks.

> > > > That means we don't emit an error in the
> > > > 10391   else if (TREE_CONSTANT (size)
> > > > block in the same function, and we go on.  Then we compute ITYPE
> > > > using cp_build_binary_op and use maybe_constant_value on it and
> > > > suddenly we have something that's TREE_CONSTANT again.
> > > 
> > > Why does maybe_constant_value consider (long)"h" - 1 to be a
> > > constant-expression?
> > 
> > That's because this check in cxx_eval_outermost_constant_expr:
> >    if (CONVERT_EXPR_CODE_P (TREE_CODE (r))
> >        && ARITHMETIC_TYPE_P (TREE_TYPE (r))
> >        && TREE_CODE (TREE_OPERAND (r, 0)) == ADDR_EXPR)
> >      {
> >        if (!allow_non_constant)
> >          error ("conversion from pointer type %qT "
> >                 "to arithmetic type %qT in a constant expression",
> >                 TREE_TYPE (TREE_OPERAND (r, 0)), TREE_TYPE (r));
> >        non_constant_p = true;
> >      }
> > doesn't work for all subexpressions, as the comment says.  As a consequence,
> > this test
> > 
> > constexpr long int
> > foo ()
> > {
> >    return (long int) "foo"
> > #ifdef FOO
> >      - 1
> > #endif
> >      ;
> > }
> > 
> > constexpr long int l = foo ();
> > 
> > is accepted with -DFOO but rejected otherwise.  Converting a pointer to an
> > integral type must be done via a reinterpret_cast and that can't be part of
> > a core constant expression.  Do you want a PR for this?
> 
> Please.

https://gcc.gnu.org/PR93955

--
Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA

Reply via email to