[PATCH] c++: Reject some further reinterpret casts in constexpr [PR82304, PR95307]
Jason Merrill
jason@redhat.com
Fri May 29 17:26:32 GMT 2020
On 5/29/20 6:25 AM, Jakub Jelinek wrote:
> Hi!
>
> cxx_eval_outermost_constant_expr had a check for reinterpret_casts from
> pointers (well, it checked from ADDR_EXPRs) to integral type, but that
> only caught such cases at the toplevel of expressions.
> As the comment said, it should be done even inside of the expressions,
> but at the point of the writing e.g. pointer differences used to be a
> problem. We now have POINTER_DIFF_EXPR, so this is no longer an issue.
>
> Had to do it just for CONVERT_EXPR, because the FE emits NOP_EXPR casts
> from pointers to integrals in various spots, e.g. for the PMR & 1 tests,
> though on NOP_EXPR we have the REINTERPRET_CAST_P bit that we do check,
> while on CONVERT_EXPR we don't.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> PR92411 is not fixed by this change though.
>
> 2020-05-29 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/82304
> PR c++/95307
> * constexpr.c (cxx_eval_constant_expression): Diagnose CONVERT_EXPR
> conversions from pointer types to arithmetic types here...
> (cxx_eval_outermost_constant_expr): ... instead of here.
>
> * g++.dg/template/pr79650.C: Expect different diagnostics and expect
> it on all lines that do pointer to integer casts.
> * g++.dg/cpp1y/constexpr-shift1.C: Expect different diagnostics.
> * g++.dg/cpp1y/constexpr-82304.C: New test.
> * g++.dg/cpp0x/constexpr-95307.C: New test.
>
> --- gcc/cp/constexpr.c.jj 2020-05-28 23:12:19.715303826 +0200
> +++ gcc/cp/constexpr.c 2020-05-29 12:02:06.161656532 +0200
> @@ -6194,6 +6194,18 @@ cxx_eval_constant_expression (const cons
> if (VOID_TYPE_P (type))
> return void_node;
>
> + if (TREE_CODE (t) == CONVERT_EXPR
> + && ARITHMETIC_TYPE_P (type)
> + && INDIRECT_TYPE_P (TREE_TYPE (op)))
> + {
> + if (!ctx->quiet)
> + error ("conversion from pointer type %qT "
> + "to arithmetic type %qT in a constant expression",
> + TREE_TYPE (op), type);
> + *non_constant_p = true;
> + return t;
> + }
> +
> if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
> op = cplus_expand_constant (op);
>
> @@ -6795,19 +6807,6 @@ cxx_eval_outermost_constant_expr (tree t
> non_constant_p = true;
> }
>
> - /* Technically we should check this for all subexpressions, but that
> - runs into problems with our internal representation of pointer
> - subtraction and the 5.19 rules are still in flux. */
> - 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;
> - }
>
> if (!non_constant_p && overflow_p)
> non_constant_p = true;
> --- gcc/testsuite/g++.dg/template/pr79650.C.jj 2020-01-12 11:54:37.249400796 +0100
> +++ gcc/testsuite/g++.dg/template/pr79650.C 2020-05-29 12:02:06.180656252 +0200
> @@ -11,10 +11,10 @@ foo ()
> static int a, b;
> lab1:
> lab2:
> - A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab2> c; // { dg-error "not a constant integer" }
> - A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab1> d;
> - A<(intptr_t)&a - (intptr_t)&b> e; // { dg-error "is not a constant expression" }
> - A<(intptr_t)&a - (intptr_t)&a> f;
> - A<(intptr_t)sizeof(a) + (intptr_t)&a> g; // { dg-error "not a constant integer" }
> + A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab2> c; // { dg-error "conversion from pointer type" }
> + A<(intptr_t)&&lab1 - (__INTPTR_TYPE__)&&lab1> d; // { dg-error "conversion from pointer type" }
> + A<(intptr_t)&a - (intptr_t)&b> e; // { dg-error "conversion from pointer type" }
> + A<(intptr_t)&a - (intptr_t)&a> f; // { dg-error "conversion from pointer type" }
> + A<(intptr_t)sizeof(a) + (intptr_t)&a> g; // { dg-error "conversion from pointer type" }
> A<(intptr_t)&a> h; // { dg-error "conversion from pointer type" }
> }
> --- gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C.jj 2020-01-12 11:54:37.115402818 +0100
> +++ gcc/testsuite/g++.dg/cpp1y/constexpr-shift1.C 2020-05-29 12:02:06.180656252 +0200
> @@ -3,7 +3,8 @@
> constexpr int p = 1;
> constexpr __PTRDIFF_TYPE__ bar (int a)
> {
> - return ((__PTRDIFF_TYPE__) &p) << a; // { dg-error "is not a constant expression" }
> + return ((__PTRDIFF_TYPE__) &p) << a;
> }
> constexpr __PTRDIFF_TYPE__ r = bar (2); // { dg-message "in .constexpr. expansion of" }
> + // { dg-error "conversion from pointer" "" { target *-*-* } .-1 }
> constexpr __PTRDIFF_TYPE__ s = bar (0); // { dg-error "conversion from pointer" }
This is a diagnostic quality regression, moving the error message away
from the line where the actual problem is.
Maybe use error_at (loc, ...)?
Jason
More information about the Gcc-patches
mailing list