Skip to content

Commit f7d42f6

Browse files
alcaeuskocsismate
authored andcommitted
Update gen_stub to avoid compile errors on duplicate function names
Closes GH-9406
1 parent e3034db commit f7d42f6

File tree

5 files changed

+144
-27
lines changed

5 files changed

+144
-27
lines changed

UPGRADING.INTERNALS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ PHP 8.2 INTERNALS UPGRADE NOTES
6363
========================
6464

6565
* Unsupported libxml2 2.10.0 symbols are no longer exported on Windows.
66+
* Identifier names for namespaced functions generated from stub files through
67+
gen_stub.php have been changed. This requires that namespaced functions
68+
should be declared via the PHP_FUNCTION macro by using the fully qualified
69+
function name (whereas each part is separated by "_") instead of just the
70+
function name itself.
6671

6772
========================
6873
3. Module changes

build/gen_stub.php

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,10 @@ public function getNonNamespacedName(): string {
10371037
}
10381038

10391039
public function getDeclarationName(): string {
1040+
return implode('_', $this->name->parts);
1041+
}
1042+
1043+
public function getFunctionName(): string {
10401044
return $this->name->getLast();
10411045
}
10421046

@@ -1380,39 +1384,42 @@ public function getFunctionEntry(): string {
13801384
}
13811385
} else if ($this->name instanceof FunctionName) {
13821386
$namespace = $this->name->getNamespace();
1383-
$declarationName = $this->name->getDeclarationName();
1387+
$functionName = $this->name->getFunctionName();
1388+
$declarationName = $this->alias ? $this->alias->getNonNamespacedName() : $this->name->getDeclarationName();
1389+
1390+
if ($namespace) {
1391+
// Namespaced functions are always declared as aliases to avoid name conflicts when two functions with
1392+
// the same name exist in separate namespaces
1393+
$macro = $this->isDeprecated ? 'ZEND_NS_DEP_FALIAS' : 'ZEND_NS_FALIAS';
13841394

1385-
if ($this->alias && $this->isDeprecated) {
1395+
// Render A\B as "A\\B" in C strings for namespaces
13861396
return sprintf(
1387-
"\tZEND_DEP_FALIAS(%s, %s, %s)\n",
1388-
$declarationName, $this->alias->getNonNamespacedName(), $this->getArgInfoName()
1397+
"\t%s(\"%s\", %s, %s, %s)\n",
1398+
$macro, addslashes($namespace), $this->name->getFunctionName(), $declarationName, $this->getArgInfoName()
13891399
);
13901400
}
13911401

13921402
if ($this->alias) {
1403+
$macro = $this->isDeprecated ? 'ZEND_DEP_FALIAS' : 'ZEND_FALIAS';
1404+
13931405
return sprintf(
1394-
"\tZEND_FALIAS(%s, %s, %s)\n",
1395-
$declarationName, $this->alias->getNonNamespacedName(), $this->getArgInfoName()
1406+
"\t%s(%s, %s, %s)\n",
1407+
$macro, $functionName, $declarationName, $this->getArgInfoName()
13961408
);
13971409
}
13981410

1399-
if ($this->isDeprecated) {
1400-
return sprintf(
1401-
"\tZEND_DEP_FE(%s, %s)\n", $declarationName, $this->getArgInfoName());
1411+
switch (true) {
1412+
case $this->isDeprecated:
1413+
$macro = 'ZEND_DEP_FE';
1414+
break;
1415+
case $this->supportsCompileTimeEval:
1416+
$macro = 'ZEND_SUPPORTS_COMPILE_TIME_EVAL_FE';
1417+
break;
1418+
default:
1419+
$macro = 'ZEND_FE';
14021420
}
14031421

1404-
if ($namespace) {
1405-
// Render A\B as "A\\B" in C strings for namespaces
1406-
return sprintf(
1407-
"\tZEND_NS_FE(\"%s\", %s, %s)\n",
1408-
addslashes($namespace), $declarationName, $this->getArgInfoName());
1409-
} else {
1410-
if ($this->supportsCompileTimeEval) {
1411-
return sprintf(
1412-
"\tZEND_SUPPORTS_COMPILE_TIME_EVAL_FE(%s, %s)\n", $declarationName, $this->getArgInfoName());
1413-
}
1414-
return sprintf("\tZEND_FE(%s, %s)\n", $declarationName, $this->getArgInfoName());
1415-
}
1422+
return sprintf("\t%s(%s, %s)\n", $macro, $functionName, $this->getArgInfoName());
14161423
} else {
14171424
throw new Error("Cannot happen");
14181425
}

ext/zend_test/test.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ static ZEND_FUNCTION(zend_test_deprecated)
9595
zend_parse_parameters(ZEND_NUM_ARGS(), "|z", &arg1);
9696
}
9797

98+
static ZEND_FUNCTION(zend_test_alias)
99+
{
100+
ZEND_PARSE_PARAMETERS_NONE();
101+
}
102+
103+
static ZEND_FUNCTION(zend_test_deprecated_alias)
104+
{
105+
ZEND_PARSE_PARAMETERS_NONE();
106+
}
107+
98108
/* Create a string without terminating null byte. Must be terminated with
99109
* zend_terminate_string() before destruction, otherwise a warning is issued
100110
* in debug builds. */
@@ -415,12 +425,38 @@ static ZEND_FUNCTION(zend_test_zend_ini_parse_uquantity)
415425
}
416426
}
417427

418-
static ZEND_FUNCTION(namespaced_func)
428+
static ZEND_FUNCTION(ZendTestNS2_namespaced_func)
419429
{
420430
ZEND_PARSE_PARAMETERS_NONE();
421431
RETURN_TRUE;
422432
}
423433

434+
static ZEND_FUNCTION(ZendTestNS2_namespaced_deprecated_func)
435+
{
436+
ZEND_PARSE_PARAMETERS_NONE();
437+
}
438+
439+
static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_func)
440+
{
441+
ZEND_PARSE_PARAMETERS_NONE();
442+
RETURN_TRUE;
443+
}
444+
445+
static ZEND_FUNCTION(ZendTestNS2_ZendSubNS_namespaced_deprecated_func)
446+
{
447+
ZEND_PARSE_PARAMETERS_NONE();
448+
}
449+
450+
static ZEND_FUNCTION(namespaced_alias_func)
451+
{
452+
ZEND_PARSE_PARAMETERS_NONE();
453+
}
454+
455+
static ZEND_FUNCTION(namespaced_deprecated_alias_func)
456+
{
457+
ZEND_PARSE_PARAMETERS_NONE();
458+
}
459+
424460
static ZEND_FUNCTION(zend_test_parameter_with_attribute)
425461
{
426462
zend_string *parameter;

ext/zend_test/test.stub.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ function zend_test_compile_string(string $source_string, string $filename, int $
109109
/** @deprecated */
110110
function zend_test_deprecated(mixed $arg = null): void {}
111111

112+
/** @alias zend_test_alias */
113+
function zend_test_aliased(): void {}
114+
115+
/**
116+
* @deprecated
117+
* @alias zend_test_deprecated_alias
118+
*/
119+
function zend_test_deprecated_aliased(): void {}
120+
112121
function zend_create_unterminated_string(string $str): string {}
113122

114123
function zend_terminate_string(string &$str): void {}
@@ -168,6 +177,20 @@ class Foo {
168177
public function method(): void {}
169178
}
170179

180+
function namespaced_func(): bool {}
181+
182+
/** @deprecated */
183+
function namespaced_deprecated_func(): void {}
184+
185+
/** @alias namespaced_alias_func */
186+
function namespaced_aliased_func(): void {}
187+
188+
/**
189+
* @deprecated
190+
* @alias namespaced_deprecated_alias_func
191+
*/
192+
function namespaced_deprecated_aliased_func(): void {}
193+
171194
}
172195

173196
namespace ZendTestNS2\ZendSubNS {
@@ -178,4 +201,16 @@ public function method(): void {}
178201

179202
function namespaced_func(): bool {}
180203

204+
/** @deprecated */
205+
function namespaced_deprecated_func(): void {}
206+
207+
/** @alias namespaced_alias_func */
208+
function namespaced_aliased_func(): void {}
209+
210+
/**
211+
* @deprecated
212+
* @alias namespaced_deprecated_alias_func
213+
*/
214+
function namespaced_deprecated_aliased_func(): void {}
215+
181216
}

ext/zend_test/test_arginfo.h

Lines changed: 39 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)