Author: Timm Baeder Date: 2026-08-20T06:53:15+02:00 New Revision: 014b3ed9f26b294d586c07403611af8f2f99160c
URL: https://github.com/llvm/llvm-project/commit/014b3ed9f26b294d586c07403611af8f2f99160c DIFF: https://github.com/llvm/llvm-project/commit/014b3ed9f26b294d586c07403611af8f2f99160c.diff LOG: [clang][Sema] Do lvalue-to-rvalue conversion on isfpclass Mask arg (#216929) Fixes https://github.com/llvm/llvm-project/issues/216294 Added: Modified: clang/lib/Sema/SemaChecking.cpp clang/test/AST/ByteCode/builtin-functions.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3e6266b8ac542..07c88a4d2af62 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -6481,10 +6481,17 @@ bool Sema::BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, // __builtin_isfpclass has integer parameter that specify test mask. It is // passed in (...), so it should be analyzed completely here. - if (IsFPClass) + if (IsFPClass) { if (BuiltinConstantArgRange(TheCall, 1, 0, llvm::fcAllFlags)) return true; + ExprResult MaskRes = PerformImplicitConversion( + TheCall->getArg(NumArgs - 1), Context.IntTy, AssignmentAction::Passing); + if (!MaskRes.isUsable()) + return true; + TheCall->setArg(NumArgs - 1, MaskRes.get()); + } + // TODO: enable this code to all classification functions. if (IsFPClass) { QualType ResultTy; diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index 87ffb1cc5b609..53c72b4ddcfd0 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -339,6 +339,26 @@ namespace isfpclass { char isfpclass_snan_1 [!__builtin_isfpclass(__builtin_nans(""), 0x0002) ? 1 : -1]; // fcQNan char isfpclass_snan_2 [__builtin_isfpclass(__builtin_nansl(""), 0x0207) ? 1 : -1]; // ~fcFinite char isfpclass_snan_3 [!__builtin_isfpclass(__builtin_nans(""), 0x01F8) ? 1 : -1]; // fcFinite + + + int foo() { + int a = 1; // #decla + char A[__builtin_isfpclass(1.0f, a)]; +#if __cplusplus >= 202002L + // both-warning@-2 {{variable length arrays}} \ + // both-note@-2 {{read of non-const variable 'a'}} \ + // both-note@#decla {{declared here}} +#endif + } + + constexpr float a = 1.0f; + static_assert(__builtin_isfpclass(1.0f, a) == 0); + + enum class EC { A, B }; + static_assert(__builtin_isfpclass(1.0f, EC::A) == 0); // both-error {{passing 'isfpclass::EC' to parameter of incompatible type 'int'}} + struct foostruct {}; + static_assert(__builtin_isfpclass(1.0f, foostruct{}) == 0); // both-error {{passing 'foostruct' to parameter of incompatible type 'int'}} + } namespace signbit { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
