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

Daniel Jasper djasper at google.com
Mon Feb 6 02:04:38 PST 2012


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/20120206/5ab1c413/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clangpatch06022012
Type: application/octet-stream
Size: 14133 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120206/5ab1c413/attachment.obj>


More information about the cfe-commits mailing list