summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaChecking.cpp15
-rw-r--r--clang/test/Sema/builtins.c23
2 files changed, 34 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5530bd8fe76..237484a4caa 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -972,6 +972,9 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI__builtin_isinf_sign:
case Builtin::BI__builtin_isnan:
case Builtin::BI__builtin_isnormal:
+ case Builtin::BI__builtin_signbit:
+ case Builtin::BI__builtin_signbitf:
+ case Builtin::BI__builtin_signbitl:
if (SemaBuiltinFPClassification(TheCall, 1))
return ExprError();
break;
@@ -4592,15 +4595,19 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
diag::err_typecheck_call_invalid_unary_fp)
<< OrigArg->getType() << OrigArg->getSourceRange();
- // If this is an implicit conversion from float -> float or double, remove it.
+ // If this is an implicit conversion from float -> float, double, or
+ // long double, remove it.
if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) {
// Only remove standard FloatCasts, leaving other casts inplace
if (Cast->getCastKind() == CK_FloatingCast) {
Expr *CastArg = Cast->getSubExpr();
if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) {
- assert((Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
- Cast->getType()->isSpecificBuiltinType(BuiltinType::Float)) &&
- "promotion from float to either float or double is the only expected cast here");
+ assert(
+ (Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) ||
+ Cast->getType()->isSpecificBuiltinType(BuiltinType::Float) ||
+ Cast->getType()->isSpecificBuiltinType(BuiltinType::LongDouble)) &&
+ "promotion from float to either float, double, or long double is "
+ "the only expected cast here");
Cast->setSubExpr(nullptr);
TheCall->setArg(NumArgs-1, CastArg);
}
diff --git a/clang/test/Sema/builtins.c b/clang/test/Sema/builtins.c
index 7e999991f34..a831d030ef1 100644
--- a/clang/test/Sema/builtins.c
+++ b/clang/test/Sema/builtins.c
@@ -253,3 +253,26 @@ void test21(const int *ptr) {
__sync_fetch_and_add(ptr, 1); // expected-error{{address argument to atomic builtin cannot be const-qualified ('const int *' invalid)}}
__atomic_fetch_add(ptr, 1, 0); // expected-error {{address argument to atomic operation must be a pointer to non-const type ('const int *' invalid)}}
}
+
+void test22(void) {
+ (void)__builtin_signbit(); // expected-error{{too few arguments to function call, expected 1, have 0}}
+ (void)__builtin_signbit(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}
+ (void)__builtin_signbit(1); // expected-error {{floating point classification requires argument of floating point type (passed in 'int')}}
+ (void)__builtin_signbit(1.0);
+ (void)__builtin_signbit(1.0f);
+ (void)__builtin_signbit(1.0L);
+
+ (void)__builtin_signbitf(); // expected-error{{too few arguments to function call, expected 1, have 0}}
+ (void)__builtin_signbitf(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}
+ (void)__builtin_signbitf(1);
+ (void)__builtin_signbitf(1.0);
+ (void)__builtin_signbitf(1.0f);
+ (void)__builtin_signbitf(1.0L);
+
+ (void)__builtin_signbitl(); // expected-error{{too few arguments to function call, expected 1, have 0}}
+ (void)__builtin_signbitl(1.0, 2.0, 3.0); // expected-error{{too many arguments to function call, expected 1, have 3}}
+ (void)__builtin_signbitl(1);
+ (void)__builtin_signbitl(1.0);
+ (void)__builtin_signbitl(1.0f);
+ (void)__builtin_signbitl(1.0L);
+}
OpenPOWER on IntegriCloud