Skip to content

ext/intl: fix clang build.#18535

Open
devnexen wants to merge 3 commits into
php:PHP-8.3from
devnexen:fix_intl_clang
Open

ext/intl: fix clang build.#18535
devnexen wants to merge 3 commits into
php:PHP-8.3from
devnexen:fix_intl_clang

Conversation

@devnexen

Copy link
Copy Markdown
Member

actually, with recent icu releases, this problem arises

checking whether clang++ supports C++17 features with -std=c++17... no
checking whether clang++ supports C++17 features with +std=c++17... no
checking whether clang++ supports C++17 features with -h std=c++17... no
checking whether clang++ supports C++17 features with -std=c++1z... no
checking whether clang++ supports C++17 features with +std=c++1z... no
checking whether clang++ supports C++17 features with -h std=c++1z... no
configure: error: *** A compiler with support for C++17 language features is required.

thus, proposing to falls into LLVM libc++ instead.

actually, with recent icu releases, this problem arises

```
checking whether clang++ supports C++17 features with -std=c++17... no
checking whether clang++ supports C++17 features with +std=c++17... no
checking whether clang++ supports C++17 features with -h std=c++17... no
checking whether clang++ supports C++17 features with -std=c++1z... no
checking whether clang++ supports C++17 features with +std=c++1z... no
checking whether clang++ supports C++17 features with -h std=c++1z... no
configure: error: *** A compiler with support for C++17 language features is required.
```

thus, proposing to falls into LLVM libc++ instead.
@devnexen

Copy link
Copy Markdown
Member Author

note it happens only when ubsan is enabled.

@devnexen

devnexen commented May 11, 2025

Copy link
Copy Markdown
Member Author

so intl itself might be compiled with rtti however we compile c++ w/o exceptions nor rtti (lean binaries ?) so had to disable vptr sanitizer check.

@devnexen
devnexen marked this pull request as ready for review May 11, 2025 13:18
@devnexen
devnexen requested a review from TimWolla as a code owner May 11, 2025 13:18
@TimWolla
TimWolla removed their request for review May 11, 2025 13:57
@devnexen
devnexen requested a review from iluuu1994 May 11, 2025 14:48
@iluuu1994

Copy link
Copy Markdown
Member

Sadly, I'm not very qualified to review this. 🙁 Maybe @petk can help?

@devnexen

devnexen commented May 17, 2025

Copy link
Copy Markdown
Member Author

Sadly, I'm not very qualified to review this. 🙁 Maybe @petk can help?

fair enough :) I suspect this might be one of the reasons @YuanchengJiang never build intl with clang (this PR fixes two distinct issues).

@petk

petk commented May 23, 2025

Copy link
Copy Markdown
Member

Hello, I can't seem to reproduce exactly this kind issue (but a whole lots of other ones unrelated to this issue :D). I've checked master branch, clang 18 (with llvm installed and without), clang 19, ICU library 74, with this:

CC=clang CXX=clang++ ./configure --enable-intl --enable-undefined-sanitizer

I have no idea. Does perhaps installing llvm library for that clang compiler help?

@devnexen

Copy link
Copy Markdown
Member Author

Hello, I can't seem to reproduce exactly this kind issue (but a whole lots of other ones unrelated to this issue :D). I've checked master branch, clang 18 (with llvm installed and without), clang 19, ICU library 74, with this:

CC=clang CXX=clang++ ./configure --enable-intl --enable-undefined-sanitizer

I have no idea. Does perhaps installing llvm library for that clang compiler help?

@petk long time no see :) did you try to build ? indeed with my other machine configure part pass but I stumble across linkage issue and yes I have llvm-dev/llvm installed. I may retry in the other machine which has clang 20 for the other problem. Cheers.

@devnexen

devnexen commented May 23, 2025

Copy link
Copy Markdown
Member Author

Here a taste of what I get

/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x5d6e): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x5d8b): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x5e57): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x5e74): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x5f87): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x5fa4): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x60e9): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:226:(.text+0x6106): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:228:(.text+0x616e): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:228:(.text+0x618b): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: ext/intl/breakiterator/codepointiterator_internal.o: in function `PHP::CodePointBreakIterator::refreshInputText(UText*, UErrorCode&)':
/home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:284:(.text+0x6687): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:284:(.text+0x66a1): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:285:(.text+0x66f6): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:285:(.text+0x6710): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:285:(.text+0x6774): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:285:(.text+0x678e): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:290:(.text+0x6857): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:290:(.text+0x6871): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:291:(.text+0x68c3): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.cpp:291:(.text+0x68dd): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: ext/intl/breakiterator/codepointiterator_internal.o: in function `PHP::CodePointBreakIterator::clearCurrentCharIter()':
/home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:96:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x76): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:96:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x90): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:96:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x11f): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:96:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x139): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:97:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x183): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:97:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x19d): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:98:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x1e6): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /home/dcarlier/Contribs/php-src/ext/intl/breakiterator/codepointiterator_internal.h:98:(.text._ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv[_ZN3PHP22CodePointBreakIterator20clearCurrentCharIterEv]+0x200): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: ext/intl/breakiterator/codepointiterator_internal.o: in function `std::type_info::operator!=(std::type_info const&) const':
/usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/typeinfo:114:(.text._ZNKSt9type_infoneERKS_[_ZNKSt9type_infoneERKS_]+0x7a): undefined reference to `__ubsan_vptr_type_cache'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/typeinfo:114:(.text._ZNKSt9type_infoneERKS_[_ZNKSt9type_infoneERKS_]+0x94): undefined reference to `__ubsan_handle_dynamic_type_cache_miss_abort'
/usr/bin/ld: ext/intl/breakiterator/codepointiterator_internal.o: in function `std::type_info::operator==(std::type_info const&) const':

this change fixes it. since we compile C++ with -fno-rtti -fno-exceptions and the sanitizer relies on type_info so ..

@iluuu1994

Copy link
Copy Markdown
Member

@devnexen I've experienced this issue in the past, and I believe linking with Clang++ fixes the issue, but I didn't know how to best achieve this in the build system.

@petk

petk commented May 23, 2025

Copy link
Copy Markdown
Member

did you try to build ?

Yes, I see. Link step fails the same as yours, yes. And adding the ,vptr fixes this.

@devnexen

Copy link
Copy Markdown
Member Author

@devnexen I've experienced this issue in the past, and I believe linking with Clang++ fixes the issue, but I didn't know how to best achieve this in the build system.

I won t mind just pushing just the ubsan change, the other part might be a bit "heavy" as forcing to use llvm c++ runtime but I may retest this a bit later.

@petk

petk commented Jun 20, 2025

Copy link
Copy Markdown
Member

Interesting here is that in my CMake build system this works ok:

  • C compiler: clang
  • C++ compiler: clang++
  • undefined sanitizer enabled
  • ext/intl enabled
  • branch: master

and there doesn't seem to be any such library (c++ or c++-abi) linked in explicitly. But I have passed some of those flags (-fsanitize=undefined -fno-sanitize-recover=undefined -fno-sanitize=object-size also to the linker)... This should be probably synced further a bit.

@petk

petk commented Jun 22, 2025

Copy link
Copy Markdown
Member

I see. Autootools always uses C compiler for linking the final SAPI and in CMake currently there is C++ compiler picked when such extension is enabled. Therefore the c++ library is automatically linked in there but not in Autotools. This sounds complex for Autotools to adjust it to use Clang++ for linking step and probably a simple c++ library explicitly linked in is the way to go, yes.

@petk

petk commented Jun 23, 2025

Copy link
Copy Markdown
Member

I'm just adding another note here. In GH-12349 there was --tag added to the libtool command when building objects and linking them together, and this --tag could be set to --tag=CXX when extension with CXX sources is enabled (this is already done for ext/intl but not yet for the SAPIs). It requires adding another make variable somewhere to set it based on the sources being compiled etc.

For example, replacing --tag=CC --mode=link $(CC) with --tag=CXX --mode=link $(CXX) for all SAPIs, works ok:

Makefile diff
22c22
< BUILD_CLI = $(LIBTOOL) --tag=CC --mode=link $(CC) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_BINARY_OBJS:.lo=.o) $(PHP_CLI_OBJS:.lo=.o) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_CLI_PATH)
---
> BUILD_CLI = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_BINARY_OBJS:.lo=.o) $(PHP_CLI_OBJS:.lo=.o) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_CLI_PATH)
27,28c27,28
< BUILD_PHPDBG = $(LIBTOOL) --tag=CC --mode=link $(CC) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_BINARY_OBJS:.lo=.o) $(PHP_PHPDBG_OBJS:.lo=.o) $(EXTRA_LIBS) $(PHPDBG_EXTRA_LIBS) $(ZEND_EXTRA_LIBS) $(PHP_FRAMEWORKS) -o $(SAPI_PHPDBG_PATH)
< BUILD_PHPDBG_SHARED = $(LIBTOOL) --tag=CC --mode=link $(CC) -shared -Wl,-soname,libphpdbg.so -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) $(EXTRA_LIBS) $(PHPDBG_EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_PHPDBG_SHARED_PATH)
---
> BUILD_PHPDBG = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_BINARY_OBJS:.lo=.o) $(PHP_PHPDBG_OBJS:.lo=.o) $(EXTRA_LIBS) $(PHPDBG_EXTRA_LIBS) $(ZEND_EXTRA_LIBS) $(PHP_FRAMEWORKS) -o $(SAPI_PHPDBG_PATH)
> BUILD_PHPDBG_SHARED = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -shared -Wl,-soname,libphpdbg.so -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) $(EXTRA_LIBS) $(PHPDBG_EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_PHPDBG_SHARED_PATH)
31c31
< BUILD_CGI = $(LIBTOOL) --tag=CC --mode=link $(CC) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_BINARY_OBJS:.lo=.o) $(PHP_FASTCGI_OBJS:.lo=.o) $(PHP_CGI_OBJS:.lo=.o) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_CGI_PATH)
---
> BUILD_CGI = $(LIBTOOL) --tag=CXX --mode=link $(CXX) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS:.lo=.o) $(PHP_BINARY_OBJS:.lo=.o) $(PHP_FASTCGI_OBJS:.lo=.o) $(PHP_CGI_OBJS:.lo=.o) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $(SAPI_CGI_PATH)
120,121c120,121
< 	$(LIBTOOL) --tag=CC --mode=link $(CC) $(LIBPHP_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
< 	-@$(LIBTOOL) --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
---
> 	$(LIBTOOL) --tag=CXX --mode=link $(CXX) $(LIBPHP_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -rpath $(phptempdir) $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
> 	-@$(LIBTOOL) --tag=CXX --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
124,125c124,125
< 	$(LIBTOOL) --tag=CC --mode=link $(CC) -dynamiclib $(LIBPHP_CFLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -rpath $(phptempdir) -install_name @rpath/$@ $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
< 	-@$(LIBTOOL) --silent --tag=CC --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1
---
> 	$(LIBTOOL) --tag=CXX --mode=link $(CXX) -dynamiclib $(LIBPHP_CFLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) -rpath $(phptempdir) -install_name @rpath/$@ $(EXTRA_LDFLAGS) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) -o $@
> 	-@$(LIBTOOL) --silent --tag=CXX --mode=install cp $@ $(phptempdir)/$@ >/dev/null 2>&1

@devnexen

Copy link
Copy Markdown
Member Author

Seems to me that would eliminate the change for adding c++ runtimes, so we would only need, eventually, the change for the sanitizer ?

@petk

petk commented Jun 23, 2025

Copy link
Copy Markdown
Member

Seems to me that would eliminate the change for adding c++ runtimes, so we would only need, eventually, the change for the sanitizer ?

I think this can be done in any case when some C++ objects are linked into the final binary (like this ext/intl being compiled). But I should check it out a bit further.

@Girgias

Girgias commented Apr 6, 2026

Copy link
Copy Markdown
Member

Is this still necessary?

@devnexen

devnexen commented Apr 6, 2026

Copy link
Copy Markdown
Member Author

yes we still need a way for the C++ part of the code base.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants