Diff Detail
Event Timeline
lib/Sema/SemaCUDA.cpp | ||
---|---|---|
110–111 | Optional<CUDAFunctionTarget> InferredTarget; | |
119 | For a non-abstract class, you should visit virtual bases as well as direct bases. (For an abstract class, you should skip direct and indirect virtual bases.) | |
128–132 | These are not necessarily correct; the user might have explicitly defaulted a const/volatile/whatever special member function. | |
146–148 | Declaring implicit special members is done lazily, so emitting diagnostics from here will result in erratic behavior. It would be better to defer the diagnostic until the special member is defined in C++98, and to mark the member as deleted in this case in C++11. | |
lib/Sema/SemaOverload.cpp | ||
5637 | Hmm, why do you need this change? |
lib/Sema/SemaCUDA.cpp | ||
---|---|---|
146–148 | If I just mark the member as deleted in C++11, is there away to still emit the descriptive diagnostic? Just deleting the member doesn't provide the user with any hint of what the underlying problem is. | |
lib/Sema/SemaOverload.cpp | ||
5637 | Consider what happens when the target inference method runs. It looks up the ctors of base classes, which gets to this point. Now, at this point we don't yet know what the caller's (the implicit method being defined) target is, so we can not reason whether there's a target mismatch. AFAIU this added test solves the problem, since we really cannot reject candidates based on target-ness when declaring an implicit member. The implicit member's target-ness will be determined by the inference method, and the collision test (the one with the Diag you commented on) should take care of mismatches. Does this make sense? |
lib/Sema/SemaCUDA.cpp | ||
---|---|---|
128–132 | Hmm, I see you're not actually doing this for any defaulted function, just for an implicit one. In that case, this looks fine, but please rename the function to talk about implicit special members not defaulted ones. | |
146–148 | Yes, see Sema::NoteDeletedFunction. | |
lib/Sema/SemaOverload.cpp | ||
5637 | Thanks, that makes sense. This at least deserves an explanatory comment. |
Thanks for the review Richard. I believe I've addressed your comments. PTAL
lib/Sema/SemaCUDA.cpp | ||
---|---|---|
110–111 | Done. | |
119 | Done. | |
128–132 | Renaming done. | |
146–148 | Thanks. I ended up implanting this into ShouldDeleteSpecialMember, with diagnostics; this is called from NoteDeletedFunction, and it also takes care of actually deleting the member in C++11 mode. Let me know if this makes sense. | |
lib/Sema/SemaOverload.cpp | ||
5637 | Comment added, let me know if you'd want to see more details in it. |
This should have more test coverage: at least cover each different kind of special member function, const/non-const arguments, explicitly-defaulted functions, and cases where a special member of a derived class is deleted because the base class's special member would call functions with a __host__ / __device__ mismatch.
lib/Sema/SemaCUDA.cpp | ||
---|---|---|
121–131 | For a non-abstract class, you'll collect direct vbases twice here (once from the bases list and once from the vbases list). The easiest thing to do would be to change the condition in the first loop to just if (!B.isVirtual()) | |
162 | This should be a note, rather than an error. | |
lib/Sema/SemaDeclCXX.cpp | ||
5568–5574 | This is SMI.ConstArg. | |
lib/Sema/SemaOverload.cpp | ||
5638 | s/we still don't know/we may not yet know/ |
Addresses Richard's comments.
I made the mismatch detection more robust - now instead of returning "host", when inference fails due to a conflict it returns an "invalid" target, which then causes all lookups to fail. This also provides a more natural place to rerun inference with Diagnose=true, when we try to diagnose why overload resolution failed.
I added more tests, but for now can't test copy/move assignment operators due to http://llvm.org/bugs/show_bug.cgi?id=20886
include/clang/Basic/Attr.td | ||
---|---|---|
545 ↗ | (On Diff #13473) | This doesn't seem like it should have a spelling. |
lib/Sema/SemaCUDA.cpp | ||
91 | Is there anything preventing a special member from being manually marked as global? (Apparently not; this parses without errors with a recent clang:) struct A { __attribute__((global)) A() {} }; | |
lib/Sema/SemaDeclCXX.cpp | ||
10438 | It looks like this is already set by the /*isImplicitlyDeclared=*/true parameter passed to CXXConstructorDecl::Create. | |
10611 | Likewise. |
Thank you for the review, Peter. PTAL
include/clang/Basic/Attr.td | ||
---|---|---|
545 ↗ | (On Diff #13473) | Done |
lib/Sema/SemaCUDA.cpp | ||
91 | Right. I think this should be detected earlier (when a method is constructed) with an appropriate error. I'll change the assertion to a runtime test for now - but am also adding a TODO to have a more descriptive error earlier. | |
lib/Sema/SemaDeclCXX.cpp | ||
10438 | This was cargo-culted from the creation of implicit default ctor and dtor. Fixed now - I've also fixed the source of the carto-culting :) Thanks for noticing this | |
10611 | Fixed |
PTAL
lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
1 | Yes, sorry. Fixing. | |
test/SemaCUDA/implicit-member-target.cu | ||
147 | Done | |
151 | Done. Note that in the case of the move constructor, the error message is not great. I presume this is because Sema tries to find the copy ctor after the move ctor doesn't match due to target; then since the move ctor is defined, the copy ctor is deleted - hence the message. |
Ping!
Since we're mostly discussing tests now, an LGTM will be appreciated. I can fix/add more tests later as needed. This change fixes completely broken functionality in the current frontend, which causes the frontend to fail compiling real code and even crash in some cases.
LGTM with nit.
test/SemaCUDA/implicit-member-target-collision-cxx11.cu | ||
---|---|---|
19 ↗ | (On Diff #14090) | Should be ) not viable}} here and elsewhere in this file. |
Is there anything preventing a special member from being manually marked as global? (Apparently not; this parses without errors with a recent clang:)