[cfe-commits] r119583 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/LangOptions.h include/clang/Driver/CC1Options.td include/clang/Driver/Options.td include/clang/Sema/Sema.h lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp lib/Sema/SemaDecl.cpp test/SemaCXX/warn-argument-larger-than.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed Nov 17 15:11:54 PST 2010


Author: akirtzidis
Date: Wed Nov 17 17:11:54 2010
New Revision: 119583

URL: http://llvm.org/viewvc/llvm-project?rev=119583&view=rev
Log:
Introduce option -Wargument-larger-than[=N] which warns about function definitions if they take by-value
or return by-value any POD that is larger than some threshold (default is 64 bytes).

Implements rdar://8548050.

Added:
    cfe/trunk/test/SemaCXX/warn-argument-larger-than.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Basic/LangOptions.h
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Wed Nov 17 17:11:54 2010
@@ -158,6 +158,7 @@
 def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
 def : DiagGroup<"write-strings">;
 def CharSubscript : DiagGroup<"char-subscripts">;
+def ArgumentSizeLargerThan : DiagGroup<"argument-larger-than">;
 
 // Aggregation warning settings.
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Nov 17 17:11:54 2010
@@ -113,6 +113,11 @@
 def warn_used_but_marked_unused: Warning<"%0 was marked unused but was used">,
   InGroup<UsedButMarkedUnused>, DefaultIgnore;
 
+def warn_parameter_size: Warning<"size of %0 is %1 bytes">,
+  InGroup<ArgumentSizeLargerThan>;
+def warn_return_value_size: Warning<"return value of %0 is %1 bytes">,
+  InGroup<ArgumentSizeLargerThan>;
+
 def warn_implicit_function_decl : Warning<
   "implicit declaration of function %0">,
   InGroup<ImplicitFunctionDeclare>, DefaultIgnore;

Modified: cfe/trunk/include/clang/Basic/LangOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/LangOptions.h (original)
+++ cfe/trunk/include/clang/Basic/LangOptions.h Wed Nov 17 17:11:54 2010
@@ -122,6 +122,8 @@
 
 public:
   unsigned InstantiationDepth;    // Maximum template instantiation depth.
+  unsigned ArgumentLargerThan;    // Warn if parameter/return value is larger
+                                  // in bytes than this setting. 0 is no check.
 
   // Version of Microsoft Visual C/C++ we are pretending to be. This is
   // temporary until we support all MS extensions used in Windows SDK and stdlib
@@ -175,6 +177,8 @@
 
     InstantiationDepth = 1024;
 
+    ArgumentLargerThan = 0;
+
     Optimize = 0;
     OptimizeSize = 0;
 

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Nov 17 17:11:54 2010
@@ -500,6 +500,11 @@
   HelpText<"Give inline C++ member functions default visibility by default">;
 def ftemplate_depth : Separate<"-ftemplate-depth">,
   HelpText<"Maximum depth of recursive template instantiation">;
+def Wargument_larger_than : Separate<"-Wargument-larger-than">,
+  HelpText<"Warn if a function definition returns or accepts an object larger "
+           "in bytes that a given value">;
+def Wargument_larger_than_EQ : Joined<"-Wargument-larger-than=">,
+  Alias<Wargument_larger_than>;
 def trigraphs : Flag<"-trigraphs">,
   HelpText<"Process trigraph sequences">;
 def fwritable_strings : Flag<"-fwritable-strings">,

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Wed Nov 17 17:11:54 2010
@@ -401,6 +401,8 @@
 def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
 def ftemplate_backtrace_limit_EQ : Joined<"-ftemplate-backtrace-limit=">,
                                    Group<f_Group>;
+def Wargument_larger_than_def : Flag<"-Wargument-larger-than">;
+def Wargument_larger_than_EQ : Joined<"-Wargument-larger-than=">;
 def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
 def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
 def ftime_report : Flag<"-ftime-report">, Group<f_Group>;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Nov 17 17:11:54 2010
@@ -760,6 +760,13 @@
   void DiagnoseUnusedParameters(ParmVarDecl * const *Begin,
                                 ParmVarDecl * const *End);
 
