From 6de8837239b4b047df3c7b130beb6eefe34e26d7 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Tue, 2 Sep 2025 18:54:03 -0600 Subject: [PATCH 1/2] Add macro PERL_UNIQUE_NAME This macro acts like a factory to produce a name from its argument that also includes the line number. --- perl.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/perl.h b/perl.h index 46c41c174ba7..e6090a26d3e0 100644 --- a/perl.h +++ b/perl.h @@ -4208,6 +4208,14 @@ Obsolete form of C, which you should convert to instead use # define UVf UVuf #endif +/* Use this like: + * #define sv1_ PERL_UNIQUE_NAME(sv) + * and it will expand to something very likely unique to your file, beginning + * with 'PL_' which means there should be no name collision with the caller. + * an underscore. If two 'sv1_' are attempted to be defined, a compiler + * warning will get raised, so you can change one of them. */ +#define PERL_UNIQUE_NAME(name) CAT2(PL_, CAT2(name, __LINE__)) + #if !defined(DEBUGGING) && !defined(NDEBUG) # define NDEBUG 1 #endif @@ -4323,15 +4331,9 @@ where it has parity with the other two forms. * We use a bit-field instead of an array because gcc accepts typedef char x[n] where n is not a compile-time constant. We want to enforce constantness. - * - * We need the FOOL macros to get proper cpp parameter concatanation. */ -# define STATIC_ASSERT_STRUCT_NAME_FOOL_CPP_2_(line) \ - static_assertion_failed_##line -# define STATIC_ASSERT_STRUCT_NAME_FOOL_CPP_(line) \ - STATIC_ASSERT_STRUCT_NAME_FOOL_CPP_2_(line) + */ /* Return the struct and element name */ -# define STATIC_ASSERT_STRUCT_NAME_ \ - STATIC_ASSERT_STRUCT_NAME_FOOL_CPP_(__LINE__) +# define STATIC_ASSERT_STRUCT_NAME_ PERL_UNIQUE_NAME(static_assertion_failed_) /* Return the struct body */ # define STATIC_ASSERT_STRUCT_BODY_(COND, NAME) \ From cfccf6050aee07c4092e82d2fd833b0cd6bd0c8a Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Tue, 2 Sep 2025 22:12:39 -0600 Subject: [PATCH 2/2] Change names in OpTYPE_set() to avoid possible collisions This uses the PERL_UNIQUE_NAME() macro created in the previous commit to get unique names for variables in macro expansions. Suppose you have #define foo STMT_START { ... } STMT_END block, and have a variable 'bar' declared in it. By first saying #define bar PERL_UNIQUE_NAME(bar) 'bar' will be replaced in the expansion of 'foo' by a unique value. It is your responsibility to not have two 'bar' symbols in the same program. But if you forget, you will be warned by the compiler that 'bar' is redefined, so you can fix it . --- op.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/op.h b/op.h index 87b5adfa8c42..a792ff6d4947 100644 --- a/op.h +++ b/op.h @@ -64,12 +64,14 @@ typedef PERL_BITFIELD16 Optype; U8 op_private; #endif +#define o1_ PERL_UNIQUE_NAME(o) +#define type1_ PERL_UNIQUE_NAME(type) #define OpTYPE_set(o,type) \ STMT_START { \ - OP *o_ = (OP *)o; \ - OPCODE type_ = type; \ - o_->op_type = type_; \ - o_->op_ppaddr = PL_ppaddr[type_]; \ + OP *o1_ = (OP *)o; \ + OPCODE type1_ = type; \ + o1_->op_type = type1_; \ + o1_->op_ppaddr = PL_ppaddr[type1_]; \ } STMT_END /* If op_type:9 is changed to :10, also change cx_pusheval()