On 2/11/26 10:50 AM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
This patch improves various reflection diagnostics as discussed in
<https://gcc.gnu.org/pipermail/gcc-patches/2025-December/704168.html>.

In particular:
- reword "not usable" diagnostics to say what kind of reflections we
   expected,
- use the new tree_category to better describe what kind of reflection
   we actually got,

Hmm, building an error message from strings like this is generally frowned on because it is difficult to translate. Maybe add a %R to cp_printer and a reflection_to_string function to print any kind of reflection?

- when we see a missing 'template' keyword, emit a -Wmissing-template-keyword
   warning instead of giving a hard error (this should only happen when the
   code would be valid with the 'template' added.

gcc/cp/ChangeLog:

        * cp-tree.h (tree_category): Declare.
        * error.cc (tree_category): New.
        * parser.cc (cp_parser_splice_specifier): Use OVL_FIRST when checking
        for TEMPLATE_DECL.
        (cp_parser_splice_type_specifier): Reword an error message.
        (cp_parser_splice_expression): Check check_splice_expr earlier.  Reword
        error messages.  Turn an error into an assert.  Use
        missing_template_diag instead of giving an error about missing template.
        (cp_parser_splice_scope_specifier): Reword an error message.
        (missing_template_diag): Forward declare.  Drop "enum" in a parameter.
        * reflect.cc (check_splice_expr): Print tree_category.

gcc/testsuite/ChangeLog:

        * g++.dg/reflect/crash9.C: Adjust dg-error.
        * g++.dg/reflect/diag1.C: Likewise.
        * g++.dg/reflect/error10.C: Likewise.
        * g++.dg/reflect/error12.C: Likewise.
        * g++.dg/reflect/error5.C: Likewise.
        * g++.dg/reflect/expr3.C: Likewise.
        * g++.dg/reflect/member1.C: Likewise.
        * g++.dg/reflect/ns2.C: Likewise.  Test more cases.
        * g++.dg/reflect/p2996-12.C: Adjust dg-error.
        * g++.dg/reflect/splice5.C: Likewise.
        * g++.dg/reflect/diag1a.C: New test.
        * g++.dg/reflect/diag1b.C: New test.
---
  gcc/cp/cp-tree.h                        |  1 +
  gcc/cp/error.cc                         | 31 +++++++++
  gcc/cp/parser.cc                        | 92 ++++++++++---------------
  gcc/cp/reflect.cc                       |  2 +-
  gcc/testsuite/g++.dg/reflect/crash9.C   |  4 +-
  gcc/testsuite/g++.dg/reflect/diag1.C    |  6 +-
  gcc/testsuite/g++.dg/reflect/diag1a.C   | 24 +++++++
  gcc/testsuite/g++.dg/reflect/diag1b.C   | 23 +++++++
  gcc/testsuite/g++.dg/reflect/error10.C  | 12 ++--
  gcc/testsuite/g++.dg/reflect/error12.C  | 20 +++---
  gcc/testsuite/g++.dg/reflect/error5.C   |  2 +-
  gcc/testsuite/g++.dg/reflect/expr3.C    | 18 ++---
  gcc/testsuite/g++.dg/reflect/member1.C  | 12 ++--
  gcc/testsuite/g++.dg/reflect/ns2.C      | 18 ++++-
  gcc/testsuite/g++.dg/reflect/p2996-12.C |  2 +-
  gcc/testsuite/g++.dg/reflect/splice5.C  |  8 +--
  16 files changed, 171 insertions(+), 104 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/reflect/diag1a.C
  create mode 100644 gcc/testsuite/g++.dg/reflect/diag1b.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fcad67a662c..b1ac66cb4e9 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7688,6 +7688,7 @@ extern bool pedwarn_cxx98                       
(location_t,
  extern location_t location_of                   (tree);
  extern void qualified_name_lookup_error               (tree, tree, tree,
                                                 location_t);
+extern const char *tree_category               (tree) ATTRIBUTE_PURE;
struct decl_location_traits
    : simple_cache_map_traits<tree_decl_hash, location_t> { };
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index c184846066e..b9ae87faed4 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -3976,6 +3976,37 @@ function_category (tree fn)
      return G_("In function %qD");
  }
+/* Return the category for T (type, expression, ...). */
+
+const char *
+tree_category (tree t)
+{
+  t = maybe_get_first_fn (t);
+  if (TREE_CODE (t) == TYPE_DECL)
+    t = TREE_TYPE (t);
+
+  if (TYPE_P (t))
+    return G_("type ");
+  else if (EXPR_P (t))
+    return G_("expression ");
+  else if (VAR_P (t))
+    return G_("variable ");
+  else if (TREE_CODE (t) == PARM_DECL)
+    return G_("parameter ");
+  else if (TREE_CODE (t) == FUNCTION_DECL)
+    return G_("function ");
+  else if (DECL_FUNCTION_TEMPLATE_P (t))
+    return G_("function template ");
+  else if (DECL_CLASS_TEMPLATE_P (t))
+    return G_("class template ");
+  else if (TREE_CODE (t) == NAMESPACE_DECL)
+    return G_("namespace ");
+  else if (TREE_CODE (t) == CONST_DECL && !DECL_TEMPLATE_PARM_P (t))
+    return G_("enumerator ");
+  else
+    return "";
+}
+
  /* Disable warnings about missing quoting in GCC diagnostics for
     the pp_verbatim calls.  Their format strings deliberately don't
     follow GCC diagnostic conventions.  */
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 8c46b260fff..0dc1d361474 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -279,6 +279,8 @@ static tree omp_start_variant_function
  static int omp_finish_variant_function
    (cp_parser *, tree, tree, tree, bool, bool);
  static void maybe_start_implicit_template (cp_parser *parser);
+static void missing_template_diag
+  (location_t, diagnostics::kind = diagnostics::kind::warning);
/* Manifest constants. */
  #define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
@@ -6182,7 +6184,9 @@ cp_parser_splice_specifier (cp_parser *parser, bool 
template_p = false,
        /* As a courtesy to the user, if there is a < after a template
         name, parse the construct as an s-s-s and warn about the missing
         'template'; it can't be anything else.  */
-      && (template_p || typename_p || TREE_CODE (expr) == TEMPLATE_DECL))
+      && (template_p
+         || typename_p
+         || TREE_CODE (OVL_FIRST (expr)) == TEMPLATE_DECL))
      {
        /* For member access splice-specialization-specifier, try to wrap
         non-dependent splice for function template into a BASELINK so
@@ -6251,7 +6255,8 @@ cp_parser_splice_type_specifier (cp_parser *parser)
    if (!valid_splice_type_p (type))
      {
        if (!cp_parser_simulate_error (parser))
-       error_at (loc, "reflection %qE not usable in a splice type", type);
+       error_at (loc, "expected a reflection of a type instead of %s%qE",
+                 tree_category (type), type);
        type = NULL_TREE;
      }
@@ -6312,63 +6317,41 @@ cp_parser_splice_expression (cp_parser *parser, bool template_p,
        return error_mark_node;
      }
+ /* Make sure this splice-expression produces an expression. */
+  if (!check_splice_expr (loc, expr.get_start (), t, address_p,
+                         member_access_p, /*complain=*/true))
+    return error_mark_node;
+
    if (template_p)
      {
        /* [expr.prim.splice] For a splice-expression of the form template
         splice-specifier, the splice-specifier shall designate a function
         template.  */
-      if (!targs_p)
+      if (!targs_p
+         && !really_overloaded_fn (t)
+         && !dependent_splice_p (t))
        {
-         if (!really_overloaded_fn (t) && !dependent_splice_p (t))
-           {
-             auto_diagnostic_group d;
-             error_at (loc, "reflection %qE not usable in a template splice",
-                       t);
-             inform (loc, "only function templates are allowed here");
-             return error_mark_node;
-           }
+         error_at (loc, "expected a reflection of a function template "
+                   "instead of %s%qE", tree_category (t), t);
+         return error_mark_node;
        }
        /* [expr.prim.splice] For a splice-expression of the form
         template splice-specialization-specifier, the splice-specifier of the
-        splice-specialization-specifier shall designate a template.  */
-      else
-       {
-         if (really_overloaded_fn (t)
-             || get_template_info (t)
-             || TREE_CODE (t) == TEMPLATE_ID_EXPR)
-           /* OK */;
-         else
-           {
-             auto_diagnostic_group d;
-             error_at (loc, "reflection %qE not usable in a template splice",
-                       t);
-             inform (loc, "only templates are allowed here");
-             return error_mark_node;
-           }
-       }
+        splice-specialization-specifier shall designate a template.  Since
+        we would have already complained, just check that we have a template.  
*/
+      gcc_checking_assert (really_overloaded_fn (t)
+                          || get_template_info (t)
+                          || TREE_CODE (t) == TEMPLATE_ID_EXPR
+                          || dependent_splice_p (t));
      }
    else if (/* No 'template' but there were template arguments?  */
-          targs_p
-          /* No 'template' but the splice-specifier designates a template?  */
-          || really_overloaded_fn (t))
-    {
-      auto_diagnostic_group d;
-      if (targs_p)
-       error_at (loc, "reflection %qE not usable in a splice expression with "
-                 "template arguments", t);
-      else
-       error_at (loc, "reflection %qE not usable in a splice expression", t);
-      location_t sloc = expr.get_start ();
-      rich_location richloc (line_table, sloc);
-      richloc.add_fixit_insert_before (sloc, "template ");
-      inform (&richloc, "add %<template%> to denote a template");
-      return error_mark_node;
-    }
-
-  /* Make sure this splice-expression produces an expression.  */
-  if (!check_splice_expr (loc, expr.get_start (), t, address_p,
-                         member_access_p, /*complain=*/true))
-    return error_mark_node;
+          (targs_p
+           /* No 'template' but the splice-specifier designates a function
+              template?  */
+           || really_overloaded_fn (t))
+          && warning_enabled_at (loc, OPT_Wmissing_template_keyword))
+    /* Were 'template' present, this would be valid code, so keep going.  */
+    missing_template_diag (loc, diagnostics::kind::pedwarn);



