carlosgalvezp added inline comments.

================
Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-virtual-class-destructor.cpp:216-218
+template <typename T>
+struct TemplatedDerived : PublicVirtualBaseStruct {
+};
----------------
aaron.ballman wrote:
> whisperity wrote:
> > carlosgalvezp wrote:
> > > aaron.ballman wrote:
> > > > I think there are more interesting template test cases that should be 
> > > > checked.
> > > > ```
> > > > // What to do when the derived type is definitely polymorphic
> > > > // but the base class may or may not be?
> > > > template <typename Ty>
> > > > struct Derived : Ty {
> > > >   virtual void func();
> > > > };
> > > > 
> > > > struct S {};
> > > > struct  T { virtual ~T(); };
> > > > 
> > > > void instantiate() {
> > > >   Derived<S> d1; // Diagnose
> > > >   Derived<T> d2; // Don't diagnose
> > > > }
> > > > ```
> > > > 
> > > Very interesting example.
> > > 
> > > The problem is that the diagnostic is shown where `Derived` is, not where 
> > > the template is instantiated. How to go about that?
> > > 
> > > Seems like more testing and better diagnostics are needed to lower the 
> > > amount of false positives, I wonder if we should disable the test 
> > > meanwhile?
> > First, let's try to see if printing, to the user, the matched record, 
> > prints `Derived<S>` instead of just `Derived`, irrespective of the 
> > location. If the matcher matched the instantiation, the printing/formatting 
> > logic should **really** pick that up.
> > 
> > It would be very hard to get to the `VarDecl` with the specific type if 
> > your matcher logic starts the top-level matching from the type definitions 
> > (`cxxRecordDecl(...)`).
> > 
> > If we **really** want to put some sort of a diagnostic at the location at 
> > the places where the type is used, it could be done with another pass over 
> > the AST. However, that has an associated runtime cost, and also could 
> > create bazillions of `note: used here`-esque messages... But certainly 
> > doable. I believe this is `typeLoc`, but `typeLoc` is always a thing I 
> > never understand and every time I may end up using it it takes me a lot of 
> > reading to understand it for a short time to use it.
> > 
> > ----
> > 
> > If the previous step failed, you could still go around in a much more 
> > convoluted way:
> > 
> > However, there is something called a `ClassTemplateSpecializationDecl` (see 
> > the AST for @aaron.ballman's example here: http://godbolt.org/z/9qd7d1rs6), 
> > which surely should have an associated matcher.
> > 
> > ```
> > | |-ClassTemplateSpecializationDecl <line:1:1, line:4:1> line:2:8 struct 
> > Derived definition
> > | | |-DefinitionData polymorphic literal has_constexpr_non_copy_move_ctor 
> > can_const_default_init
> > | | | |-DefaultConstructor exists non_trivial constexpr 
> > defaulted_is_constexpr
> > | | | |-CopyConstructor simple non_trivial has_const_param 
> > implicit_has_const_param
> > | | | |-MoveConstructor exists simple non_trivial
> > | | | |-CopyAssignment simple non_trivial has_const_param 
> > implicit_has_const_param
> > | | | |-MoveAssignment exists simple non_trivial
> > | | | `-Destructor simple irrelevant trivial
> > | | |-public 'S':'S'
> > | | |-TemplateArgument type 'S'
> > | | | `-RecordType 'S'
> > | | |   `-CXXRecord 'S'
> > | | |-CXXRecordDecl prev 0x55ebcec4e600 <col:1, col:8> col:8 implicit 
> > struct Derived
> > ```
> > 
> > The location for the "template specialisation" is still the location of the 
> > primary template (as it is not an //explicit specialisation//), but at 
> > least somehow in the AST the information of //"Which type was this class 
> > template instantiated with?"// (`S`) is stored, so it is very likely that 
> > you can either match on this directly, or if you can't match that way, you 
> > could match all of these `ClassTemplateSpecializationDecl`s and check if 
> > their type parameter matches a `ProblematicClassOrStruct`.
> > 
> > Of course, this becomes extra nasty the moment we have multiple template 
> > parameters, or nested stuff, `template template`s (brrrr...).
> > 
> > This will still not give you the location of the variable definition, but 
> > at least you would have in your hand the template 
> > specialisation/instantiation instance properly.
> Oh, I may have caused some confusion with the comments in my example, sorry 
> for that! I was imagining the diagnostics would be emitted on the line with 
> the class declaration, but I commented on which instantiation I thought 
> should diagnose. Being more explicit with what I was thinking:
> ```
> // What to do when the derived type is definitely polymorphic
> // but the base class may or may not be?
> template <typename Ty>
> struct Derived : Ty { // Diagnostic emitted here
>   virtual void func();
> };
> 
> struct S {};
> struct  T { virtual ~T(); };
> 
> void instantiate() {
>   Derived<S> d1; // Instantiation causes a diagnostic above
>   Derived<T> d2; // Instantiation does not cause a diagnostic above
> }
> ```
No worries, that was my understanding as well :) I was more thinking about how 
to tag the expected error/no-error with `CHECK-MESSAGES`. I would need to say 
that the same line both should get an error and not get an error.

Maybe I will solve it with some duplication creating another class template.

Thanks for the comments, will update asap!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D110614/new/

https://reviews.llvm.org/D110614

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to