[cfe-commits] r142157 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaChecking.cpp lib/Sema/SemaType.cpp test/Sema/static-array.c
Douglas Gregor
dgregor at apple.com
Mon Oct 17 09:02:41 PDT 2011
On Oct 16, 2011, at 2:17 PM, Peter Collingbourne wrote:
> Author: pcc
> Date: Sun Oct 16 16:17:32 2011
> New Revision: 142157
>
> URL: http://llvm.org/viewvc/llvm-project?rev=142157&view=rev
> Log:
> Add sema checks for calls to functions taking static array parameters
>
> Added:
> cfe/trunk/test/Sema/static-array.c
> Modified:
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/Sema/SemaChecking.cpp
> cfe/trunk/lib/Sema/SemaType.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=142157&r1=142156&r2=142157&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Oct 16 16:17:32 2011
> @@ -2716,6 +2716,9 @@
> "zero size arrays are an extension">;
> def err_typecheck_zero_array_size : Error<
> "zero-length arrays are not permitted in C++">;
> +def warn_typecheck_zero_static_array_size : Warning<
> + "'static' has no effect on zero-length arrays">,
> + InGroup<DiagGroup<"array-bounds">>;
> def err_at_least_one_initializer_needed_to_size_array : Error<
> "at least one initializer value required to size array">;
> def err_array_size_non_int : Error<"size of array has non-integer type %0">;
> @@ -4509,6 +4512,11 @@
> def warn_null_arg : Warning<
> "null passed to a callee which requires a non-null argument">,
> InGroup<NonNull>;
> +def warn_static_array_too_small : Warning<
> + "array argument is too small; contains %0 elements, callee requires at least %1">,
> + InGroup<DiagGroup<"array-bounds">>;
> +def note_callee_static_array : Note<
> + "callee declares array parameter as static here">;
> def warn_empty_format_string : Warning<
> "format string is empty">, InGroup<FormatZeroLength>;
> def warn_format_string_is_wide_literal : Warning<
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=142157&r1=142156&r2=142157&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Sun Oct 16 16:17:32 2011
> @@ -6103,6 +6103,10 @@
> const Expr * const *ExprArgs,
> SourceLocation CallSiteLoc);
>
> + void CheckStaticArrayArguments(const FunctionDecl *FDecl,
> + const Expr * const *ExprArgs,
> + SourceLocation CallSiteLoc);
> +
> void CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg,
> unsigned format_idx, unsigned firstDataArg,
> bool isPrintf);
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=142157&r1=142156&r2=142157&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Sun Oct 16 16:17:32 2011
> @@ -360,6 +360,9 @@
> TheCall->getCallee()->getLocStart());
> }
>
> + CheckStaticArrayArguments(FDecl, TheCall->getArgs(),
> + TheCall->getCallee()->getLocStart());
> +
> // Builtin handling
> int CMF = -1;
> switch (FDecl->getBuiltinID()) {
> @@ -1362,6 +1365,64 @@
> }
> }
>
> +static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) {
> + TypeLoc TL = PVD->getTypeSourceInfo()->getTypeLoc();
> + if (ArrayTypeLoc *ATL = dyn_cast<ArrayTypeLoc>(&TL))
> + S.Diag(PVD->getLocation(), diag::note_callee_static_array)
> + << ATL->getLocalSourceRange();
> +}
> +
> +/// CheckStaticArrayArguments - Check that each argument corresponding to a
> +/// static array parameter is non-null, and that if it is formed by
> +/// array-to-pointer decay, the underlying array is sufficiently large.
> +///
> +/// C99 6.7.5.3p7: If the keyword static also appears within the [ and ] of the
> +/// array type derivation, then for each call to the function, the value of the
> +/// corresponding actual argument shall provide access to the first element of
> +/// an array with at least as many elements as specified by the size expression.
> +void
> +Sema::CheckStaticArrayArguments(const FunctionDecl *FDecl,
> + const Expr * const *ExprArgs,
> + SourceLocation CallSiteLoc) {
> + // Static array parameters are not supported in C++.
> + if (getLangOptions().CPlusPlus)
> + return;
> +
> + for (FunctionDecl::param_const_iterator i = FDecl->param_begin(),
> + e = FDecl->param_end(); i != e; ++i, ++ExprArgs) {
> + const Expr *ArgExpr = *ExprArgs;
> + QualType OrigTy = (*i)->getOriginalType();
> +
> + const ArrayType *AT = Context.getAsArrayType(OrigTy);
> + if (!AT || AT->getSizeModifier() != ArrayType::Static)
> + continue;
> +
> + if (ArgExpr->isNullPointerConstant(Context,
> + Expr::NPC_NeverValueDependent)) {
> + Diag(CallSiteLoc, diag::warn_null_arg) << ArgExpr->getSourceRange();
> + DiagnoseCalleeStaticArrayParam(*this, *i);
> + continue;
> + }
> +
> + const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT);
> + if (!CAT)
> + continue;
> +
> + const ConstantArrayType *ArgCAT =
> + Context.getAsConstantArrayType(ArgExpr->IgnoreParenImpCasts()->getType());
> + if (!ArgCAT)
> + continue;
> +
> + if (ArgCAT->getSize().ult(CAT->getSize())) {
> + Diag(CallSiteLoc, diag::warn_static_array_too_small)
> + << ArgExpr->getSourceRange()
> + << (unsigned) ArgCAT->getSize().getZExtValue()
> + << (unsigned) CAT->getSize().getZExtValue();
> + DiagnoseCalleeStaticArrayParam(*this, *i);
> + }
> + }
> +}
> +
Why is this implemented as a separate pass over the parameter/argument pairs? It should be implemented as part of Sema::GatherArgumentsForCall, when we're already inspecting the parameter and argument.
- Doug
More information about the cfe-commits
mailing list