From dd0e2b01ae58f3b5c9cf8adfd016c9d239458955 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Tue, 19 Jun 2018 14:59:11 +0000 Subject: [PATCH] Implement semantic checking for __builtin_signbit. r242675 changed the signature for the signbit builtin but did not introduce proper semantic checking to ensure the arguments are as-expected. This patch groups the signbit builtin along with the other fp classification builtins. Fixes PR28172. llvm-svn: 335050 --- clang/lib/Sema/SemaChecking.cpp | 15 +++++++++++---- clang/test/Sema/builtins.c | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 5530bd8..237484a 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(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 7e99999..a831d03 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); +} -- 2.7.4