]> granicus.if.org Git - clang/commitdiff
Add Sema support for __builtin_fpclassify by extending the existing check for __built...
authorBenjamin Kramer <benny.kra@googlemail.com>
Mon, 15 Feb 2010 22:42:31 +0000 (22:42 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Mon, 15 Feb 2010 22:42:31 +0000 (22:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96291 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Builtins.def
lib/Sema/Sema.h
lib/Sema/SemaChecking.cpp
test/Sema/builtin-unary-fp.c

index 5060e9e9e90d3062a39acce50fb732083dc6eb87..85504ac268bc45fdada48e2b1bb7cba2a9c8247e 100644 (file)
@@ -233,13 +233,12 @@ BUILTIN(__builtin_islessgreater , "i.", "nc")
 BUILTIN(__builtin_isunordered   , "i.", "nc")
 
 // Unary FP classification
-// BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
+BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
 BUILTIN(__builtin_isfinite,   "i.", "nc")
 BUILTIN(__builtin_isinf,      "i.", "nc")
 BUILTIN(__builtin_isinf_sign, "i.", "nc")
 BUILTIN(__builtin_isnan,      "i.", "nc")
 BUILTIN(__builtin_isnormal,   "i.", "nc")
-BUILTIN(__builtin_fpclassify, "iiiiii.", "nc")
 
 // Builtins for arithmetic.
 BUILTIN(__builtin_clz  , "iUi"  , "nc")
index 8db3eb1713202aae83eb7645deccd628bbd0a921..3c7492af610879f4e4a570b243b21b23e8a48b79 100644 (file)
@@ -4129,7 +4129,7 @@ private:
                                                     CallExpr *TheCall);
   bool SemaBuiltinVAStart(CallExpr *TheCall);
   bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
-  bool SemaBuiltinUnaryFP(CallExpr *TheCall);
+  bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned LastArg=1);
   bool SemaBuiltinStackAddress(CallExpr *TheCall);
 
 public:
index 64cbde050bfd006776847696f9025b4123e2e0b3..f9466ca385e90c62c7992a2d570a93163311de6d 100644 (file)
@@ -141,12 +141,16 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
     if (SemaBuiltinUnorderedCompare(TheCall))
       return ExprError();
     break;
+  case Builtin::BI__builtin_fpclassify:
+    if (SemaBuiltinFPClassification(TheCall, 6))
+      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))
+    if (SemaBuiltinFPClassification(TheCall))
       return ExprError();
     break;
   case Builtin::BI__builtin_return_address:
@@ -584,20 +588,21 @@ 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)
+/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like
+/// __builtin_isnan and friends.  This is declared to take (...), so we have
+/// to check everything.
+bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned LastArg) {
+  if (TheCall->getNumArgs() < LastArg)
     return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args)
       << 0 /*function call*/;
-  if (TheCall->getNumArgs() > 1)
-    return Diag(TheCall->getArg(1)->getLocStart(),
+  if (TheCall->getNumArgs() > LastArg)
+    return Diag(TheCall->getArg(LastArg)->getLocStart(),
                 diag::err_typecheck_call_too_many_args)
       << 0 /*function call*/
-      << SourceRange(TheCall->getArg(1)->getLocStart(),
+      << SourceRange(TheCall->getArg(LastArg)->getLocStart(),
                      (*(TheCall->arg_end()-1))->getLocEnd());
 
-  Expr *OrigArg = TheCall->getArg(0);
+  Expr *OrigArg = TheCall->getArg(LastArg-1);
 
   if (OrigArg->isTypeDependent())
     return false;
index 8f48d7ffc56c9ced37741660ed7948ff00185b84..57568db8ae3ff008f05ee415e5141fbc2bdf1bcf 100644 (file)
@@ -9,4 +9,8 @@ void a() {
   check(__builtin_isfinite(1)); // expected-error{{requires argument of floating point type}}
   check(__builtin_isinf()); // expected-error{{too few 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}}
 }