I think one note to speficify the forward declaretion location should be enough. Two notes might be too noisy.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Thanks! This looks promising.
In addition to updating existing tests, it would be good to add a test aimed explicitly at this. Maybe you can reduce something from the example in the bug report. Maybe looking at git blame for emitBadConversionNotes() will provide hints for where existing tests for such notes were added.
clang/lib/Sema/SemaInit.cpp | ||
---|---|---|
8710 | Can the reverse situation happen, where it's destType that's forward declared? | |
8713 | Is the getDeclKind() still necessary even though you're doing getPointeeCXXRecordDecl() above and fromDecl is os type CXXRecordDecl*? | |
8714 | I think we could add a new note instead of just note_forward_declaration which is more helpful, explaining that maybe the conversion would be valid if the type was defined and not just forward declared. |
clang/lib/Sema/SemaInit.cpp | ||
---|---|---|
8710 | If we only consider normal class without template, I think it's not necessary. class B{}; class A; B *b; A *a= b; Even if A is defined as class A: public B{};, A *a = b is still not valid, initializing pointer to derived class with pointer to base class. | |
8713 | Because I was thinking about excluding class template. getPointeeCXXRecordDecl() might return a ClassTemplateSpecializationDecl or ClassTemplatePartialSpecializationDecl. template<class C> class A{}; A<int> *a1; A<char> *a2 = a1; And the following code compiles: template<class C> class A{}; template<> class A<char>{}; template<> class A<int> : public A<char>{}; A<int> *a1; A<char> *a2 = a1; This seems like the same error as normal class, could resolved by inheritance. |
clang/lib/Sema/SemaInit.cpp | ||
---|---|---|
8710 | The reverse situation could happen in class template. template<class C> class A{}; template<class C> class B; // template<class C> class B : public A<C>{}; compiles B<int> *b; A<int> *a = b; |
Add new note and test case.
I think for the class template case, the new note might not be useful, since they might simply caused by mismatch of template arguments.
Looks great, thanks! I put a suggestion for different wording of the note, but I'll leave it up to you to decide.
clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp | ||
---|---|---|
5 | Thanks, this is a much better message! Instead of "forward declaration of class" it would be good to use the class name there, for example: "'B1' is not defined, but forward declared here; conversion would be valid if it's derived from 'A1'" Or something like that. Finding the right words is hard :) |
Please see llvm.org/PR52014 -- this patch is not properly handling cv-qualifiers. We should not produce the new note if the destination type has qualifiers that the source type does not possess, because in that case inheritance makes no difference to whether the conversion is valid.
Can the reverse situation happen, where it's destType that's forward declared?