forked from OSchip/llvm-project
Move static array parameter checks to SemaExpr, per Doug's request
llvm-svn: 142465
This commit is contained in:
parent
c39977d01b
commit
a48f33f951
|
@ -2475,6 +2475,9 @@ public:
|
|||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation RParenLoc,
|
||||
bool ExecConfig = false);
|
||||
void CheckStaticArrayArgument(SourceLocation CallLoc,
|
||||
ParmVarDecl *Param,
|
||||
const Expr *ArgExpr);
|
||||
|
||||
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
|
||||
/// This provides the location of the left/right parens and a list of comma
|
||||
|
@ -6112,10 +6115,6 @@ private:
|
|||
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);
|
||||
|
|
|
@ -360,9 +360,6 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
|
|||
TheCall->getCallee()->getLocStart());
|
||||
}
|
||||
|
||||
CheckStaticArrayArguments(FDecl, TheCall->getArgs(),
|
||||
TheCall->getCallee()->getLocStart());
|
||||
|
||||
// Builtin handling
|
||||
int CMF = -1;
|
||||
switch (FDecl->getBuiltinID()) {
|
||||
|
@ -1365,64 +1362,6 @@ Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// CheckPrintfScanfArguments - Check calls to printf and scanf (and similar
|
||||
/// functions) for correct use of format strings.
|
||||
void
|
||||
|
|
|
@ -3424,6 +3424,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
|||
QualType ProtoArgType = Proto->getArgType(i);
|
||||
|
||||
Expr *Arg;
|
||||
ParmVarDecl *Param;
|
||||
if (ArgIx < NumArgs) {
|
||||
Arg = Args[ArgIx++];
|
||||
|
||||
|
@ -3434,7 +3435,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
|||
return true;
|
||||
|
||||
// Pass the argument
|
||||
ParmVarDecl *Param = 0;
|
||||
Param = 0;
|
||||
if (FDecl && i < FDecl->getNumParams())
|
||||
Param = FDecl->getParamDecl(i);
|
||||
|
||||
|
@ -3456,7 +3457,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
|||
|
||||
Arg = ArgE.takeAs<Expr>();
|
||||
} else {
|
||||
ParmVarDecl *Param = FDecl->getParamDecl(i);
|
||||
Param = FDecl->getParamDecl(i);
|
||||
|
||||
ExprResult ArgExpr =
|
||||
BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
|
||||
|
@ -3471,6 +3472,9 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
|||
// with its own checking, such as a BinaryOperator.
|
||||
CheckArrayAccess(Arg);
|
||||
|
||||
// Check for violations of C99 static array rules (C99 6.7.5.3p7).
|
||||
CheckStaticArrayArgument(CallLoc, Param, Arg);
|
||||
|
||||
AllArgs.push_back(Arg);
|
||||
}
|
||||
|
||||
|
@ -3508,6 +3512,60 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
|||
return Invalid;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/// CheckStaticArrayArgument - If the given argument corresponds to a static
|
||||
/// array parameter, check that it 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::CheckStaticArrayArgument(SourceLocation CallLoc,
|
||||
ParmVarDecl *Param,
|
||||
const Expr *ArgExpr) {
|
||||
// Static array parameters are not supported in C++.
|
||||
if (!Param || getLangOptions().CPlusPlus)
|
||||
return;
|
||||
|
||||
QualType OrigTy = Param->getOriginalType();
|
||||
|
||||
const ArrayType *AT = Context.getAsArrayType(OrigTy);
|
||||
if (!AT || AT->getSizeModifier() != ArrayType::Static)
|
||||
return;
|
||||
|
||||
if (ArgExpr->isNullPointerConstant(Context,
|
||||
Expr::NPC_NeverValueDependent)) {
|
||||
Diag(CallLoc, diag::warn_null_arg) << ArgExpr->getSourceRange();
|
||||
DiagnoseCalleeStaticArrayParam(*this, Param);
|
||||
return;
|
||||
}
|
||||
|
||||
const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT);
|
||||
if (!CAT)
|
||||
return;
|
||||
|
||||
const ConstantArrayType *ArgCAT =
|
||||
Context.getAsConstantArrayType(ArgExpr->IgnoreParenImpCasts()->getType());
|
||||
if (!ArgCAT)
|
||||
return;
|
||||
|
||||
if (ArgCAT->getSize().ult(CAT->getSize())) {
|
||||
Diag(CallLoc, diag::warn_static_array_too_small)
|
||||
<< ArgExpr->getSourceRange()
|
||||
<< (unsigned) ArgCAT->getSize().getZExtValue()
|
||||
<< (unsigned) CAT->getSize().getZExtValue();
|
||||
DiagnoseCalleeStaticArrayParam(*this, Param);
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a function expression of unknown-any type, try to rebuild it
|
||||
/// to have a function type.
|
||||
static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn);
|
||||
|
|
Loading…
Reference in New Issue