This is an archive of the discontinued LLVM Phabricator instance.

[libc++] cuchar redeclares ::mbstate_t when it's in its own clang module
ClosedPublic

Authored by iana on Apr 17 2023, 9:39 AM.

Details

Summary

When cuchar is compiled independently on platforms that don't have <uchar.h>, it doesn't get a declaration of mbstate_t, and so makes an empty declaration for ::mbstate_t. That conflicts with the declarations in __mbstate_t.h and cwchar since both of those headers do get mbstate_t before making ::mbstate_t.

Change __mbstate_t.h to just get the underlying declaration for mbstate_t and not make a declaration for ::mbstate_t. Include __mbstate_t.h in uchar.h and wchar.h when their next headers aren't available so that at least mbstate_t gets defined.

Add __std_mbstate_t.h to declare ::mbstate_t for headers that need that when cuchar or cwchar aren't available (because either _LIBCPP_HAS_NO_WIDE_CHARACTERS or _LIBCPP_CXX03_LANG).

Diff Detail

Event Timeline

iana created this revision.Apr 17 2023, 9:39 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 17 2023, 9:39 AM
Herald added a subscriber: ributzka. · View Herald Transcript
iana requested review of this revision.Apr 17 2023, 9:39 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 17 2023, 9:39 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik requested changes to this revision.Apr 17 2023, 10:18 AM
philnik added a subscriber: philnik.

Why do we want to change this? The current version looks just fine.

This revision now requires changes to proceed.Apr 17 2023, 10:18 AM
iana added a comment.Apr 17 2023, 10:36 AM

Why do we want to change this? The current version looks just fine.

The redeclaration becomes an error with clang modules when __mbstate.h and cuchar are in different modules.

iana requested review of this revision.Apr 17 2023, 10:36 AM
Mordante accepted this revision as: Mordante.Apr 18 2023, 10:58 AM

LGTM modulo one comment. I leave the final approval to @philnik.

libcxx/include/cuchar
53 ↗(On Diff #514279)

Can you update this comment why this is needed, this is useful for future readers of the code.

philnik accepted this revision.Apr 18 2023, 2:53 PM

Why do we want to change this? The current version looks just fine.

The redeclaration becomes an error with clang modules when __mbstate.h and cuchar are in different modules.

Please add that information to the commit message.

LGTM with comments addressed.

libcxx/include/cuchar
52 ↗(On Diff #514279)

I don't think this check makes sense. It seems like right now we might have this symbol in C++03 in some headers, but not in cuchar. If we only want this in C++11 we should guard it in __mbstate_t.h.

This revision is now accepted and ready to land.Apr 18 2023, 2:53 PM
iana added a comment.Apr 18 2023, 5:10 PM

Why do we want to change this? The current version looks just fine.

The redeclaration becomes an error with clang modules when __mbstate_t.h and cuchar are in different modules.

I dug into it a little more. When <cuchar> is compiled all by itself on Apple platforms, mbstate_t isn't defined because Apple doesn't have a <uchar.h>, and <stddef.h> doesn't declare mbstate_t either. But when <__mbstate_t.h> (and <cwchar>) are compiled, they both get the OS declaration of mbstate_t and their using declaration gets a type. I think it works out with the current std mega module because declarations leak between the submodules, but when those three headers are in different top level modules, that's when things get mad at <cuchar>.

So it looks like it's fine to leave the using ::mbstate_t _LIBCPP_USING_IF_EXISTS; line in <cuchar>, but we need to include something to get mbstate_t defined. Do we want to unconditionally include __mbstate_t.h? That will have the side effect of often including <wchar.h>, and also declaring ::mbstate_t which maybe we don't want. We could leave that include conditional on _LIBCPP_CXX03_LANG? Or we could instead include <bits/types/mbstate_t.h> or <sys/_types/_mbstate_t.h> to get just the C declaration?

iana requested review of this revision.Apr 18 2023, 5:11 PM
iana updated this revision to Diff 515086.Apr 19 2023, 2:06 PM

Redo the fix to make the libc++ uchar.h try harder to find mbstate_t.

iana retitled this revision from [libc++] cuchar redeclares ::mbstate_t to [libc++] cuchar redeclares ::mbstate_t when it's in its own clang module.Apr 19 2023, 2:06 PM
iana edited the summary of this revision. (Show Details)
iana added a comment.Apr 20 2023, 10:17 AM

The sanitizer and aix test failures don't look related to this change, I get the same ones in an unrelated review too.

libcxx/include/uchar.h
51

This should maybe be

# define __need_size_t
# include_next <stddef.h>

Or maybe that's a bit too stringent.

ldionne added inline comments.Apr 25 2023, 12:11 PM
libcxx/include/uchar.h
51

Shouldn't we include __mbstate_t.h instead? Then we can tweak what that header does as needed to avoid including wchar.h from it unconditionally, perhaps?

iana added inline comments.Apr 25 2023, 12:23 PM
libcxx/include/uchar.h
51

The problem with including __mbstate_t.h here is it adds ::mbstate_t which I don't think we want in the C header. I was originally doing that in cuchar, but then that was kind of weird because it would declare ::mbstate_t all the time when the rest of the file is gated on _LIBCPP_CXX03_LANG. People thought it was weird to conditionally include __mbstate_t.h in cuchar too. Also __mbstate_t.h starts off trying to include all of wchar.h which seems counter to the comment at its top?

iana updated this revision to Diff 516959.Apr 25 2023, 3:39 PM

Edits with feedback from @ldionne

ldionne accepted this revision.Apr 26 2023, 3:12 PM

So hard for such a small patch! Thanks for working through this with me!

libcxx/include/__mbstate_t.h
18–25
34–38
libcxx/include/wchar.h
126
This revision is now accepted and ready to land.Apr 26 2023, 3:12 PM
iana updated this revision to Diff 517674.Apr 27 2023, 12:13 PM
iana marked 4 inline comments as done.

Review changes, fix failed test.

ldionne accepted this revision.Apr 27 2023, 12:58 PM
iana edited the summary of this revision. (Show Details)Apr 27 2023, 12:59 PM
iana edited the summary of this revision. (Show Details)
iana updated this revision to Diff 517753.EditedApr 27 2023, 4:52 PM

__locale uses mbstate_t without including __mbstate_t.h

iana updated this revision to Diff 518085.Apr 28 2023, 4:17 PM

std::mbstate_t is still needed even when uchar/wchar aren't available. Make a __std_mbstate_t.h header for that.

iana edited the summary of this revision. (Show Details)Apr 28 2023, 4:17 PM
iana updated this revision to Diff 518133.Apr 28 2023, 11:34 PM

Revert ignore_format.txt

ldionne accepted this revision.May 1 2023, 8:56 AM

This LGTM to merge, the CI failures are unrelated, I just checked.

This revision was landed with ongoing or failed builds.May 1 2023, 11:48 AM
This revision was automatically updated to reflect the committed changes.

I confirmed that a local revert fixed the issue for me