[cfe-commits] Clang change to detect and warn about unused private members

Daniel Jasper djasper at google.com
Fri Mar 16 01:50:56 PDT 2012


Did/will anyone have time to take a look at this?

On Mon, Feb 6, 2012 at 11:04 AM, Daniel Jasper <djasper at google.com> wrote:

> Comments inline, new version attached.
>
> On Wed, Feb 1, 2012 at 10:52 AM, Chandler Carruth <chandlerc at google.com>wrote:
>
>> Thanks, comments inline... This is sadly a pretty cursory read, sorry,
>> working on other stuff. I think, especially given the "used" concept at
>> play here, Richard or Eli looking at this would be very good. =] Thanks
>> again for working on it.
>>
>> --- a/include/clang/Basic/DiagnosticSemaKinds.td
>> +++ b/include/clang/Basic/DiagnosticSemaKinds.td
>> @@ -134,6 +134,9 @@  def warn_unneeded_member_function : Warning<
>>    "member function %0 is not needed and will not be emitted">,
>>    InGroup<UnneededMemberFunction>, DefaultIgnore;
>>
>> +def warn_unused_private_field: Warning<"private field %0 is not used">,
>> +  InGroup<UnusedPrivateField>, DefaultIgnore;
>> +
>>
>> I wouldn't separate this in its own group w/ vertical whitespace, but
>> rather jam it in with the other unused warning messages.
>>
>
> Done.
>
>
>> --- a/lib/Sema/SemaDeclCXX.cpp
>> +++ b/lib/Sema/SemaDeclCXX.cpp
>> @@ -1617,8 +1617,25 @@  Sema::ActOnCXXMemberDeclarator(Scope *S,
>> AccessSpecifier AS, Declarator &D,
>>
>>    assert((Name || isInstField) && "No identifier for non-field ?");
>>
>> -  if (isInstField)
>> -    FieldCollector->Add(cast<FieldDecl>(Member));
>> +  if (isInstField) {
>> +    FieldDecl *FD = cast<FieldDecl>(Member);
>> +    FieldCollector->Add(FD);
>> +    if (FD->getAccess() == AS_private) {
>> +      bool hasNoSideEffects = true;
>> +      if (!FD->getType().isNull()) {
>> +        if (const CXXRecordDecl *RD =
>> +            FD->getType().getTypePtrOrNull()->getAsCXXRecordDecl()) {
>>
>> You shouldn't need getTypePtrOrNull() here. QualType provides an ->
>> overload that delegates to Type.
>>
>
> Done.
>
>
>>
>> +      if
>> (!FD->getParent()->getTypeForDecl()->isInstantiationDependentType() &&
>> +          hasNoSideEffects)
>>
>> I'm a bit surprised at checking InstantiationDependentType here... Not
>> just Dependent... Also some comments as to what this is supposed to handle
>> would be good...
>>
>
> Done.
>
>
>> @@ -2063,6 +2080,15 @@  Sema::BuildMemberInitializer(ValueDecl *Member,
>>    assert((DirectMember || IndirectMember) &&
>>           "Member must be a FieldDecl or IndirectFieldDecl");
>>
>> +  // FIXME: Allow more initializers not to count as usage, e.g. where all
>> +  // arguments are primitive types.
>> +  ValueDecl *VD = dyn_cast<ValueDecl>(Member);
>>
>> If you know the cast will always succeed, just use "cast" rather than
>> "dyn_cast".
>>
>
> Done.
>
>
>> +  if (!VD->getType()->isBuiltinType() &&
>> +      !VD->getType()->isAnyPointerType() &&
>>
>> Why are these here? We already have constraints on the type of things
>> above when we check the Field Decl? Maybe I just don't understand what
>> these are doing.
>>
>
> I added a comment. Basically, this currently marks fields of a
> non-primitive type as used, if a non-trivial constructor is called by an
> initializer.
>
> --- a/lib/Sema/SemaTemplateInstantiate.cpp
>> +++ b/lib/Sema/SemaTemplateInstantiate.cpp
>> @@ -1791,6 +1791,19 @@  Sema::InstantiateClass(SourceLocation
>> PointOfInstantiation,
>>          if (OldField->getInClassInitializer())
>>            FieldsWithMemberInitializers.push_back(std::make_pair(OldField,
>>                                                                  Field));
>> +        if (Field->getAccess() == AS_private) {
>> +          bool hasNoSideEffects = true;
>> +          if (!Field->getType().isNull()) {
>> +            if (const CXXRecordDecl *RD =
>> +
>>  Field->getType().getTypePtrOrNull()->getAsCXXRecordDecl()) {
>> +              hasNoSideEffects = RD->isCompleteDefinition() &&
>> +                                 RD->hasTrivialDefaultConstructor() &&
>> +                                 RD->hasTrivialDestructor();
>> +            }
>> +          }
>> +          if (hasNoSideEffects)
>> +            UnusedPrivateFields.insert(Field);
>> +        }
>>
>> This is the second copy of this pattern. We should either have template
>> instantiation call the not-template Sema routines to do this, or we should
>> factor the predicate into a helper somewhere, likely FieldDecl.
>>
>
> Done. I implemented a method hasSideEffects that computes whether the
> declaration of the field has side effects. It currently only recognizes the
> trivial default constructor and the trivial destructor as side-effect-free.
> This can be extended in the future. Should the method be moved to
> DeclaratorDecl or ValueDecl (it doesn't use anything FieldDecl-specific)?
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120316/84078084/attachment.html>


More information about the cfe-commits mailing list