/* When doing foo.[: bar :], cp_parser_postfix_dot_deref_expression wants
       to see an identifier or a TEMPLATE_ID_EXPR, if we have something like
@@ -6469,14 +6452,9 @@ cp_parser_splice_scope_specifier (cp_parser *parser, 
bool typename_p,
if (!valid_splice_scope_p (scope))
      {
-      auto_diagnostic_group d;
-      error_at (loc, "reflection not usable in a splice scope");
-      if (TYPE_P (scope))
-       inform (loc, "%qT is not a class, namespace, or enumeration",
-               tree (scope));
-      else
-       inform (loc, "%qE is not a class, namespace, or enumeration",
-               tree (scope));
+      error_at (loc, "expected a reflection of a class, namespace, or "
+               "enumeration instead of %s%qE",
+               tree_category (tree (scope)), tree (scope));
        scope = error_mark_node;
      }
@@ -7234,7 +7212,7 @@ cp_parser_primary_expression (cp_parser *parser, static void
  missing_template_diag (location_t loc,
-                      enum diagnostics::kind diag_kind = 
diagnostics::kind::warning)
+                      diagnostics::kind diag_kind/*=kind::warning*/)
  {
    if (warning_suppressed_at (loc, OPT_Wmissing_template_keyword))
      return;
diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index d04930d732c..507174c9b22 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -8346,7 +8346,7 @@ check_splice_expr (location_t loc, location_t start_loc, 
tree t,
            }
          else
            error_at (loc, "expected a reflection of an expression instead "
-                     "of %qD", t);
+                     "of %s%qD", tree_category (t), t);
        }
        return false;
      }
