[gcc r17-164] c++/reflection: disallow reflecting block-scope externs (CWG 3065) [PR124756]
Marek Polacek
mpolacek@gcc.gnu.org
Tue Apr 28 20:54:43 GMT 2026
https://gcc.gnu.org/g:c1977d101524d87642790422134fe170ce00b545
commit r17-164-gc1977d101524d87642790422134fe170ce00b545
Author: Marek Polacek <polacek@redhat.com>
Date: Fri Apr 24 17:30:43 2026 -0400
c++/reflection: disallow reflecting block-scope externs (CWG 3065) [PR124756]
The proposed resolution of CWG 3065 suggests that reflection on a block-scope
extern declaration be ill-formed. This patch makes it so, and it also
happens to fix a crash.
PR c++/124756
gcc/cp/ChangeLog:
* reflect.cc (get_reflection): Give an error when taking the
reflection of a block-scope extern.
gcc/testsuite/ChangeLog:
* g++.dg/reflect/identifier_of3.C: Add dg-error.
* g++.dg/reflect/pr123612.C: Likewise.
* g++.dg/reflect/error13.C: New test.
Reviewed-by: Jason Merrill <jason@redhat.com>
Diff:
---
gcc/cp/reflect.cc | 9 ++++++--
gcc/testsuite/g++.dg/reflect/error13.C | 30 +++++++++++++++++++++++++++
gcc/testsuite/g++.dg/reflect/identifier_of3.C | 17 ++++++++-------
gcc/testsuite/g++.dg/reflect/pr123612.C | 13 ++++++------
4 files changed, 53 insertions(+), 16 deletions(-)
diff --git a/gcc/cp/reflect.cc b/gcc/cp/reflect.cc
index 27e1efee106b..6ef718e560fc 100644
--- a/gcc/cp/reflect.cc
+++ b/gcc/cp/reflect.cc
@@ -238,9 +238,14 @@ get_reflection (location_t loc, tree t, reflect_kind kind/*=REFLECT_UNDEF*/)
t = dtor;
}
- /* Look through block scope externs. */
+ /* Block-scope externs are invalid here as per the proposed resolution
+ of CWG 3065. */
if (VAR_OR_FUNCTION_DECL_P (t) && DECL_LOCAL_DECL_P (t))
- t = DECL_LOCAL_DECL_ALIAS (t);
+ {
+ error_at (loc, "cannot take the reflection of a block-scope extern %qE",
+ t);
+ return error_mark_node;
+ }
if (t == error_mark_node)
return error_mark_node;
diff --git a/gcc/testsuite/g++.dg/reflect/error13.C b/gcc/testsuite/g++.dg/reflect/error13.C
new file mode 100644
index 000000000000..8d61b7f192ce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/error13.C
@@ -0,0 +1,30 @@
+// PR c++/124756
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-freflection" }
+
+template<typename T>
+consteval void
+f0 ()
+{
+ void fun(T);
+ auto _ = ^^fun; // { dg-error "cannot take the reflection of a block-scope extern .fun." }
+ extern int arr[3];
+ auto _ = ^^arr; // { dg-error "cannot take the reflection of a block-scope extern .arr." }
+ extern int e;
+ auto _ = ^^e; // { dg-error "cannot take the reflection of a block-scope extern .e." }
+}
+
+consteval {
+ f0<int>();
+}
+
+consteval void
+f1 ()
+{
+ void fun(int);
+ auto _ = ^^fun; // { dg-error "cannot take the reflection of a block-scope extern .fun." }
+ extern int arr[3];
+ auto _ = ^^arr; // { dg-error "cannot take the reflection of a block-scope extern .arr." }
+ extern int e;
+ auto _ = ^^e; // { dg-error "cannot take the reflection of a block-scope extern .e." }
+}
diff --git a/gcc/testsuite/g++.dg/reflect/identifier_of3.C b/gcc/testsuite/g++.dg/reflect/identifier_of3.C
index 5383de07dd24..266b43471ae2 100644
--- a/gcc/testsuite/g++.dg/reflect/identifier_of3.C
+++ b/gcc/testsuite/g++.dg/reflect/identifier_of3.C
@@ -4,6 +4,7 @@
// Test std::meta::identifier_of.
#include <meta>
+using namespace std::meta;
void foo (int, int x, int y, int z);
@@ -38,10 +39,10 @@ baz ()
void foo (int w, int, int v, int z);
int bar (int, int, int v, int z, int u);
void qux (int, int x, int y, int z);
- constexpr auto qux1 = parameters_of (^^qux)[0];
- constexpr auto qux2 = parameters_of (^^qux)[1];
- constexpr auto qux3 = parameters_of (^^qux)[2];
- constexpr auto qux4 = parameters_of (^^qux)[3];
+ constexpr auto qux1 = parameters_of (^^qux)[0]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
+ constexpr auto qux2 = parameters_of (^^qux)[1]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
+ constexpr auto qux3 = parameters_of (^^qux)[2]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
+ constexpr auto qux4 = parameters_of (^^qux)[3]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
static_assert (!has_identifier (qux1));
static_assert (identifier_of (qux2) == std::string_view ("x"));
static_assert (identifier_of (qux3) == std::string_view ("y"));
@@ -62,10 +63,10 @@ void
fred ()
{
void qux (int w, int, int v, int z);
- constexpr auto qux1 = parameters_of (^^qux)[0];
- constexpr auto qux2 = parameters_of (^^qux)[1];
- constexpr auto qux3 = parameters_of (^^qux)[2];
- constexpr auto qux4 = parameters_of (^^qux)[3];
+ constexpr auto qux1 = parameters_of (^^qux)[0]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
+ constexpr auto qux2 = parameters_of (^^qux)[1]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
+ constexpr auto qux3 = parameters_of (^^qux)[2]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
+ constexpr auto qux4 = parameters_of (^^qux)[3]; // { dg-error "cannot take the reflection of a block-scope extern .qux." }
static_assert (identifier_of (qux1) == std::string_view ("w"));
static_assert (identifier_of (qux2) == std::string_view ("x"));
static_assert (!has_identifier (qux3));
diff --git a/gcc/testsuite/g++.dg/reflect/pr123612.C b/gcc/testsuite/g++.dg/reflect/pr123612.C
index 97da7bbdd0e3..0dee4ed4f653 100644
--- a/gcc/testsuite/g++.dg/reflect/pr123612.C
+++ b/gcc/testsuite/g++.dg/reflect/pr123612.C
@@ -3,6 +3,7 @@
// { dg-additional-options "-freflection" }
#include <meta>
+using namespace std::meta;
int a;
extern int b;
@@ -12,14 +13,14 @@ consteval auto
bar ()
{
extern int a;
- return ^^a;
+ return ^^a; // { dg-error "cannot take the reflection of a block-scope extern .a." }
}
consteval auto
baz ()
{
extern int b;
- return ^^b;
+ return ^^b; // { dg-error "cannot take the reflection of a block-scope extern .b." }
}
consteval auto
@@ -30,10 +31,10 @@ qux ()
static_assert (has_default_argument (parameters_of (^^foo)[2]));
{
extern int foo (int x, int y = 5, int z = 16);
- static_assert (!has_default_argument (parameters_of (^^foo)[0]));
- static_assert (has_default_argument (parameters_of (^^foo)[1]));
- static_assert (has_default_argument (parameters_of (^^foo)[2]));
- return ^^foo;
+ static_assert (!has_default_argument (parameters_of (^^foo)[0])); // { dg-error "cannot take the reflection of a block-scope extern .foo." }
+ static_assert (has_default_argument (parameters_of (^^foo)[1])); // { dg-error "cannot take the reflection of a block-scope extern .foo." }
+ static_assert (has_default_argument (parameters_of (^^foo)[2])); // { dg-error "cannot take the reflection of a block-scope extern .foo." }
+ return ^^foo; // { dg-error "cannot take the reflection of a block-scope extern .foo." }
}
}
More information about the Gcc-cvs
mailing list