https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126088

--- Comment #3 from Max Orth <max.orth96 at gmail dot com> ---
(In reply to Jakub Jelinek from comment #2)
> #include <meta>
> 
> constexpr char a[] = "str1";
> constexpr char const *b = "str2";
> struct A { char const *c = "str3"; };
> [[=A { "str4" }]] int d = 1;
> [[=A { a }]] int e = 2;
> [[=A { }]] int f = 3;
> [[=A { b }]] int g = 4;
> 
> consteval std::meta::info
> foo (std::meta::info x)
> {
>   std::vector<std::meta::info> h = std::meta::annotations_of (x);
>   A i = std::meta::extract<A> (h[0]);
>   std::string_view j (i.c, __builtin_strlen (i.c));
>   return std::meta::reflect_constant_string (j);
> }
> 
> int
> main ()
> {
>   char const *k = [: foo (^^d) :];
>   char const *l = [: foo (^^e) :];
>   char const *m = [: foo (^^f) :];
>   char const *n = [: foo (^^g) :];
> }
> 
> Isn't this correct?
> This is
> #0  convert_reflect_constant_arg (type=<record_type 0x7fffe616bdc8 A>,
> expr=<constructor 0x7fffe61c67c8>) at ../../gcc/cp/pt.cc:34029
> #1  0x0000000000880983 in eval_reflect_constant (loc=4611686018427411086,
> ctx=0x7fffffff85c0, type=<record_type 0x7fffe616bdc8 A>, expr=<constructor
> 0x7fffe61c67c8>, 
>     non_constant_p=0x7fffffffaf5f, jump_target=0x7fffffffa6f0,
> fun=<function_decl 0x7fffe6172c00 extract>) at ../../gcc/cp/reflect.cc:4081
> #2  0x000000000087a4ce in eval_constant_of (loc=4611686018427411086,
> ctx=0x7fffffff85c0, r=<constructor 0x7fffe61c67c8>, kind=REFLECT_ANNOTATION,
> non_constant_p=0x7fffffffaf5f, 
>     overflow_p=0x7fffffffaf5e, jump_target=0x7fffffffa6f0,
> fun=<function_decl 0x7fffe6172c00 extract>) at ../../gcc/cp/reflect.cc:2874
> 
> Now, if I call
>   expr = convert_nontype_argument (type, expr, tf_warning_or_error);
> instead of
>   expr = convert_nontype_argument (type, expr, tf_none);
> then it explains the reason:
> pr126088.C: In function ‘consteval std::meta::info foo(std::meta::info)’:
> pr126088.C:23:26:   in ‘constexpr’ expansion of ‘foo(^^d)’
>    23 |   char const *k = [: foo (^^d) :];
>       |                      ~~~~^~~~~
> pr126088.C:6:8: error: ‘"str4"’ is not a valid template argument of type
> ‘const char*’ because ‘"str4"’ is not a variable or function
>     6 | [[=A { "str4" }]] int d = 1;
>       |        ^~~~~~
> This is similar to why
> template <const char *P>
> void foo () {}
> const char a[] = "str";
> void bar () { foo <a> (); foo <"str"> (); }
> rejects foo <"str"> but not foo <a>.

I'm satisfied, can close as not a bug.  It would be nice if the reflection
error had more detail about why it failed.  Indicating the end of the splice
operator, along with "reflect_constant failed" is not very helpful.

Reply via email to