diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9609,6 +9609,22 @@ return Success(N == Val.getBitWidth() ? 0 : N + 1, E); } + case Builtin::BI__builtin_lround: + case Builtin::BI__builtin_lroundf: + case Builtin::BI__builtin_llround: + case Builtin::BI__builtin_llroundf: { + APFloat FPVal(0.0); + APSInt IVal(Info.Ctx.getIntWidth(E->getType()), 0); + bool isExact = true; + + if(!EvaluateFloat(E->getArg(0), FPVal, Info)) return false; + APFloat::opStatus status = + FPVal.convertToInteger(IVal, APFloat::rmNearestTiesToAway, &isExact); + if(status != APFloat::opInexact && status != APFloat::opOK) return false; + + return Success(IVal.getExtValue(), E); + } + case Builtin::BI__builtin_fpclassify: { APFloat Val(0.0); if (!EvaluateFloat(E->getArg(5), Val, Info)) diff --git a/clang/test/SemaCXX/math-builtins.cpp b/clang/test/SemaCXX/math-builtins.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/math-builtins.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +int main() +{ + constexpr float f1 = 12345.6789; + constexpr float f2 = 12345.4321; + + static_assert(__builtin_llround(f1) == 12346, ""); + static_assert(__builtin_llroundf(f1) == 12346, ""); + + static_assert(__builtin_lround(f1) == 12346, ""); + static_assert(__builtin_lroundf(f1) == 12346, ""); + + static_assert(__builtin_llround(f2) == 12345, ""); + static_assert(__builtin_llroundf(f2) == 12345, ""); + + static_assert(__builtin_lround(f2) == 12345, ""); + static_assert(__builtin_lroundf(f2) == 12345, ""); + + static_assert(__builtin_llround(__builtin_nanf("")) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_llroundf(__builtin_nanf("")) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(__builtin_lround(__builtin_nanf("")) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_lroundf(__builtin_nanf("")) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(__builtin_llround(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_llroundf(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + + static_assert(__builtin_lround(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} + static_assert(__builtin_lroundf(__FLT_MAX__) == 0, ""); // expected-error {{static_assert expression is not an integral constant expression}} +} \ No newline at end of file