+  /// \brief Diagnose size of parameters and return value of a Function
+  /// or ObjCMethod.
+  void DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin,
+                                              ParmVarDecl * const *End,
+                                              QualType ReturnTy,
+                                              NamedDecl *D);
+
   void DiagnoseInvalidJumps(Stmt *Body);
   Decl *ActOnFileScopeAsmDecl(SourceLocation Loc, Expr *expr);
 

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Nov 17 17:11:54 2010
@@ -1199,6 +1199,15 @@
     CmdArgs.push_back(A->getValue(Args));
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_Wargument_larger_than_EQ,
+                               options::OPT_Wargument_larger_than_def)) {
+    CmdArgs.push_back("-Wargument-larger-than");
+    if (A->getNumValues())
+      CmdArgs.push_back(A->getValue(Args));
+    else
+      CmdArgs.push_back("64"); // default value for -Wargument-larger-than
+  }
+
   if (Args.hasArg(options::OPT__relocatable_pch))
     CmdArgs.push_back("-relocatable-pch");
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Nov 17 17:11:54 2010
@@ -1373,6 +1373,8 @@
   Opts.MathErrno = Args.hasArg(OPT_fmath_errno);
   Opts.InstantiationDepth = Args.getLastArgIntValue(OPT_ftemplate_depth, 1024,
                                                Diags);
+  Opts.ArgumentLargerThan = Args.getLastArgIntValue(OPT_Wargument_larger_than,
+                                                    0, Diags);
   Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
   Opts.ObjCConstantStringClass =
     Args.getLastArgValue(OPT_fconstant_string_class);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=119583&r1=119582&r2=119583&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Nov 17 17:11:54 2010
@@ -26,6 +26,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/AST/CharUnits.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Parse/ParseDiagnostic.h"
@@ -4864,6 +4865,36 @@
   }
 }
 
+void Sema::DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Param,
+                                                  ParmVarDecl * const *ParamEnd,
+                                                  QualType ReturnTy,
+                                                  NamedDecl *D) {
+  if (LangOpts.ArgumentLargerThan == 0) // No check.
+    return;
+
+  if (ReturnTy->isPODType() &&
+      Diags.getDiagnosticLevel(diag::warn_return_value_size) !=
+          Diagnostic::Ignored) {
+    unsigned Size = Context.getTypeSizeInChars(ReturnTy).getQuantity();
+    if (Size > LangOpts.ArgumentLargerThan)
+      Diag(D->getLocation(), diag::warn_return_value_size)
+          << D->getDeclName() << Size;
+  }
+
+  if (Diags.getDiagnosticLevel(diag::warn_parameter_size)==Diagnostic::Ignored)
+    return;
+
+  for (; Param != ParamEnd; ++Param) {
+    QualType T = (*Param)->getType();
+    if (!T->isPODType())
+      continue;
+    unsigned Size = Context.getTypeSizeInChars(T).getQuantity();
+    if (Size > LangOpts.ArgumentLargerThan)
+      Diag((*Param)->getLocation(), diag::warn_parameter_size)
+          << (*Param)->getDeclName() << Size;
+  }
+}
+
 ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
                                   TypeSourceInfo *TSInfo, QualType T,
                                   IdentifierInfo *Name,
@@ -5162,6 +5193,8 @@
 
     if (!FD->isInvalidDecl()) {
       DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
+      DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(),
+                                             FD->getResultType(), FD);
       
       // If this is a constructor, we need a vtable.
       if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
@@ -5175,8 +5208,11 @@
     assert(MD == getCurMethodDecl() && "Method parsing confused");
     MD->setBody(Body);
     MD->setEndLoc(Body->getLocEnd());
-    if (!MD->isInvalidDecl())
+    if (!MD->isInvalidDecl()) {
       DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
+      DiagnoseSizeOfParametersAndReturnValue(MD->param_begin(), MD->param_end(),
+                                             MD->getResultType(), MD);
+    }
   } else {
     return 0;
   }

Added: cfe/trunk/test/SemaCXX/warn-argument-larger-than.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-argument-larger-than.cpp?rev=119583&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-argument-larger-than.cpp (added)
+++ cfe/trunk/test/SemaCXX/warn-argument-larger-than.cpp Wed Nov 17 17:11:54 2010
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wargument-larger-than=100 %s
+
+// rdar://8548050
+namespace rdar8548050 {
+
+struct S100 {
+    char x[100];
+};
+
+struct S101 {
+    char x[101];
+};
+
+S100 f100(S100 s) { return s; }
+
+S101 f101(S101 s) { return s; } // expected-warning {{return value of 'f101' is 101 bytes}} \
+                                // expected-warning {{size of 's' is 101 bytes}}
+
+typedef int Arr[200];
+void farr(Arr a) { }
+
+struct NonPOD {
+  char x[200];
+  virtual void m();
+};
+
+NonPOD fNonPOD(NonPOD s) { return s; }
+
+template <unsigned size>
+struct TS {
+    char x[size];
+};
+
+template <unsigned size>
+void tf(TS<size> ts) {} // expected-warning {{size of 'ts' is 300 bytes}}
+
+void g() {
+    TS<300> ts;
+    tf<300>(ts); // expected-note {{instantiation}}
+}
+
+}





More information about the cfe-commits mailing list