[cfe-commits] r95940 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Frontend/PCHBitCodes.h include/clang/Frontend/PCHReader.h lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/S

Douglas Gregor dgregor at apple.com
Fri Feb 12 10:22:17 PST 2010


On Feb 12, 2010, at 10:18 AM, Tanya M. Lattner wrote:

> 
> According to Doug this is ok behavior. The rational is that why did the user bother to define the function if the definition was never used? Seems ok to warn.

It was used. The problem---which I should have thought of earlier---is that the first declaration of f0() gets marked "used", but the -Wunused-function check looks at the definition and sees that it is not used.

The fix is probably to loop over the redeclaration chain for each static function to see if any of the redeclarations were marked "used".

	- Doug

> -Tanya
> 
> On Fri, 12 Feb 2010, Daniel Dunbar wrote:
> 
>> Hi Tanya,
>> 
>> This is giving a false positive on the following code, can you take a look?
>> 
>> --
>> ddunbar at lordcrumb:tmp$ cat t.c
>> static void f0(void);
>> void f1(void(*a0)(void));
>> void f2(void) { f1(f0); }
>> static void f0(void) {}
>> ddunbar at lordcrumb:tmp$ clang -Wunused-function -fsyntax-only t.c
>> t.c:4:13: warning: unused function 'f0' [-Wunused-function]
>> static void f0(void) {}
>>           ^
>> 1 diagnostic generated.
>> ddunbar at lordcrumb:tmp$
>> --
>> 
>> - Daniel
>> 
>> On Thu, Feb 11, 2010 at 4:07 PM, Tanya Lattner <tonic at nondot.org> wrote:
>>> Author: tbrethou
>>> Date: Thu Feb 11 18:07:30 2010
>>> New Revision: 95940
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=95940&view=rev
>>> Log:
>>> Implementing unused function warning.
>>> 
>>> Added:
>>>    cfe/trunk/test/Sema/warn-unused-function.c
>>> Modified:
>>>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>>    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
>>>    cfe/trunk/include/clang/Frontend/PCHReader.h
>>>    cfe/trunk/lib/Frontend/PCHReader.cpp
>>>    cfe/trunk/lib/Frontend/PCHWriter.cpp
>>>    cfe/trunk/lib/Sema/Sema.cpp
>>>    cfe/trunk/lib/Sema/Sema.h
>>>    cfe/trunk/lib/Sema/SemaDecl.cpp
>>>    cfe/trunk/lib/Sema/SemaExpr.cpp
>>> 
>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Feb 11 18:07:30 2010
>>> @@ -87,7 +87,9 @@
>>>   "declaration of %0 will not be visible outside of this function">;
>>>  def err_array_star_in_function_definition : Error<
>>>   "variable length array must be bound in function definition">;
>>> -
>>> +def warn_unused_function : Warning<"unused function %0">,
>>> +  InGroup<UnusedFunction>, DefaultIgnore;
>>> +
>>>  def warn_implicit_function_decl : Warning<
>>>   "implicit declaration of function %0">,
>>>   InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
>>> 
>>> Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
>>> +++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Thu Feb 11 18:07:30 2010
>>> @@ -221,7 +221,11 @@
>>> 
>>>       /// \brief Record code for the version control branch and revision
>>>       /// information of the compiler used to build this PCH file.
>>> -      VERSION_CONTROL_BRANCH_REVISION = 21
>>> +      VERSION_CONTROL_BRANCH_REVISION = 21,
>>> +
>>> +      /// \brief Record code for the array of unused static functions.
>>> +      UNUSED_STATIC_FUNCS = 22
>>> +
>>>     };
>>> 
>>>     /// \brief Record types used within a source manager block.
>>> 
>>> Modified: cfe/trunk/include/clang/Frontend/PCHReader.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHReader.h?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/include/clang/Frontend/PCHReader.h (original)
>>> +++ cfe/trunk/include/clang/Frontend/PCHReader.h Thu Feb 11 18:07:30 2010
>>> @@ -306,6 +306,10 @@
>>>   /// \brief The set of tentative definitions stored in the the PCH
>>>   /// file.
>>>   llvm::SmallVector<uint64_t, 16> TentativeDefinitions;
>>> +
>>> +  /// \brief The set of tentative definitions stored in the the PCH
>>> +  /// file.
>>> +  llvm::SmallVector<uint64_t, 16> UnusedStaticFuncs;
>>> 
>>>   /// \brief The set of locally-scoped external declarations stored in
>>>   /// the the PCH file.
>>> 
>>> Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
>>> +++ cfe/trunk/lib/Frontend/PCHReader.cpp Thu Feb 11 18:07:30 2010
>>> @@ -1332,6 +1332,14 @@
>>>       TentativeDefinitions.swap(Record);
>>>       break;
>>> 
>>> +    case pch::UNUSED_STATIC_FUNCS:
>>> +      if (!UnusedStaticFuncs.empty()) {
>>> +        Error("duplicate UNUSED_STATIC_FUNCS record in PCH file");
>>> +        return Failure;
>>> +      }
>>> +      UnusedStaticFuncs.swap(Record);
>>> +      break;
>>> +
>>>     case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
>>>       if (!LocallyScopedExternalDecls.empty()) {
>>>         Error("duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
>>> @@ -2479,6 +2487,13 @@
>>>     VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
>>>     SemaObj->TentativeDefinitions.push_back(Var);
>>>   }
>>> +
>>> +  // If there were any unused static functions, deserialize them and add to
>>> +  // Sema's list of unused static functions.
>>> +  for (unsigned I = 0, N = UnusedStaticFuncs.size(); I != N; ++I) {
>>> +    FunctionDecl *FD = cast<FunctionDecl>(GetDecl(UnusedStaticFuncs[I]));
>>> +    SemaObj->UnusedStaticFuncs.push_back(FD);
>>> +  }
>>> 
>>>   // If there were any locally-scoped external declarations,
>>>   // deserialize them and add them to Sema's table of locally-scoped
>>> 
>>> Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
>>> +++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Feb 11 18:07:30 2010
>>> @@ -545,6 +545,7 @@
>>>   RECORD(SPECIAL_TYPES);
>>>   RECORD(STATISTICS);
>>>   RECORD(TENTATIVE_DEFINITIONS);
>>> +  RECORD(UNUSED_STATIC_FUNCS);
>>>   RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS);
>>>   RECORD(SELECTOR_OFFSETS);
>>>   RECORD(METHOD_POOL);
>>> @@ -1982,6 +1983,11 @@
>>>     AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
>>>   }
>>> 
>>> +  // Build a record containing all of the static unused functions in this file.
>>> +  RecordData UnusedStaticFuncs;
>>> +  for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i)
>>> +    AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs);
>>> +
>>>   // Build a record containing all of the locally-scoped external
>>>   // declarations in this header file. Generally, this record will be
>>>   // empty.
>>> @@ -2083,6 +2089,10 @@
>>>   if (!TentativeDefinitions.empty())
>>>     Stream.EmitRecord(pch::TENTATIVE_DEFINITIONS, TentativeDefinitions);
>>> 
>>> +  // Write the record containing unused static functions.
>>> +  if (!UnusedStaticFuncs.empty())
>>> +    Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs);
>>> +
>>>   // Write the record containing locally-scoped external definitions.
>>>   if (!LocallyScopedExternalDecls.empty())
>>>     Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS,
>>> 
>>> Modified: cfe/trunk/lib/Sema/Sema.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/Sema.cpp (original)
>>> +++ cfe/trunk/lib/Sema/Sema.cpp Thu Feb 11 18:07:30 2010
>>> @@ -185,6 +185,12 @@
>>>  /// popped.
>>>  void Sema::ActOnEndOfTranslationUnit() {
>>> 
>>> +  // Remove functions that turned out to be used.
>>> +  UnusedStaticFuncs.erase(std::remove_if(UnusedStaticFuncs.begin(),
>>> +                                         UnusedStaticFuncs.end(),
>>> +                                         std::mem_fun(&FunctionDecl::isUsed)),
>>> +                          UnusedStaticFuncs.end());
>>> +
>>>   while (1) {
>>>     // C++: Perform implicit template instantiations.
>>>     //
>>> @@ -265,6 +271,15 @@
>>>       Consumer.CompleteTentativeDefinition(VD);
>>> 
>>>   }
>>> +
>>> +  // Output warning for unused functions.
>>> +  for (std::vector<FunctionDecl*>::iterator
>>> +       F = UnusedStaticFuncs.begin(),
>>> +       FEnd = UnusedStaticFuncs.end();
>>> +       F != FEnd;
>>> +       ++F)
>>> +    Diag((*F)->getLocation(), diag::warn_unused_function) << (*F)->getDeclName();
>>> +
>>>  }
>>> 
>>> 
>>> 
>>> Modified: cfe/trunk/lib/Sema/Sema.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/Sema.h (original)
>>> +++ cfe/trunk/lib/Sema/Sema.h Thu Feb 11 18:07:30 2010
>>> @@ -276,6 +276,9 @@
>>>   /// \brief All the tentative definitions encountered in the TU.
>>>   std::vector<VarDecl *> TentativeDefinitions;
>>> 
>>> +  /// \brief The set of static functions seen so far that have not been used.
>>> +  std::vector<FunctionDecl*> UnusedStaticFuncs;
>>> +
>>>   /// An enum describing the kind of diagnostics to use when checking
>>>   /// access.
>>>   enum AccessDiagnosticsKind {
>>> 
>>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Feb 11 18:07:30 2010
>>> @@ -3129,6 +3129,15 @@
>>>   if (FunctionTemplate)
>>>     return FunctionTemplate;
>>> 
>>> +
>>> +  // Keep track of static, non-inlined function definitions that
>>> +  // have not been used. We will warn later.
>>> +  // FIXME: Also include static functions declared but not defined.
>>> +  if (!NewFD->isInvalidDecl() && IsFunctionDefinition
>>> +      && !NewFD->isInlined() && NewFD->getLinkage() == InternalLinkage
>>> +      && !NewFD->isUsed())
>>> +    UnusedStaticFuncs.push_back(NewFD);
>>> +
>>>   return NewFD;
>>>  }
>>> 
>>> 
>>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=95940&r1=95939&r2=95940&view=diff
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 11 18:07:30 2010
>>> @@ -7293,6 +7293,7 @@
>>> 
>>>     // FIXME: keep track of references to static functions
>>>     Function->setUsed(true);
>>> +
>>>     return;
>>>   }
>>> 
>>> 
>>> Added: cfe/trunk/test/Sema/warn-unused-function.c
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-unused-function.c?rev=95940&view=auto
>>> 
>>> ==============================================================================
>>> --- cfe/trunk/test/Sema/warn-unused-function.c (added)
>>> +++ cfe/trunk/test/Sema/warn-unused-function.c Thu Feb 11 18:07:30 2010
>>> @@ -0,0 +1,16 @@
>>> +// RUN: %clang_cc1 -fsyntax-only -Wunused-function -verify %s
>>> +
>>> +void foo() {}
>>> +static void f2() {}
>>> +static void f1() {f2();} // expected-warning{{unused}}
>>> +
>>> +static int f0() { return 17; } // expected-warning{{unused}}
>>> +int x = sizeof(f0());
>>> +
>>> +static void f3();
>>> +extern void f3() { } // expected-warning{{unused}}
>>> +
>>> +// FIXME: This will trigger a warning when it should not.
>>> +// Update once PR6281 is fixed.
>>> +//inline static void f4();
>>> +//void f4() { }
>>> \ No newline at end of file
>>> 
>>> 
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>> 
>> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits





More information about the cfe-commits mailing list