зеркало из https://github.com/microsoft/clang.git
Add Sema support for __builtin_fpclassify by extending the existing check for __builtin_isinf and friends. Part of PR6083.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96291 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
e0097db284
Коммит
e771a7ac11
|
@ -233,13 +233,12 @@ BUILTIN(__builtin_islessgreater , "i.", "nc")
|
||||||
BUILTIN(__builtin_isunordered , "i.", "nc")
|
BUILTIN(__builtin_isunordered , "i.", "nc")
|
||||||
|
|
||||||
// Unary FP classification
|
// Unary FP classification
|
||||||
// BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
|
BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
|
||||||
BUILTIN(__builtin_isfinite, "i.", "nc")
|
BUILTIN(__builtin_isfinite, "i.", "nc")
|
||||||
BUILTIN(__builtin_isinf, "i.", "nc")
|
BUILTIN(__builtin_isinf, "i.", "nc")
|
||||||
BUILTIN(__builtin_isinf_sign, "i.", "nc")
|
BUILTIN(__builtin_isinf_sign, "i.", "nc")
|
||||||
BUILTIN(__builtin_isnan, "i.", "nc")
|
BUILTIN(__builtin_isnan, "i.", "nc")
|
||||||
BUILTIN(__builtin_isnormal, "i.", "nc")
|
BUILTIN(__builtin_isnormal, "i.", "nc")
|
||||||
BUILTIN(__builtin_fpclassify, "iiiiii.", "nc")
|
|
||||||
|
|
||||||
// Builtins for arithmetic.
|
// Builtins for arithmetic.
|
||||||
BUILTIN(__builtin_clz , "iUi" , "nc")
|
BUILTIN(__builtin_clz , "iUi" , "nc")
|
||||||
|
|
|
@ -4129,7 +4129,7 @@ private:
|
||||||
CallExpr *TheCall);
|
CallExpr *TheCall);
|
||||||
bool SemaBuiltinVAStart(CallExpr *TheCall);
|
bool SemaBuiltinVAStart(CallExpr *TheCall);
|
||||||
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
|
bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
|
||||||
bool SemaBuiltinUnaryFP(CallExpr *TheCall);
|
bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned LastArg=1);
|
||||||
bool SemaBuiltinStackAddress(CallExpr *TheCall);
|
bool SemaBuiltinStackAddress(CallExpr *TheCall);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -141,12 +141,16 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
|
||||||
if (SemaBuiltinUnorderedCompare(TheCall))
|
if (SemaBuiltinUnorderedCompare(TheCall))
|
||||||
return ExprError();
|
return ExprError();
|
||||||
break;
|
break;
|
||||||
|
case Builtin::BI__builtin_fpclassify:
|
||||||
|
if (SemaBuiltinFPClassification(TheCall, 6))
|
||||||
|
return ExprError();
|
||||||
|
break;
|
||||||
case Builtin::BI__builtin_isfinite:
|
case Builtin::BI__builtin_isfinite:
|
||||||
case Builtin::BI__builtin_isinf:
|
case Builtin::BI__builtin_isinf:
|
||||||
case Builtin::BI__builtin_isinf_sign:
|
case Builtin::BI__builtin_isinf_sign:
|
||||||
case Builtin::BI__builtin_isnan:
|
case Builtin::BI__builtin_isnan:
|
||||||
case Builtin::BI__builtin_isnormal:
|
case Builtin::BI__builtin_isnormal:
|
||||||
if (SemaBuiltinUnaryFP(TheCall))
|
if (SemaBuiltinFPClassification(TheCall))
|
||||||
return ExprError();
|
return ExprError();
|
||||||
break;
|
break;
|
||||||
case Builtin::BI__builtin_return_address:
|
case Builtin::BI__builtin_return_address:
|
||||||
|
@ -584,20 +588,21 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isnan and
|
/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
|
||||||
/// friends. This is declared to take (...), so we have to check everything.
|
/// __builtin_isnan and friends. This is declared to take (...), so we have
|
||||||
bool Sema::SemaBuiltinUnaryFP(CallExpr *TheCall) {
|
/// to check everything.
|
||||||
if (TheCall->getNumArgs() < 1)
|
bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned LastArg) {
|
||||||
|
if (TheCall->getNumArgs() < LastArg)
|
||||||
return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
|
return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
|
||||||
<< 0 /*function call*/;
|
<< 0 /*function call*/;
|
||||||
if (TheCall->getNumArgs() > 1)
|
if (TheCall->getNumArgs() > LastArg)
|
||||||
return Diag(TheCall->getArg(1)->getLocStart(),
|
return Diag(TheCall->getArg(LastArg)->getLocStart(),
|
||||||
diag::err_typecheck_call_too_many_args)
|
diag::err_typecheck_call_too_many_args)
|
||||||
<< 0 /*function call*/
|
<< 0 /*function call*/
|
||||||
<< SourceRange(TheCall->getArg(1)->getLocStart(),
|
<< SourceRange(TheCall->getArg(LastArg)->getLocStart(),
|
||||||
(*(TheCall->arg_end()-1))->getLocEnd());
|
(*(TheCall->arg_end()-1))->getLocEnd());
|
||||||
|
|
||||||
Expr *OrigArg = TheCall->getArg(0);
|
Expr *OrigArg = TheCall->getArg(LastArg-1);
|
||||||
|
|
||||||
if (OrigArg->isTypeDependent())
|
if (OrigArg->isTypeDependent())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -9,4 +9,8 @@ void a() {
|
||||||
check(__builtin_isfinite(1)); // expected-error{{requires argument of floating point type}}
|
check(__builtin_isfinite(1)); // expected-error{{requires argument of floating point type}}
|
||||||
check(__builtin_isinf()); // expected-error{{too few arguments}}
|
check(__builtin_isinf()); // expected-error{{too few arguments}}
|
||||||
check(__builtin_isnan(1,2)); // expected-error{{too many arguments}}
|
check(__builtin_isnan(1,2)); // expected-error{{too many arguments}}
|
||||||
|
check(__builtin_fpclassify(0, 0, 0, 0, 0, 1.0));
|
||||||
|
check(__builtin_fpclassify(0, 0, 0, 0, 0, 1)); // expected-error{{requires argument of floating point type}}
|
||||||
|
check(__builtin_fpclassify(0, 0, 0, 0, 1)); // expected-error{{too few arguments}}
|
||||||
|
check(__builtin_fpclassify(0, 0, 0, 0, 0, 1, 0)); // expected-error{{too many arguments}}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче