Skip to content

Commit 9c120de

Browse files
DutChen18yuri91
authored andcommitted
Skip an address space check when initializing const reference
1 parent 855e692 commit 9c120de

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

clang/lib/Sema/SemaInit.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4935,13 +4935,42 @@ static void TryReferenceInitializationCore(Sema &S,
49354935
const Type *T1Ptr = T1.getTypePtr();
49364936
const Type *T2Ptr = T2.getTypePtr();
49374937

4938+
// CHEERP: Skip the address space check. This makes it so we can implicitly
4939+
// construct objects in one address space, by calling a constructor that
4940+
// takes an argument in an incompatible address space.
4941+
//
4942+
// For example:
4943+
//
4944+
// namespace client [[cheerp::genericjs]] {
4945+
// class [[cheerp::client_layout]] String {
4946+
// public:
4947+
// String();
4948+
// String(const char *str) : String() {}
4949+
// };
4950+
// }
4951+
//
4952+
// [[cheerp::genericjs]]
4953+
// void foo(const client::String &str);
4954+
//
4955+
// [[cheerp::genericjs]]
4956+
// int main() {
4957+
// // NOTE: "hello" is wasm_as when compiling with
4958+
// // "-target cheerp-wasm", even though main is a js function.
4959+
// foo("hello");
4960+
// }
4961+
//
4962+
// Skipping the check entirely may allow some invalid code, but we ignore
4963+
// this for now.
4964+
bool canInitializeAddressSpace = S.getLangOpts().Cheerp ||
4965+
T1Quals.isAddressSpaceSupersetOf(T2Quals, T1Ptr, T2Ptr);
4966+
49384967
// - Otherwise, the reference shall be an lvalue reference to a
49394968
// non-volatile const type (i.e., cv1 shall be const), or the reference
49404969
// shall be an rvalue reference.
49414970
// For address spaces, we interpret this to mean that an addr space
49424971
// of a reference "cv1 T1" is a superset of addr space of "cv2 T2".
49434972
if (isLValueRef && !(T1Quals.hasConst() && !T1Quals.hasVolatile() &&
4944-
T1Quals.isAddressSpaceSupersetOf(T2Quals, T1Ptr, T2Ptr))) {
4973+
canInitializeAddressSpace)) {
49454974
if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy)
49464975
Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
49474976
else if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
@@ -4950,7 +4979,7 @@ static void TryReferenceInitializationCore(Sema &S,
49504979
ConvOvlResult);
49514980
else if (!InitCategory.isLValue())
49524981
Sequence.SetFailed(
4953-
T1Quals.isAddressSpaceSupersetOf(T2Quals, T1Ptr, T2Ptr)
4982+
canInitializeAddressSpace
49544983
? InitializationSequence::
49554984
FK_NonConstLValueReferenceBindingToTemporary
49564985
: InitializationSequence::FK_ReferenceInitDropsQualifiers);

0 commit comments

Comments
 (0)