diff --git a/gcc/testsuite/g++.dg/reflect/crash9.C 
b/gcc/testsuite/g++.dg/reflect/crash9.C
index 1f8aff6a715..043f4175c4a 100644
--- a/gcc/testsuite/g++.dg/reflect/crash9.C
+++ b/gcc/testsuite/g++.dg/reflect/crash9.C
@@ -3,8 +3,8 @@
namespace N { } -template <auto V> constexpr int e = [:V:]; // { dg-error "expected a reflection of an expression instead of .N." }
-template <auto V> constexpr int e2 = [:V:]; // { dg-error "expected a reflection of 
an expression instead of .N." }
+template <auto V> constexpr int e = [:V:];  // { dg-error "expected a reflection of 
an expression instead of namespace .N." }
+template <auto V> constexpr int e2 = [:V:]; // { dg-error "expected a reflection of 
an expression instead of namespace .N." }
  constexpr auto h = ^^N;
  constexpr auto i = e<([:^^h:])>;
  constexpr auto j = e2<^^N>;
diff --git a/gcc/testsuite/g++.dg/reflect/diag1.C 
b/gcc/testsuite/g++.dg/reflect/diag1.C
index 2d34623a8ac..537929decb7 100644
--- a/gcc/testsuite/g++.dg/reflect/diag1.C
+++ b/gcc/testsuite/g++.dg/reflect/diag1.C
@@ -14,12 +14,10 @@ void
  f ()
  {
    S s;
-  s.[: ^^S::tfn :](42); // { dg-error "reflection .S::tfn. not usable in a splice 
expression" }
-// { dg-message "add .template. to denote a template" "" { target *-*-* } .-1 }
+  s.[: ^^S::tfn :](42); // { dg-error "expected 'template' keyword before dependent 
template name" }
    s.template [: ^^S::tfn :](42);
constexpr auto r = ^^fortytwo;
-  constexpr int i1 = [:r:]<int>; // { dg-error "reflection .fortytwo<int>. not 
usable in a splice expression with template arguments" }
-// { dg-message "add .template. to denote a template" "" { target *-*-* } .-1 }
+  constexpr int i1 = [:r:]<int>; // { dg-error "expected 'template' keyword before 
dependent template name" }
    constexpr int i2 = template [:r:]<int>;
  }
