This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch c++]: Fix PR/53904
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Kai Tietz <ktietz70 at googlemail dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 21 Nov 2014 12:38:15 +0100
- Subject: Re: [patch c++]: Fix PR/53904
- Authentication-results: sourceware.org; auth=none
- References: <CAEwic4bN8mKygQk_30k8w-n3A-Q2181tQEzUFm3Y5W48ZWVHMg at mail dot gmail dot com>
On Thu, Nov 20, 2014 at 8:48 PM, Kai Tietz <ktietz70@googlemail.com> wrote:
> Hello,
>
> this issue fixes a type-overflow issue caused by trying to cast a UHWI
> via tree_to_shwi.
> As soon as value gets larger then SHWI_MAX, we get an error for it.
> So we need to cast it
> via tree_to_uhwi, and then casting it to the signed variant.
I think it's better to handle the degenerate case (no element) explicitely.
And I would think that sth like "nelts" should have a positive result,
thus why is 'max' not unsigned? Also 'max' and using 'nelts' looks
like a mismatch? max == nelts - 1. Ah, because array_type_nelts
returns nelts - 1 ... how useful ;)
Still you want to special-case the array_type_nelts == -1 case.
Richard.
> ChangeLog
>
> 2014-11-20 Kai Tietz <ktietz@redhat.com>
>
> PR c++/63904
> * constexpr.c (cxx_eval_vec_init_1): Avoid
> type-overflow issue.
>
> 2014-11-20 Kai Tietz <ktietz@redhat.com>
>
> PR c++/63904
> * g++.dg/cpp0x/pr63904.C: New.
>
>
> Regression tested for x86_64-unknown-linux-gnu. Ok for apply?
>
> Regards,
> Kai
>
> Index: gcc/gcc/cp/constexpr.c
> ===================================================================
> --- gcc.orig/gcc/cp/constexpr.c
> +++ gcc/gcc/cp/constexpr.c
> @@ -2006,12 +2050,12 @@ cxx_eval_vec_init_1 (const constexpr_ctx
> bool *non_constant_p, bool *overflow_p)
> {
> tree elttype = TREE_TYPE (atype);
> - int max = tree_to_shwi (array_type_nelts (atype));
> + HOST_WIDE_INT max = (HOST_WIDE_INT) tree_to_uhwi (array_type_nelts (atype));
> verify_ctor_sanity (ctx, atype);
> vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
> vec_alloc (*p, max + 1);
> bool pre_init = false;
> - int i;
> + HOST_WIDE_INT i;
>
> /* For the default constructor, build up a call to the default
> constructor of the element type. We only need to handle class types
> Index: gcc/gcc/testsuite/g++.dg/cpp0x/pr63904.C
> ===================================================================
> --- /dev/null
> +++ gcc/gcc/testsuite/g++.dg/cpp0x/pr63904.C
> @@ -0,0 +1,13 @@
> +// { dg-do compile { target c++11 } }
> +
> +template<int N>
> +struct foo {
> + constexpr foo() : a() {}
> + int a[N];
> +};
> +
> +int main() {
> + foo< (foo<1>{}).a[0] > f;
> + return 0;
> +}
> +