[C++ PATCH] Fix ICE with label difference as template non-type argument (PR c++/79650)

Jason Merrill jason@redhat.com
Wed Dec 13 22:28:00 GMT 2017


OK.

On Wed, Dec 13, 2017 at 5:21 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> reduced_constant_expression_p uses initializer_constant_valid_p
> to determine what is a valid constant expression.  That accepts several
> cases which aren't compile time INTEGER_CST, just something that the assembler
> can finalize into a constant, e.g. difference of labels, difference of
> STRING_CSTs, something plus ADDR_EXPR of a static var etc.
> But for template non-type arguments my understanding is we really need
> an INTEGER_CST, we cam hardly instantiate on something that only during
> assembly will become a constant.
>
> The following patch attempts to diagnose it.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> Or do you have better suggestions for the diagnostics wording?
>
> 2017-12-13  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/79650
>         * pt.c (convert_nontype_argument): Diagnose
>         reduced_constant_expression_p expressions that aren't INTEGER_CST.
>
>         * g++.dg/template/pr79650.C: New test.
>
> --- gcc/cp/pt.c.jj      2017-12-13 15:52:51.000000000 +0100
> +++ gcc/cp/pt.c 2017-12-13 19:21:35.861825357 +0100
> @@ -6577,7 +6577,19 @@ convert_nontype_argument (tree type, tre
>                 return NULL_TREE;
>               /* else cxx_constant_value complained but gave us
>                  a real constant, so go ahead.  */
> -             gcc_assert (TREE_CODE (expr) == INTEGER_CST);
> +             if (TREE_CODE (expr) != INTEGER_CST)
> +               {
> +                 /* Some assemble time constant expressions like
> +                    (intptr_t)&&lab1 - (intptr_t)&&lab2 or
> +                    4 + (intptr_t)&&var satisfy reduced_constant_expression_p
> +                    as we can emit them into .rodata initializers of
> +                    variables, yet they can't fold into an INTEGER_CST at
> +                    compile time.  Refuse them here.  */
> +                 gcc_checking_assert (reduced_constant_expression_p (expr));
> +                 error_at (loc, "template argument %qE for type %qT not "
> +                                "a constant integer", expr, type);
> +                 return NULL_TREE;
> +               }
>             }
>           else
>             return NULL_TREE;
> --- gcc/testsuite/g++.dg/template/pr79650.C.jj  2017-12-13 19:29:04.549196268 +0100
> +++ gcc/testsuite/g++.dg/template/pr79650.C     2017-12-13 19:34:15.202298913 +0100
> @@ -0,0 +1,20 @@
> +// PR c++/79650
> +// { dg-do compile { target c++11 } }
> +// { dg-options "" }
> +
> +typedef __INTPTR_TYPE__ intptr_t;
> +template<intptr_t> struct A {};
> +
> +void
> +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)&a> h;                                   // { dg-error "conversion from pointer type" }
> +}
>
>         Jakub



More information about the Gcc-patches mailing list