diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-08-31 20:06:00 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-08-31 20:06:00 +0000 |
commit | 9ac6f62a77be5b281a7ddc24a16669b457ac47c2 (patch) | |
tree | af24553022147289b4da436bd63ab56b702f2f46 /lib/Sema/SemaChecking.cpp | |
parent | 017dde547d359a66ec38b80a098a5ddbef087048 (diff) |
PR4836, part 1: add Sema support for __builtin_isnan and friends; they
are apparently used by Solaris libc despite the fact that clang claims
to be compatible with gcc 4.2, which doesn't support them.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80610 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index e6fa372736..449c5f3384 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -125,6 +125,14 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaBuiltinUnorderedCompare(TheCall)) return ExprError(); break; + case Builtin::BI__builtin_isfinite: + case Builtin::BI__builtin_isinf: + case Builtin::BI__builtin_isinf_sign: + case Builtin::BI__builtin_isnan: + case Builtin::BI__builtin_isnormal: + if (SemaBuiltinUnaryFP(TheCall)) + return ExprError(); + break; case Builtin::BI__builtin_return_address: case Builtin::BI__builtin_frame_address: if (SemaBuiltinStackAddress(TheCall)) @@ -557,6 +565,33 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { return false; } +/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isnan and +/// friends. This is declared to take (...), so we have to check everything. +bool Sema::SemaBuiltinUnaryFP(CallExpr *TheCall) { + if (TheCall->getNumArgs() < 1) + return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) + << 0 /*function call*/; + if (TheCall->getNumArgs() > 1) + return Diag(TheCall->getArg(1)->getLocStart(), + diag::err_typecheck_call_too_many_args) + << 0 /*function call*/ + << SourceRange(TheCall->getArg(1)->getLocStart(), + (*(TheCall->arg_end()-1))->getLocEnd()); + + Expr *OrigArg = TheCall->getArg(0); + + if (OrigArg->isTypeDependent()) + return false; + + // This operation requires a floating-point number + if (!OrigArg->getType()->isRealFloatingType()) + return Diag(OrigArg->getLocStart(), + diag::err_typecheck_call_invalid_unary_fp) + << OrigArg->getType() << OrigArg->getSourceRange(); + + return false; +} + bool Sema::SemaBuiltinStackAddress(CallExpr *TheCall) { // The signature for these builtins is exact; the only thing we need // to check is that the argument is a constant. |