diff --git a/gcc/testsuite/g++.dg/reflect/diag1a.C 
b/gcc/testsuite/g++.dg/reflect/diag1a.C
new file mode 100644
index 00000000000..d276a7d22f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/diag1a.C
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++26 } }
+// { dg-options "" }
+// { dg-additional-options "-freflection" }
+// Test that we offer some helpful diagnostic.
+
+struct S {
+  template<typename T>
+  void tfn (T) { }
+};
+
+template<typename T>
+constexpr T fortytwo = 42;
+
+void
+f ()
+{
+  S s;
+  s.[: ^^S::tfn :](42); // { dg-warning "expected 'template' keyword before 
dependent template name" }
+  s.template [: ^^S::tfn :](42);
+
+  constexpr auto r = ^^fortytwo;
+  constexpr int i1 = [:r:]<int>; // { dg-warning "expected 'template' keyword 
before dependent template name" }
+  constexpr int i2 = template [:r:]<int>;
+}
diff --git a/gcc/testsuite/g++.dg/reflect/diag1b.C 
b/gcc/testsuite/g++.dg/reflect/diag1b.C
new file mode 100644
index 00000000000..b2c9bade331
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/diag1b.C
@@ -0,0 +1,23 @@
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection -Wno-missing-template-keyword" }
+// Test that we offer some helpful diagnostic.
+
+struct S {
+  template<typename T>
+  void tfn (T) { }
+};
+
+template<typename T>
+constexpr T fortytwo = 42;
+
+void
+f ()
+{
+  S s;
+  s.[: ^^S::tfn :](42); // { dg-bogus "expected 'template' keyword before dependent 
template name" }
+  s.template [: ^^S::tfn :](42);
+
+  constexpr auto r = ^^fortytwo;
+  constexpr int i1 = [:r:]<int>; // { dg-bogus "expected 'template' keyword before 
dependent template name" }
+  constexpr int i2 = template [:r:]<int>;
+}
diff --git a/gcc/testsuite/g++.dg/reflect/error10.C 
b/gcc/testsuite/g++.dg/reflect/error10.C
index 2ca2b18a1fa..fda6a66cb42 100644
--- a/gcc/testsuite/g++.dg/reflect/error10.C
+++ b/gcc/testsuite/g++.dg/reflect/error10.C
@@ -4,29 +4,29 @@
  int g;
void
-fn0 (int, typename [: ^^:: :] i) // { dg-error "reflection .::. not usable in a 
splice type|declared" }
+fn0 (int, typename [: ^^:: :] i) // { dg-error "expected a reflection of a type 
instead of namespace .::.|declared" }
  {
  }
void
-fn1 (int, typename [: ^^g :] i) // { dg-error "reflection .g. not usable in a 
splice type|declared" }
+fn1 (int, typename [: ^^g :] i) // { dg-error "expected a reflection of a type 
instead of variable .g.|declared" }
  {
  }
void
-fn2 (int, typename [: ^^fn1 :] i) // { dg-error "reflection .fn1. not usable in a 
splice type|declared" }
+fn2 (int, typename [: ^^fn1 :] i) // { dg-error "expected a reflection of a type 
instead of function .fn1.|declared" }
  {
  }
void
-fn3 (int p, typename [: ^^p :] i) // { dg-error "reflection .p. not usable in a 
splice type|declared" }
+fn3 (int p, typename [: ^^p :] i) // { dg-error "expected a reflection of a type 
instead of parameter .p.|declared" }
  {
  }
enum Harold { Budd }; void
-fn4 (int, typename [: ^^Budd :] i) // { dg-error "reflection .Budd. not usable in a 
splice type|declared" }
+fn4 (int, typename [: ^^Budd :] i) // { dg-error "expected a reflection of a type 
instead of enumerator .Budd.|declared" }
  {
  }
@@ -34,6 +34,6 @@ template<int>
  struct S {};
void
-fn5 (int, typename [: ^^S :] i) // { dg-error "reflection .S. not usable in a 
splice type|declared" }
+fn5 (int, typename [: ^^S :] i) // { dg-error "expected a reflection of a type 
instead of class template .S.|declared" }
  {
  }
diff --git a/gcc/testsuite/g++.dg/reflect/error12.C 
b/gcc/testsuite/g++.dg/reflect/error12.C
index 7eb787f010d..d8073b20cc4 100644
--- a/gcc/testsuite/g++.dg/reflect/error12.C
+++ b/gcc/testsuite/g++.dg/reflect/error12.C
@@ -7,16 +7,16 @@ constexpr auto r = ^^i;
  constexpr bool b0 = template [:r:] < 0 > 0;  // { dg-error "not a template" }
  constexpr bool b1 = template [:r:] < 0 < 0;  // { dg-error "not a 
template|expected" }
  constexpr bool b2 = template [:r:] < 43;     // { dg-error "not a 
template|expected" }
-constexpr bool b3 = template [:r:] <= 43;    // { dg-error "template splice" }
-constexpr bool b4 = template [:r:] > 41;     // { dg-error "template splice" }
-constexpr bool b5 = template [:r:] >= 41;    // { dg-error "template splice" }
-constexpr bool b6 = template [:r:] == 42;    // { dg-error "template splice" }
-constexpr bool b7 = template [:r:] != 41;    // { dg-error "template splice" }
+constexpr bool b3 = template [:r:] <= 43;    // { dg-error "expected a reflection 
of a function template instead of variable .i." }
+constexpr bool b4 = template [:r:] > 41;     // { dg-error "expected a reflection 
of a function template instead of variable .i." }
+constexpr bool b5 = template [:r:] >= 41;    // { dg-error "expected a reflection 
of a function template instead of variable .i." }
+constexpr bool b6 = template [:r:] == 42;    // { dg-error "expected a reflection 
of a function template instead of variable .i." }
+constexpr bool b7 = template [:r:] != 41;    // { dg-error "expected a reflection 
of a function template instead of variable .i." }
template<bool> struct S { };
  S<template [:r:] < 43> s1;    // { dg-error "not a template|invalid" }
