mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-13 02:21:45 +00:00
Sema: Windows/ARM __va_start is not const correct
The `__va_start` intrinsic for Windows ARM does not account for const correctness when performing a check. All local qualifiers are ignored when validating the invocation. This was exposed by building the swift stdlib against the Windows 10586 SDK for ARM. Simply expand out the check for the two parameters and ignore the qualifiers for the check. llvm-svn: 314226
This commit is contained in:
parent
1b3c43b6dd
commit
448e8ad943
@ -3943,23 +3943,33 @@ bool Sema::SemaBuiltinVAStartARM(CallExpr *Call) {
|
||||
if (checkVAStartIsInVariadicFunction(*this, Func))
|
||||
return true;
|
||||
|
||||
const struct {
|
||||
unsigned ArgNo;
|
||||
QualType Type;
|
||||
} ArgumentTypes[] = {
|
||||
{ 1, Context.getPointerType(Context.CharTy.withConst()) },
|
||||
{ 2, Context.getSizeType() },
|
||||
};
|
||||
// __va_start on Windows does not validate the parameter qualifiers
|
||||
|
||||
for (const auto &AT : ArgumentTypes) {
|
||||
const Expr *Arg = Call->getArg(AT.ArgNo)->IgnoreParens();
|
||||
if (Arg->getType().getCanonicalType() == AT.Type.getCanonicalType())
|
||||
continue;
|
||||
Diag(Arg->getLocStart(), diag::err_typecheck_convert_incompatible)
|
||||
<< Arg->getType() << AT.Type << 1 /* different class */
|
||||
<< 0 /* qualifier difference */ << 3 /* parameter mismatch */
|
||||
<< AT.ArgNo + 1 << Arg->getType() << AT.Type;
|
||||
}
|
||||
const Expr *Arg1 = Call->getArg(1)->IgnoreParens();
|
||||
const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();
|
||||
|
||||
const Expr *Arg2 = Call->getArg(2)->IgnoreParens();
|
||||
const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();
|
||||
|
||||
const QualType &ConstCharPtrTy =
|
||||
Context.getPointerType(Context.CharTy.withConst());
|
||||
if (!Arg1Ty->isPointerType() ||
|
||||
Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)
|
||||
Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)
|
||||
<< Arg1->getType() << ConstCharPtrTy
|
||||
<< 1 /* different class */
|
||||
<< 0 /* qualifier difference */
|
||||
<< 3 /* parameter mismatch */
|
||||
<< 2 << Arg1->getType() << ConstCharPtrTy;
|
||||
|
||||
const QualType SizeTy = Context.getSizeType();
|
||||
if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)
|
||||
Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)
|
||||
<< Arg2->getType() << SizeTy
|
||||
<< 1 /* different class */
|
||||
<< 0 /* qualifier difference */
|
||||
<< 3 /* parameter mismatch */
|
||||
<< 3 << Arg2->getType() << SizeTy;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -20,3 +20,8 @@ int builtin(int i, ...) {
|
||||
return __builtin_va_arg(ap, int);
|
||||
}
|
||||
|
||||
void test___va_start_ignore_const(const char *format, ...) {
|
||||
va_list args;
|
||||
((void)(__va_start(&args, (&const_cast<char &>(reinterpret_cast<const volatile char &>(format))), ((sizeof(format) + 4 - 1) & ~(4 - 1)), (&const_cast<char &>(reinterpret_cast<const volatile char &>(format))))));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user