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 | 7e4faaccda693444b1c8c0a6527d8861d52de558 (patch) | |
tree | 9f5b4d93b51bdc618a5458c883f91d3af8fd61fa /clang/lib/Sema/SemaChecking.cpp | |
parent | f14b46f9a86391961c257232c64ced7f17f05f71 (diff) | |
download | bcm5719-llvm-7e4faaccda693444b1c8c0a6527d8861d52de558.tar.gz bcm5719-llvm-7e4faaccda693444b1c8c0a6527d8861d52de558.zip |
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.
llvm-svn: 80610
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e6fa3727369..449c5f33840 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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. |