-S<template [:r:] <= 43> s2;   // { dg-error "template splice|invalid" }
-S<(template [:r:] > 41)> s3;  // { dg-error "template splice|invalid" }
-S<template [:r:] >= 41> s4;   // { dg-error "template splice|invalid" }
-S<template [:r:] == 42> s5;   // { dg-error "template splice|invalid" }
-S<template[:r:] != 41> s6;    // { dg-error "template splice|invalid" }
+S<template [:r:] <= 43> s2;   // { dg-error "expected a reflection|invalid" }
+S<(template [:r:] > 41)> s3;  // { dg-error "expected a reflection|invalid" }
+S<template [:r:] >= 41> s4;   // { dg-error "expected a reflection|invalid" }
+S<template [:r:] == 42> s5;   // { dg-error "expected a reflection|invalid" }
+S<template[:r:] != 41> s6;    // { dg-error "expected a reflection|invalid" }
diff --git a/gcc/testsuite/g++.dg/reflect/error5.C 
b/gcc/testsuite/g++.dg/reflect/error5.C
index 2b125fffc1a..a906684487a 100644
--- a/gcc/testsuite/g++.dg/reflect/error5.C
+++ b/gcc/testsuite/g++.dg/reflect/error5.C
@@ -9,7 +9,7 @@ template<info R>
  void
  f ()
  {
-  int i = [:R:]; // { dg-error "expected a reflection of an expression instead of 
.N." }
+  int i = [:R:]; // { dg-error "expected a reflection of an expression instead of 
namespace .N." }
  }
void
diff --git a/gcc/testsuite/g++.dg/reflect/expr3.C 
b/gcc/testsuite/g++.dg/reflect/expr3.C
index de7cffe1a56..0a5475b9c98 100644
--- a/gcc/testsuite/g++.dg/reflect/expr3.C
+++ b/gcc/testsuite/g++.dg/reflect/expr3.C
@@ -24,28 +24,28 @@ void
  g ()
  {
    int i1 = [: ^^x :];
-  int i2 = template [: ^^x :];    // { dg-error "reflection .x. not usable in a 
template splice" }
+  int i2 = template [: ^^x :];    // { dg-error "expected a reflection of a 
function template instead of variable .x." }
    int i3 = [: ^^two<int> :];
-  int i4 = template [: ^^two<int> :]; // { dg-error "reflection .two<int>. not 
usable in a template splice" }
-  int i5 = [: ^^foo :](42);          // { dg-error "reflection .foo. not usable in 
a splice expression" }
+  int i4 = template [: ^^two<int> :]; // { dg-error "expected a reflection of a function 
template instead of variable .two<int>." }
+  int i5 = [: ^^foo :](42);          // { dg-error "expected 'template' keyword 
before dependent template name" }
    int i6 = template [: ^^foo :](42);
    int i7 = [: ^^foo<int> :](42);
-  int i8 = template [: ^^foo<int> :](42);   // { dg-error "reflection .foo<int>. 
not usable in a template splice" }
+  int i8 = template [: ^^foo<int> :](42);   // { dg-error "expected a reflection of a 
function template instead of function .foo<int>." }
    int i9 = [: ^^foo :]<int>(42);            // { dg-error "reflection .foo. not 
usable in a splice expression|expected" }
    int i10 = template [: ^^foo :]<int>(42);
    int i11 = template [: ^^bar :]<int>(42);  // { dg-error "no matching function 
for call" }
-  int i12 = [: ^^two :]<int>;                // { dg-error "reflection .two<int>. 
not usable in a splice expression with template arguments" }
+  int i12 = [: ^^two :]<int>;                // { dg-error "expected 'template' 
keyword before dependent template name" }
    int i13 = template [: ^^two :]<int>;
- [: ^^ST :]<int> c1; // { dg-error "reflection .ST<int>. not usable in a splice expression with template arguments" }
+  [: ^^ST :]<int> c1;  // { dg-error "expected a reflection of an expression instead of 
type .struct ST<int>." }
    typename [: ^^ST :]<int> c2;
-  template [: ^^ST :]<int> c3;  // { dg-error "expected a reflection of an 
expression" }
+  template [: ^^ST :]<int> c3;  // { dg-error "expected a reflection of an 
expression instead of type" }
    [: ^^S :]<int> c4;   // { dg-error "expected a reflection of an 
expression|expected primary-expression" }
    template [: ^^S :]<int> c5;   // { dg-error ".S. is not a template" }
    typename [: ^^S :]<int> c6;   // { dg-error ".S. is not a 
template|expected" }
    [: ^^bar :]<int>();   // { dg-error "expected" }
- auto x1 = [: ^^ST :]<int>{}; // { dg-error "reflection .ST<int>. not usable in a splice expression with template arguments" }
-  auto x2 = template [: ^^ST :]<int>{};  // { dg-error "expected a reflection of an 
expression" }
+  auto x1 = [: ^^ST :]<int>{};     // { dg-error "expected a reflection of an expression 
instead of type .struct ST<int>." }
+  auto x2 = template [: ^^ST :]<int>{};  // { dg-error "expected a reflection of an 
expression instead of type" }
    auto x3 = typename [: ^^ST :]<int>{};
  }
