forked from OSchip/llvm-project
Fix for PR5679: make __builtin_prefetch a bit more flexible in what it accepts
as a constant integer. Also, some minor cleanup and improvements to the diagnostics. llvm-svn: 90504
This commit is contained in:
parent
721fcc007e
commit
5efba264cb
|
@ -2374,7 +2374,9 @@ def err_altivec_empty_initializer : Error<"expected initializer">;
|
|||
def err_stack_const_level : Error<
|
||||
"level argument for a stack address builtin must be constant">;
|
||||
|
||||
def err_prefetch_invalid_argument : Error<
|
||||
def err_prefetch_invalid_arg_type : Error<
|
||||
"argument to __builtin_prefetch must be of integer type">;
|
||||
def err_prefetch_invalid_arg_ice : Error<
|
||||
"argument to __builtin_prefetch must be a constant integer">;
|
||||
def err_argument_invalid_range : Error<
|
||||
"argument should be a value from %0 to %1">;
|
||||
|
|
|
@ -700,30 +700,30 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
|
|||
if (Arg->isTypeDependent())
|
||||
continue;
|
||||
|
||||
QualType RWType = Arg->getType();
|
||||
|
||||
const BuiltinType *BT = RWType->getAs<BuiltinType>();
|
||||
llvm::APSInt Result;
|
||||
if (!BT || BT->getKind() != BuiltinType::Int)
|
||||
return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument)
|
||||
if (!Arg->getType()->isIntegralType())
|
||||
return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_arg_type)
|
||||
<< Arg->getSourceRange();
|
||||
|
||||
ImpCastExprToType(Arg, Context.IntTy, CastExpr::CK_IntegralCast);
|
||||
TheCall->setArg(i, Arg);
|
||||
|
||||
if (Arg->isValueDependent())
|
||||
continue;
|
||||
|
||||
llvm::APSInt Result;
|
||||
if (!Arg->isIntegerConstantExpr(Result, Context))
|
||||
return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument)
|
||||
return Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_arg_ice)
|
||||
<< SourceRange(Arg->getLocStart(), Arg->getLocEnd());
|
||||
|
||||
// FIXME: gcc issues a warning and rewrites these to 0. These
|
||||
// seems especially odd for the third argument since the default
|
||||
// is 3.
|
||||
if (i == 1) {
|
||||
if (Result.getSExtValue() < 0 || Result.getSExtValue() > 1)
|
||||
if (Result.getLimitedValue() > 1)
|
||||
return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
|
||||
<< "0" << "1" << Arg->getSourceRange();
|
||||
} else {
|
||||
if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3)
|
||||
if (Result.getLimitedValue() > 3)
|
||||
return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
|
||||
<< "0" << "3" << Arg->getSourceRange();
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ void foo() {
|
|||
__builtin_prefetch(&a, 1);
|
||||
__builtin_prefetch(&a, 1, 2);
|
||||
__builtin_prefetch(&a, 1, 9, 3); // expected-error{{too many arguments to function}}
|
||||
__builtin_prefetch(&a, "hello", 2); // expected-error{{argument to __builtin_prefetch must be a constant integer}}
|
||||
__builtin_prefetch(&a, "hello", 2); // expected-error{{argument to __builtin_prefetch must be of integer type}}
|
||||
__builtin_prefetch(&a, a, 2); // expected-error{{argument to __builtin_prefetch must be a constant integer}}
|
||||
__builtin_prefetch(&a, 2); // expected-error{{argument should be a value from 0 to 1}}
|
||||
__builtin_prefetch(&a, 0, 4); // expected-error{{argument should be a value from 0 to 3}}
|
||||
__builtin_prefetch(&a, -1, 4); // expected-error{{argument should be a value from 0 to 1}}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: clang-cc -fsyntax-only %s -verify
|
||||
// PR5679
|
||||
|
||||
enum X { A = 3 };
|
||||
|
||||
void Test() {
|
||||
char ch;
|
||||
__builtin_prefetch(&ch, 0, A);
|
||||
}
|
Loading…
Reference in New Issue