@@ -283,8 +283,8 @@ if(PHP_ADDRESS_SANITIZER)
283283 cmake_push_check_state(RESET)
284284 set (CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=address" )
285285
286- php_check_compiler_flag(C " -fsanitize=address" HAVE_ADDRESS_SANITIZER_C)
287- php_check_compiler_flag(CXX " -fsanitize=address" HAVE_ADDRESS_SANITIZER_CXX)
286+ php_check_compiler_flag(C -fsanitize=address HAVE_ADDRESS_SANITIZER_C)
287+ php_check_compiler_flag(CXX -fsanitize=address HAVE_ADDRESS_SANITIZER_CXX)
288288 cmake_pop_check_state()
289289
290290 if (HAVE_ADDRESS_SANITIZER_C AND HAVE_ADDRESS_SANITIZER_CXX)
@@ -320,8 +320,16 @@ if(PHP_UNDEFINED_SANITIZER)
320320 cmake_push_check_state(RESET)
321321 set (CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=undefined" )
322322
323- php_check_compiler_flag(C "-fsanitize=undefined" HAVE_UNDEFINED_SANITIZER_C)
324- php_check_compiler_flag(CXX "-fsanitize=undefined" HAVE_UNDEFINED_SANITIZER_CXX)
323+ php_check_compiler_flag(
324+ C
325+ -fsanitize=undefined
326+ HAVE_UNDEFINED_SANITIZER_C
327+ )
328+ php_check_compiler_flag(
329+ CXX
330+ -fsanitize=undefined
331+ HAVE_UNDEFINED_SANITIZER_CXX
332+ )
325333 cmake_pop_check_state()
326334
327335 if (HAVE_UNDEFINED_SANITIZER_C AND HAVE_UNDEFINED_SANITIZER_CXX)
@@ -342,8 +350,16 @@ if(PHP_UNDEFINED_SANITIZER)
342350 cmake_push_check_state(RESET)
343351 set (CMAKE_REQUIRED_LINK_OPTIONS "-fno-sanitize=object-size" )
344352
345- php_check_compiler_flag(C "-fno-sanitize=object-size" HAVE_OBJECT_SIZE_SANITIZER_C)
346- php_check_compiler_flag(CXX "-fno-sanitize=object-size" HAVE_OBJECT_SIZE_SANITIZER_CXX)
353+ php_check_compiler_flag(
354+ C
355+ -fno-sanitize=object-size
356+ HAVE_OBJECT_SIZE_SANITIZER_C
357+ )
358+ php_check_compiler_flag(
359+ CXX
360+ -fno-sanitize=object-size
361+ HAVE_OBJECT_SIZE_SANITIZER_CXX
362+ )
347363 cmake_pop_check_state()
348364
349365 if (HAVE_OBJECT_SIZE_SANITIZER_C AND HAVE_OBJECT_SIZE_SANITIZER_CXX)
@@ -362,43 +378,60 @@ if(PHP_UNDEFINED_SANITIZER)
362378
363379 # Clang 17 adds stricter function pointer compatibility checks where pointer
364380 # args cannot be cast to void*. In that case, set -fno-sanitize=function.
365- if (NOT CMAKE_CROSSCOMPILING )
366- cmake_push_check_state(RESET)
367- set (
368- CMAKE_REQUIRED_FLAGS
369- "-fsanitize=undefined -fno-sanitize-recover=undefined"
381+ if (
382+ NOT DEFINED PHP_HAVE_UBSAN_EXITCODE
383+ AND CMAKE_CROSSCOMPILING
384+ AND NOT CMAKE_CROSSCOMPILING_EMULATOR
385+ AND CMAKE_C_COMPILER_ID STREQUAL "Clang"
386+ AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 17
387+ )
388+ # When cross-compiling without emulator and using Clang 17 and greater,
389+ # assume that -fno-sanitize=function needs to be added.
390+ set (PHP_HAVE_UBSAN_EXITCODE 1)
391+ endif ()
392+
393+ cmake_push_check_state(RESET)
394+ set (
395+ CMAKE_REQUIRED_FLAGS
396+ "-fsanitize=undefined -fno-sanitize-recover=undefined"
397+ )
398+ check_source_runs(C [[
399+ void foo(char *string) { (void)string; }
400+ int main(void)
401+ {
402+ void (*f)(void *) = (void (*)(void *))foo;
403+ f("foo");
404+ return 0;
405+ }
406+ ]] PHP_HAVE_UBSAN)
407+ cmake_pop_check_state()
408+
409+ if (NOT PHP_HAVE_UBSAN)
410+ php_check_compiler_flag(
411+ C
412+ -fno-sanitize=function
413+ HAVE_FNO_SANITIZE_FUNCTION_C
414+ )
415+ php_check_compiler_flag(
416+ CXX
417+ -fno-sanitize=function
418+ HAVE_FNO_SANITIZE_FUNCTION_CXX
419+ )
420+
421+ if (HAVE_FNO_SANITIZE_FUNCTION_C)
422+ target_compile_options (
423+ php_configuration
424+ INTERFACE
425+ $<$<COMPILE_LANGUAGE:ASM,C>:-fno-sanitize=function>
426+ )
427+ endif ()
428+
429+ if (HAVE_FNO_SANITIZE_FUNCTION_CXX)
430+ target_compile_options (
431+ php_configuration
432+ INTERFACE
433+ $<$<COMPILE_LANGUAGE:CXX>:-fno-sanitize=function>
370434 )
371- check_source_runs(C [[
372- void foo(char *string) {
373- (void)string;
374- }
375- int main(void) {
376- void (*f)(void *) = (void (*)(void *))foo;
377- f("foo");
378- return 0;
379- }
380- ]] _php_ubsan_works)
381- cmake_pop_check_state()
382-
383- if (NOT _php_ubsan_works)
384- php_check_compiler_flag(C -fno-sanitize=function HAVE_FNO_SANITIZE_FUNCTION_C)
385- php_check_compiler_flag(CXX -fno-sanitize=function HAVE_FNO_SANITIZE_FUNCTION_CXX)
386-
387- if (HAVE_FNO_SANITIZE_FUNCTION_C)
388- target_compile_options (
389- php_configuration
390- INTERFACE
391- $<$<COMPILE_LANGUAGE:ASM,C>:-fno-sanitize=function>
392- )
393- endif ()
394-
395- if (HAVE_FNO_SANITIZE_FUNCTION_CXX)
396- target_compile_options (
397- php_configuration
398- INTERFACE
399- $<$<COMPILE_LANGUAGE:CXX>:-fno-sanitize=function>
400- )
401- endif ()
402435 endif ()
403436 endif ()
404437
@@ -410,8 +443,16 @@ if(PHP_UNDEFINED_SANITIZER)
410443endif ()
411444
412445if (PHP_MEMORY_SANITIZER OR PHP_ADDRESS_SANITIZER OR PHP_UNDEFINED_SANITIZER)
413- php_check_compiler_flag(C -fno-omit-frame-pointer HAVE_FNO_OMIT_FRAME_POINTER_C)
414- php_check_compiler_flag(CXX -fno-omit-frame-pointer HAVE_FNO_OMIT_FRAME_POINTER_CXX)
446+ php_check_compiler_flag(
447+ C
448+ -fno-omit-frame-pointer
449+ HAVE_FNO_OMIT_FRAME_POINTER_C
450+ )
451+ php_check_compiler_flag(
452+ CXX
453+ -fno-omit-frame-pointer
454+ HAVE_FNO_OMIT_FRAME_POINTER_CXX
455+ )
415456
416457 if (HAVE_FNO_OMIT_FRAME_POINTER_C)
417458 target_compile_options (
0 commit comments