rjmccall added inline comments.
================ Comment at: lib/Sema/SemaInit.cpp:4539 + if (InitCategory.isPRValue() || InitCategory.isXValue()) + T1Quals.removeAddressSpace(); + ---------------- ebevhan wrote: > rjmccall wrote: > > rjmccall wrote: > > > I can understand why a pr-value wouldn't have an address space, but an > > > x-value's address space is surely important. > > No, wait, I think this is more deeply wrong. We're initializing a > > reference to type `cv1 T1`, and if we're initializing it with a temporary, > > we're dropping the address space from `cv1`? That's definitely wrong. > > > > If we're starting with a pr-value, reference-initialization normally has to > > start by initializing a temporary. (The exception is it's a class type > > with a conversion operator to a reference type; C++ is abysmally > > complicated. Let's ignore this for a moment.) Temporaries are always in > > the default address space (the address space of local variables) because > > the language (neither OpenCL nor Embedded C) does not give us any facility > > for allocating temporary memory anywhere else. So reference-initialization > > from a pr-value creates a temporary in the default address space and then > > attempts to initialize the destination reference type with that temporary. > > That initialization should fail if there's no conversion from the default > > address space to the destination address space. For example, consider > > initializing a `const int __global &` from a pr-value: this should clearly > > not succeed, because we have no way of putting a temporary in the global > > address space. That reference can only be initialized with a gl-value > > that's already in the `__global` address space. > > > > On the other hand, we can successfully initialize a `const int &` with a > > gl-value of type `const int __global` not by direct reference > > initialization but by loading from the operand and then materializing the > > result into a new temporary. > > > > I think what this means is: > > > > - We need to be doing this checking as if pr-values were in `__private`. > > This includes both (1) expressions that were originally pr-values and (2) > > expressions that have been converted to pr-values due to a failure to > > perform direct reference initialization. > > > > - We need to make sure that reference compatibility correctly prevents > > references from being bound to gl-values in incompatible address spaces. > > On the other hand, we can successfully initialize a `const int &` with a > > gl-value of type `const int __global` not by direct reference > > initialization but by loading from the operand and then materializing the > > result into a new temporary. > > Is this the right thing to do? It means that initializing such a reference > would incur a cost under the hood that might be unnoticed/unwanted by the > user. Hmm. I was going to say that it's consistent with the normal behavior of C++, but looking at the actual rule, it's more complicated than that: C++ will only do this if the types are not reference-related or if the gl-value is a bit-field. So this would only be allowed if the reference type was e.g. `const long &`. It's a strange rule, but it's straightforward to stay consistent with it. I think we will eventually find ourselves needing a special-case rule for copy-initializing and copy-assigning trivially-copyable types, but we're not there yet. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D56066/new/ https://reviews.llvm.org/D56066 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits