diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Driver/Tools.cpp | 9 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 38 |
3 files changed, 48 insertions, 1 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index aa1b439916..d9e3760a8d 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1199,6 +1199,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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"); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index b20520bbee..466dfbd9af 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1373,6 +1373,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, 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); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c246cad098..dc017d2ba5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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::DiagnoseUnusedParameters(ParmVarDecl * const *Param, } } +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 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, 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 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, 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; } |