diff --git a/gcc/testsuite/g++.dg/reflect/member1.C 
b/gcc/testsuite/g++.dg/reflect/member1.C
index e9d9a64d0eb..6ea7bac289c 100644
--- a/gcc/testsuite/g++.dg/reflect/member1.C
+++ b/gcc/testsuite/g++.dg/reflect/member1.C
@@ -55,9 +55,9 @@ f ()
    sp->template [: ^^S::tfn :](42);
    s.template [: ^^S::tfn :]<int>(42);
    sp->template [: ^^S::tfn :]<int>(42);
-  s.[: ^^S::var :]<int> = 1; // { dg-error "reflection .var<int>. not usable in a 
splice expression with template arguments" }
+  s.[: ^^S::var :]<int> = 1; // { dg-error "expected 'template' keyword before 
dependent template name" }
    s.template [: ^^S::var :]<int> = 1;
-  sp->[: ^^S::var :]<int> = 1; // { dg-error "reflection .var<int>. not usable in a 
splice expression with template arguments" }
+  sp->[: ^^S::var :]<int> = 1; // { dg-error "expected 'template' keyword before 
dependent template name" }
    sp->template [: ^^S::var :]<int> = 1;
    s.[: ^^S::b :].[: ^^B::a :].val;
    sp->[: ^^S::b :].[: ^^B::a :].val;
@@ -74,9 +74,9 @@ f ()
    cp->template [: ^^C<int>::tfn :](42);
    c.template [: ^^C<int>::tfn :]<int>(42);
    cp->template [: ^^C<int>::tfn :]<int>(42);
-  c.[: ^^C<int>::var :]<int> = 1; // { dg-error "reflection .var<int>. not usable 
in a splice expression with template arguments" }
+  c.[: ^^C<int>::var :]<int> = 1; // { dg-error "expected 'template' keyword before 
dependent template name" }
    c.template [: ^^C<int>::var :]<int> = 1;
-  cp->[: ^^C<int>::var :]<int> = 1; // { dg-error "reflection .var<int>. not usable 
in a splice expression with template arguments" }
+  cp->[: ^^C<int>::var :]<int> = 1; // { dg-error "expected 'template' keyword 
before dependent template name" }
    cp->template [: ^^C<int>::var :]<int> = 1;
    c.[: ^^C<int>::b :].[: ^^B::a :].val;
    cp->[: ^^C<int>::b :].[: ^^B::a :].val;
@@ -92,8 +92,8 @@ f ()
    sp.[: ^^S::x :] = 2; // { dg-error "which is of pointer type" }
    c.[: ^^C<char>::x :] = 1; // { dg-error "is not a base of" }
    cp->[: ^^C<char>::x :] = 1; // { dg-error "is not a base of" }
-  s.template [: ^^S::N :].t;  // { dg-error "reflection .S::N. not usable in a 
template splice" }
+  s.template [: ^^S::N :].t;  // { dg-error "expected a reflection of a function 
template instead of class template .S::N." }
    S::template [: ^^S::N<int> :] e1;  // { dg-error "expected unqualified-id" }
    C<int>::template [: ^^S::N<int> :] e2;  // { dg-error "expected 
unqualified-id" }
-  s.template [: ^^S::var<int> :] = 1;  // { dg-error "reflection .S::var<int>. not 
usable in a template splice" }
+  s.template [: ^^S::var<int> :] = 1;  // { dg-error "expected a reflection of a function 
template instead of variable .S::var<int>." }
  }
diff --git a/gcc/testsuite/g++.dg/reflect/ns2.C 
b/gcc/testsuite/g++.dg/reflect/ns2.C
index 482b8754713..a0156d1d080 100644
--- a/gcc/testsuite/g++.dg/reflect/ns2.C
+++ b/gcc/testsuite/g++.dg/reflect/ns2.C
@@ -3,19 +3,31 @@
  // Test reflections on namespaces.  Invalid stuff.
void foo (int);
+int i;
+enum E { EE };
+template<typename>
+struct S { };
+template<typename>
+void bar ();
namespace N {
  }
void
-f1 ()
+f1 (int p)
  {
    constexpr auto r = ^^::;
    [: r :] foo (0); // { dg-error "expected" }
constexpr auto q = ^^int;
-  [: q :]::T x; // { dg-error "reflection not usable in a splice 
scope|expected" }
-  // { dg-message ".int. is not a class, namespace, or enumeration" "" { 
target *-*-* } .-1 }
+  [: q :]::T x; // { dg-error "expected a reflection of a class, namespace, or 
enumeration instead of type .int.|expected" }
+
+  [: ^^foo :]::X; // { dg-error "expected a reflection of a class, namespace, or 
enumeration instead of function .foo." }
+  [: ^^EE :]::Y;  // { dg-error "expected a reflection of a class, namespace, or 
enumeration instead of enumerator .EE." }
+  [: ^^S :]::Z;          // { dg-error "expected a reflection of a class, 
namespace, or enumeration instead of class template .S." }
+  [: ^^bar :]::W; // { dg-error "expected a reflection of a class, namespace, or 
enumeration instead of function template .bar." }
+  [: ^^i :]::U;          // { dg-error "expected a reflection of a class, 
namespace, or enumeration instead of variable .i." }
+  [: ^^p :]::V;          // { dg-error "expected a reflection of a class, 
namespace, or enumeration instead of parameter .p." }
constexpr auto x = ^^N::X; // { dg-error ".N::X. has not been declared" }
  }
diff --git a/gcc/testsuite/g++.dg/reflect/p2996-12.C 
b/gcc/testsuite/g++.dg/reflect/p2996-12.C
index 58a145693f4..33fc9f5c2c3 100644
--- a/gcc/testsuite/g++.dg/reflect/p2996-12.C
+++ b/gcc/testsuite/g++.dg/reflect/p2996-12.C
@@ -15,7 +15,7 @@ using alias = [:^^TCls:]<([:^^v:])>;
  static_assert(alias::s == 2);
// error: < means less than
-auto o1 = [:^^TCls:]<([:^^v:])>();  // { dg-error "reflection .TCls<1>. not 
usable" }
+auto o1 = [:^^TCls:]<([:^^v:])>();  // { dg-error "expected a reflection of an expression 
instead of type .struct TCls<1>." }
  // OK, o2 is an object of type TCls<1>
  auto o2 = typename [:^^TCls:]<([:^^v:])>();
diff --git a/gcc/testsuite/g++.dg/reflect/splice5.C b/gcc/testsuite/g++.dg/reflect/splice5.C
index 78144863337..c4d150a2801 100644
--- a/gcc/testsuite/g++.dg/reflect/splice5.C
+++ b/gcc/testsuite/g++.dg/reflect/splice5.C
@@ -13,10 +13,10 @@ struct S {
  void
  baz (S &s)
  {
-  template [: ^^foo :] (0);                    // { dg-error "reflection 'foo' not 
usable in a template splice" }
-  template [: ^^bar :] (0);                    // { dg-message "only function templates are 
allowed here" "" { target *-*-* } .-1 }
-  s.template [: ^^S::foo :] (0);               // { dg-error "reflection 'S::foo' 
not usable in a template splice" }
-  s.template [: ^^S::bar :] (0);               // { dg-message "only function templates are 
allowed here" "" { target *-*-* } .-1 }
+  template [: ^^foo :] (0);                    // { dg-error "expected a reflection 
of a function template instead of function .foo." }
+  template [: ^^bar :] (0);
+  s.template [: ^^S::foo :] (0);               // { dg-error "expected a reflection 
of a function template instead of function .S::foo." }
+  s.template [: ^^S::bar :] (0);
  }
template <int N>

base-commit: 1cd5aaf462ed6096363a45c608115d02a921aafd

Reply via email to