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

Reply via email to