This is an archive of the discontinued LLVM Phabricator instance.

Fix PR20495: correct inference of the CUDA target for implicit members
ClosedPublic

Authored by eliben on Sep 4 2014, 4:24 PM.

Details

Reviewers
pcc
rsmith

Diff Detail

Event Timeline

eliben updated this revision to Diff 13293.Sep 4 2014, 4:24 PM
eliben retitled this revision from to Fix PR20495: correct inference of the CUDA target for implicit members.
eliben updated this object.
eliben edited the test plan for this revision. (Show Details)
eliben added a reviewer: pcc.
eliben added a subscriber: Unknown Object (MLST).
rsmith added a subscriber: rsmith.Sep 4 2014, 4:47 PM
rsmith added inline comments.
lib/Sema/SemaCUDA.cpp
120–121

Optional<CUDAFunctionTarget> InferredTarget;

129

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.)

138–142

These are not necessarily correct; the user might have explicitly defaulted a const/volatile/whatever special member function.

156–158

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?

eliben added inline comments.Sep 4 2014, 5:32 PM
lib/Sema/SemaCUDA.cpp
156–158

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?

rsmith added inline comments.Sep 4 2014, 5:55 PM
lib/Sema/SemaCUDA.cpp
138–142

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.

156–158

Yes, see Sema::NoteDeletedFunction.

lib/Sema/SemaOverload.cpp
5637

Thanks, that makes sense. This at least deserves an explanatory comment.

eliben updated this revision to Diff 13334.Sep 5 2014, 11:35 AM
eliben added a reviewer: rsmith.

Addresses Richard's review comments

Thanks for the review Richard. I believe I've addressed your comments. PTAL

lib/Sema/SemaCUDA.cpp
120–121

Done.

129

Done.

138–142

Renaming done.

156–158

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.

rsmith edited edge metadata.Sep 5 2014, 2:23 PM

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
131–141

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())
172

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/

eliben updated this revision to Diff 13473.Sep 9 2014, 8:39 AM
eliben edited edge metadata.

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

eliben added a comment.Sep 9 2014, 8:40 AM

Thanks for the review. PTAL

lib/Sema/SemaCUDA.cpp
131–141

Done

172

Done

lib/Sema/SemaDeclCXX.cpp
5568–5574

Done

lib/Sema/SemaOverload.cpp
5638

Done

Friendly ping

Friendly ping!

pcc added inline comments.Sep 19 2014, 2:33 PM
include/clang/Basic/Attr.td
545

This doesn't seem like it should have a spelling.

lib/Sema/SemaCUDA.cpp
101

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.

eliben updated this revision to Diff 13894.Sep 19 2014, 3:26 PM

Addressing Peter's comments

Thank you for the review, Peter. PTAL

include/clang/Basic/Attr.td
545

Done

lib/Sema/SemaCUDA.cpp
101

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

pcc added inline comments.Sep 24 2014, 6:26 PM
lib/Sema/SemaDeclCXX.cpp
1

I assume this was a mistake.

test/SemaCUDA/implicit-member-target.cu
147

This should derive from A7_with_copy_assign, right?

151

Please update this test once your other patch lands and add the other tests Richard asked for.

eliben updated this revision to Diff 14090.Sep 25 2014, 5:53 PM

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.

pcc accepted this revision.Sep 29 2014, 1:11 PM
pcc edited edge metadata.

LGTM with nit.

test/SemaCUDA/implicit-member-target-collision-cxx11.cu
19

Should be ) not viable}} here and elsewhere in this file.

This revision is now accepted and ready to land.Sep 29 2014, 1:11 PM
eliben closed this revision.Sep 29 2014, 1:49 PM

Committed (with nit addressed)

r218624.

Thanks for the review!