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
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index e6fa372..449c5f3 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -125,6 +125,14 @@
     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 @@
   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.