Hi!
I found 2 bugs in the plugin.
It wasn't walking class template members (that fixes e.g. the atomic_base.h
stuff but shows other stuff) and it didn't ignore auto:NN names (I guess
DECL_ARTIFICIAL check would leave those out maybe too but I was afraid of
using it just in case something based on the source gets DECL_ARTIFICIAL
flag).
Interdiff from previous patch is:
@@ -79,6 +79,9 @@
+ return;
+
+ const char *cname = IDENTIFIER_POINTER (name);
++ if (memcmp (cname, "auto:", 5) == 0)
++ return;
++
+ if (cname[0] != '_'
+ || (cname[1] != '_'
+ && !ISUPPER (cname[1])
@@ -183,6 +186,8 @@
+ if (DECL_FUNCTION_TEMPLATE_P (decl))
+ plugin_check_fn (DECL_TEMPLATE_RESULT (decl));
+
++ if (DECL_CLASS_TEMPLATE_P (decl))
++ decl = DECL_TEMPLATE_RESULT (decl);
+ if (TREE_CODE (decl) == TYPE_DECL
+ && DECL_IMPLICIT_TYPEDEF_P (decl))
+ {
With this what I get is (only mentioning the non-whitelisted stuff now).
subs is IMHO a bug in the headers, /ext/ is up to Jonathan to decide what to
do (comment out <bits/extc++.h>, blacklist those 2 headers, fix them).
set_debug_format is in https://eel.is/c++draft/libraryindex and so
are the <generator> ones, and max_load_factor is too, haven't figured out
yet what's going on with those.
submdspan_mapping is something weird, not in the index, but mentioned in
https://eel.is/c++draft/mdspan.sub.map#sliceable-2 so probably needs to be
whitelisted directly in the plugin for cxx_dialect >= cxx26.
libstdc++-v3/include/bits/chrono_io.h:1885:47: note: non-uglified name 'subs'
libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp:145:34:
note: non-uglified name 'n'
libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp:157:35:
note: non-uglified name 'n'
libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp:159:28:
note: non-uglified name 'p_upper'
libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp:170:36:
note: non-uglified name 'n'
libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_prime_size_policy_imp.hpp:172:22:
note: non-uglified name 'p_lower'
libstdc++-v3/include/ext/throw_allocator.h:116:22: note: non-uglified name 'l'
libstdc++-v3/include/ext/throw_allocator.h:126:18: note: non-uglified name
'entry'
libstdc++-v3/include/ext/throw_allocator.h:134:49: note: non-uglified name
'inserted'
libstdc++-v3/include/ext/throw_allocator.h:159:12: note: non-uglified name
'inserted'
libstdc++-v3/include/ext/throw_allocator.h:178:32: note: non-uglified name
'found'
libstdc++-v3/include/ext/throw_allocator.h:201:18: note: non-uglified name
'label'
libstdc++-v3/include/ext/throw_allocator.h:203:19: note: non-uglified name
'found'
libstdc++-v3/include/ext/throw_allocator.h:240:19: note: non-uglified name
'found'
libstdc++-v3/include/ext/throw_allocator.h:275:12: note: non-uglified name
'found'
libstdc++-v3/include/ext/throw_allocator.h:288:30: note: non-uglified name
'label'
libstdc++-v3/include/ext/throw_allocator.h:292:19: note: non-uglified name
'found'
libstdc++-v3/include/ext/throw_allocator.h:318:32: note: non-uglified name 's'
libstdc++-v3/include/ext/throw_allocator.h:324:12: note: non-uglified name 'buf'
libstdc++-v3/include/ext/throw_allocator.h:325:18: note: non-uglified name 'tab'
libstdc++-v3/include/ext/throw_allocator.h:327:21: note: non-uglified name 'l'
libstdc++-v3/include/ext/throw_allocator.h:350:12: note: non-uglified name 'buf'
libstdc++-v3/include/ext/throw_allocator.h:351:18: note: non-uglified name 'tab'
libstdc++-v3/include/ext/throw_allocator.h:353:21: note: non-uglified name 'l'
libstdc++-v3/include/ext/throw_allocator.h:389:28: note: non-uglified name 'os'
libstdc++-v3/include/ext/throw_allocator.h:392:27: note: non-uglified name
'base_type'
libstdc++-v3/include/ext/throw_allocator.h:574:31: note: non-uglified name
'distribution'
libstdc++-v3/include/ext/throw_allocator.h:575:19: note: non-uglified name
'generator'
libstdc++-v3/include/ext/throw_allocator.h:578:75: note: non-uglified name
'gen_t'
libstdc++-v3/include/ext/throw_allocator.h:580:20: note: non-uglified name
'generator'
libstdc++-v3/include/ext/throw_allocator.h:587:14: note: non-uglified name
'random'
libstdc++-v3/include/ext/throw_allocator.h:593:16: note: non-uglified name 'buf'
libstdc++-v3/include/format:1477:7: note: non-uglified name 'set_debug_format'
libstdc++-v3/include/format:5783:7: note: non-uglified name 'set_debug_format'
libstdc++-v3/include/format:5913:11: note: non-uglified name 'set_debug_format'
libstdc++-v3/include/generator:130:9: note: non-uglified name 'initial_suspend'
libstdc++-v3/include/generator:134:9: note: non-uglified name 'yield_value'
libstdc++-v3/include/generator:141:9: note: non-uglified name 'yield_value'
libstdc++-v3/include/generator:152:9: note: non-uglified name 'yield_value'
libstdc++-v3/include/generator:162:9: note: non-uglified name 'yield_value'
libstdc++-v3/include/generator:169:9: note: non-uglified name 'yield_value'
libstdc++-v3/include/generator:186:9: note: non-uglified name 'final_suspend'
libstdc++-v3/include/generator:190:9: note: non-uglified name
'unhandled_exception'
libstdc++-v3/include/generator:203:14: note: non-uglified name 'await_transform'
libstdc++-v3/include/generator:204:14: note: non-uglified name 'return_void'
libstdc++-v3/include/mdspan:3385:10: note: non-uglified name 'submdspan_mapping'
libstdc++-v3/include/tr1/hashtable_policy.h:387:5: note: non-uglified name
'max_load_factor'
2026-03-17 Jakub Jelinek <[email protected]>
* g++.dg/plugin/plugin.exp (plugin_test_list): Add uglification tests.
* g++.dg/plugin/uglification_plugin.cc: New file.
* g++.dg/plugin/uglification-c++98.C: New test.
* g++.dg/plugin/uglification-c++11.C: New test.
* g++.dg/plugin/uglification-c++14.C: New test.
* g++.dg/plugin/uglification-c++17.C: New test.
* g++.dg/plugin/uglification-c++20.C: New test.
* g++.dg/plugin/uglification-c++23.C: New test.
* g++.dg/plugin/uglification-c++26.C: New test.
--- gcc/testsuite/g++.dg/plugin/plugin.exp.jj 2026-01-02 09:56:10.336333661
+0100
+++ gcc/testsuite/g++.dg/plugin/plugin.exp 2026-03-17 16:54:28.967391245
+0100
@@ -78,6 +78,14 @@ set plugin_test_list [list \
show-template-tree-color-no-highlight-colors.C \
show-template-tree-color-labels.C \
show-template-tree-color-no-elide-type.C } \
+ { uglification_plugin.cc \
+ uglification-c++98.C \
+ uglification-c++11.C \
+ uglification-c++14.C \
+ uglification-c++17.C \
+ uglification-c++20.C \
+ uglification-c++23.C \
+ uglification-c++26.C } \
{ comment_plugin.cc comments-1.C } \
]
--- gcc/testsuite/g++.dg/plugin/uglification_plugin.cc.jj 2026-03-17
16:37:46.128622695 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification_plugin.cc 2026-03-17
21:15:32.898848906 +0100
@@ -0,0 +1,250 @@
+#include "gcc-plugin.h"
+#include <stdlib.h>
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "intl.h"
+#include "cp/cp-tree.h"
+#include "cp/name-lookup.h"
+#include "diagnostic.h"
+
+int plugin_is_GPL_compatible;
+
+void plugin_walk_ns (tree);
+
+const char *badnames[] = {
+ /* See libstdc++-v3/testsuite/17_intro/{,bad}names.cc. */
+ "_A", "_B", "_C", "_G", "_L", "_N", "_P", "_S", "_T", "_U", "_X",
+ "__deref", "__used", "__unused", "__inline", "_Complex",
+ "__istype", "__maskrune", "__tolower", "__toupper", "__wchar_t",
+ "__wint_t", "_res", "_res_ext", "_C2", "__lockable", "__null_sentinel",
+ "__packed", "__weak", "__strong", "_In_", "_Inout_", "_Out_",
+ "_Reserved_", "__inout", "__in_opt", "__out_opt"
+};
+
+vec<tree> nonugly_names;
+hash_set<tree> whitelist;
+bool impl_ns;
+
+void
+plugin_check_decl (tree decl)
+{
+ if (decl == NULL_TREE)
+ return;
+
+ if (VAR_OR_FUNCTION_DECL_P (decl)
+ && DECL_EXTERNAL (decl)
+ && DECL_CONTEXT (decl)
+ && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
+ return;
+
+ tree name = DECL_NAME (decl);
+ if (name == NULL_TREE
+ || IDENTIFIER_ANON_P (name)
+ || name == this_identifier
+ || IDENTIFIER_ANY_OP_P (name))
+ return;
+
+ const char *cname = IDENTIFIER_POINTER (name);
+ if (memcmp (cname, "auto:", 5) == 0)
+ return;
+
+ if (cname[0] != '_'
+ || (cname[1] != '_'
+ && !ISUPPER (cname[1])
+ && cname[1]))
+ {
+ nonugly_names.safe_push (decl);
+ return;
+ }
+
+ bool badname = false;
+ for (int i = 0; i < ARRAY_SIZE (badnames); ++i)
+ if (strcmp (badnames[i], cname) == 0)
+ {
+ badname = true;
+ break;
+ }
+ if (!badname && cname[1] == 'E' && ISDIGIT (cname[2]))
+ {
+ if (cname[2] != '0'
+ && (!cname[3] || ((cname[2] == '1' || cname[2] == '2')
+ && ISDIGIT (cname[3])
+ && !cname[4])))
+ badname = true;
+ }
+ else if (memcmp (cname + 1, "_tg_", 4) == 0)
+ badname = true;
+ if (badname)
+ inform (DECL_SOURCE_LOCATION (decl), "badname %qs", cname);
+}
+
+tree
+plugin_check_tree (tree *tp, int */*walk_subtrees*/, void */*data*/)
+{
+ if (TREE_CODE (*tp) == BIND_EXPR)
+ for (tree var = BIND_EXPR_VARS (*tp); var; var = DECL_CHAIN (var))
+ plugin_check_decl (var);
+ if (TREE_CODE (*tp) == DECL_EXPR)
+ plugin_check_decl (DECL_EXPR_DECL (*tp));
+ return NULL_TREE;
+}
+
+void
+plugin_check_fn (tree decl)
+{
+ for (tree arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg))
+ plugin_check_decl (arg);
+
+ cp_walk_tree_without_duplicates (&DECL_SAVED_TREE (decl), plugin_check_tree,
+ NULL);
+}
+
+bool
+plugin_header_check (tree decl)
+{
+ expanded_location eloc = expand_location (DECL_SOURCE_LOCATION (decl));
+ if (eloc.file == NULL)
+ return false;
+ if (strstr (eloc.file, "/libstdc++-v3/include/") == NULL
+ && strstr (eloc.file, "/libstdc++-v3/libsupc++/") == NULL)
+ return false;
+ return true;
+}
+
+void
+plugin_walk_decl (tree decl)
+{
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ {
+ if (impl_ns
+ || (DECL_NAME (decl)
+ && IDENTIFIER_POINTER (DECL_NAME (decl))[0] != '_')
+ || DECL_NAMESPACE_INLINE_P (decl))
+ plugin_walk_ns (decl);
+ else
+ {
+ impl_ns = true;
+ plugin_walk_ns (decl);
+ impl_ns = false;
+ }
+ return;
+ }
+
+ if (!plugin_header_check (decl))
+ return;
+
+ if (!impl_ns
+ && DECL_NAME (decl)
+ && !IDENTIFIER_ANON_P (DECL_NAME (decl))
+ && !IDENTIFIER_ANY_OP_P (DECL_NAME (decl))
+ && IDENTIFIER_POINTER (DECL_NAME (decl))[0] != '_')
+ whitelist.add (DECL_NAME (decl));
+ else if (impl_ns && DECL_NAME (decl))
+ plugin_check_decl (decl);
+
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ {
+ tree parms = DECL_INNERMOST_TEMPLATE_PARMS (decl);
+ for (tree node : tree_vec_range (parms))
+ plugin_check_decl (TREE_VALUE (node));
+ }
+
+ if (DECL_FUNCTION_TEMPLATE_P (decl))
+ plugin_check_fn (DECL_TEMPLATE_RESULT (decl));
+
+ if (DECL_CLASS_TEMPLATE_P (decl))
+ decl = DECL_TEMPLATE_RESULT (decl);
+ if (TREE_CODE (decl) == TYPE_DECL
+ && DECL_IMPLICIT_TYPEDEF_P (decl))
+ {
+ if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+ for (tree fld = TYPE_FIELDS (TREE_TYPE (decl));
+ fld; fld = DECL_CHAIN (fld))
+ plugin_walk_decl (fld);
+ else if (TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
+ for (tree en = TYPE_VALUES (TREE_TYPE (decl));
+ en; en = TREE_CHAIN (en))
+ plugin_walk_decl (TREE_VALUE (en));
+ }
+}
+
+void
+plugin_walk_binding (tree binding)
+{
+ tree value = NULL_TREE;
+
+ if (STAT_HACK_P (binding))
+ {
+ if (!STAT_TYPE_HIDDEN_P (binding)
+ && STAT_TYPE (binding))
+ return plugin_walk_decl (STAT_TYPE (binding));
+ else if (!STAT_DECL_HIDDEN_P (binding))
+ value = STAT_DECL (binding);
+ }
+ else
+ value = binding;
+
+ value = ovl_skip_hidden (value);
+ if (value)
+ {
+ value = OVL_FIRST (value);
+ return plugin_walk_decl (value);
+ }
+}
+
+void
+plugin_walk_ns (tree ns)
+{
+ using itert = hash_table<named_decl_hash>::iterator;
+ itert end (DECL_NAMESPACE_BINDINGS (ns)->end ());
+ for (itert iter (DECL_NAMESPACE_BINDINGS (ns)->begin ());
+ iter != end; ++iter)
+ {
+ tree b = *iter;
+ gcc_assert (TREE_CODE (b) != BINDING_VECTOR);
+ plugin_walk_binding (b);
+ }
+}
+
+void
+plugin_finish_parse_function (void *event_data, void *)
+{
+ tree decl = (tree) event_data;
+ if (!plugin_header_check (decl))
+ return;
+
+ /* Templates are handled from plugin_walk_ns. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
+ return;
+ plugin_check_fn (decl);
+}
+
+void
+plugin_finish_unit (void *, void *)
+{
+ plugin_walk_ns (std_node);
+ unsigned int i;
+ tree decl;
+ FOR_EACH_VEC_ELT (nonugly_names, i, decl)
+ if (!whitelist.contains (DECL_NAME (decl)))
+ inform (DECL_SOURCE_LOCATION (decl), "non-uglified name %qs",
+ IDENTIFIER_POINTER (DECL_NAME (decl)));
+ else
+ inform (DECL_SOURCE_LOCATION (decl), "non-uglified whitelisted name %qs",
+ IDENTIFIER_POINTER (DECL_NAME (decl)));
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ const char *plugin_name = plugin_info->base_name;
+
+ register_callback (plugin_name, PLUGIN_FINISH_UNIT,
+ plugin_finish_unit, NULL);
+ register_callback (plugin_name, PLUGIN_FINISH_PARSE_FUNCTION,
+ plugin_finish_parse_function, NULL);
+ return 0;
+}
--- gcc/testsuite/g++.dg/plugin/uglification-c++98.C.jj 2026-03-17
16:52:27.238446844 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification-c++98.C 2026-03-17
16:52:40.508222726 +0100
@@ -0,0 +1,10 @@
+// Verify template parameter names, names of arguments and block scope decls
+// in functions and function templates are uglified and don't contain
+// badnames.
+// { dg-options "-O0 -std=c++98" }
+
+#include <bits/stdc++.h>
+#include <bits/extc++.h>
+
+// { dg-bogus "note: non-uglified name" "" { target *-*-* } 0 }
+// { dg-bogus "note: badname" "" { target *-*-* } 0 }
--- gcc/testsuite/g++.dg/plugin/uglification-c++11.C.jj 2026-03-17
16:52:52.727016358 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification-c++11.C 2026-03-17
16:52:56.556951673 +0100
@@ -0,0 +1,10 @@
+// Verify template parameter names, names of arguments and block scope decls
+// in functions and function templates are uglified and don't contain
+// badnames.
+// { dg-options "-O0 -std=c++11" }
+
+#include <bits/stdc++.h>
+#include <bits/extc++.h>
+
+// { dg-bogus "note: non-uglified name" "" { target *-*-* } 0 }
+// { dg-bogus "note: badname" "" { target *-*-* } 0 }
--- gcc/testsuite/g++.dg/plugin/uglification-c++14.C.jj 2026-03-17
16:53:46.707104669 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification-c++14.C 2026-03-17
16:53:16.031622759 +0100
@@ -0,0 +1,10 @@
+// Verify template parameter names, names of arguments and block scope decls
+// in functions and function templates are uglified and don't contain
+// badnames.
+// { dg-options "-O0 -std=c++14" }
+
+#include <bits/stdc++.h>
+#include <bits/extc++.h>
+
+// { dg-bogus "note: non-uglified name" "" { target *-*-* } 0 }
+// { dg-bogus "note: badname" "" { target *-*-* } 0 }
--- gcc/testsuite/g++.dg/plugin/uglification-c++17.C.jj 2026-03-17
16:54:00.757867359 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification-c++17.C 2026-03-17
16:53:21.357532805 +0100
@@ -0,0 +1,10 @@
+// Verify template parameter names, names of arguments and block scope decls
+// in functions and function templates are uglified and don't contain
+// badnames.
+// { dg-options "-O0 -std=c++17" }
+
+#include <bits/stdc++.h>
+#include <bits/extc++.h>
+
+// { dg-bogus "note: non-uglified name" "" { target *-*-* } 0 }
+// { dg-bogus "note: badname" "" { target *-*-* } 0 }
--- gcc/testsuite/g++.dg/plugin/uglification-c++20.C.jj 2026-03-17
16:54:00.757867359 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification-c++20.C 2026-03-17
16:53:27.575427792 +0100
@@ -0,0 +1,10 @@
+// Verify template parameter names, names of arguments and block scope decls
+// in functions and function templates are uglified and don't contain
+// badnames.
+// { dg-options "-O0 -std=c++20" }
+
+#include <bits/stdc++.h>
+#include <bits/extc++.h>
+
+// { dg-bogus "note: non-uglified name" "" { target *-*-* } 0 }
+// { dg-bogus "note: badname" "" { target *-*-* } 0 }
--- gcc/testsuite/g++.dg/plugin/uglification-c++23.C.jj 2026-03-17
16:54:00.757867359 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification-c++23.C 2026-03-17
16:53:36.641274675 +0100
@@ -0,0 +1,10 @@
+// Verify template parameter names, names of arguments and block scope decls
+// in functions and function templates are uglified and don't contain
+// badnames.
+// { dg-options "-O0 -std=c++23" }
+
+#include <bits/stdc++.h>
+#include <bits/extc++.h>
+
+// { dg-bogus "note: non-uglified name" "" { target *-*-* } 0 }
+// { dg-bogus "note: badname" "" { target *-*-* } 0 }
--- gcc/testsuite/g++.dg/plugin/uglification-c++26.C.jj 2026-03-17
16:54:00.757867359 +0100
+++ gcc/testsuite/g++.dg/plugin/uglification-c++26.C 2026-03-17
16:53:41.819187221 +0100
@@ -0,0 +1,10 @@
+// Verify template parameter names, names of arguments and block scope decls
+// in functions and function templates are uglified and don't contain
+// badnames.
+// { dg-options "-O0 -std=c++26" }
+
+#include <bits/stdc++.h>
+#include <bits/extc++.h>
+
+// { dg-bogus "note: non-uglified name" "" { target *-*-* } 0 }
+// { dg-bogus "note: badname" "" { target *-*-* } 0 }
Jakub