OK.
On Wed, Dec 13, 2017 at 5:21 PM, Jakub Jelinek <ja...@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 <ja...@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