================
@@ -3494,6 +3494,95 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
     if (BuiltinCountedByRef(TheCall))
       return ExprError();
     break;
+
+  case Builtin::BI__builtin_ct_select: {
+    if (TheCall->getNumArgs() != 3) {
+      // Simple argument count check without complex diagnostics
+      if (TheCall->getNumArgs() < 3) {
+        return Diag(TheCall->getEndLoc(),
+                    diag::err_typecheck_call_too_few_args_at_least)
+               << 0 << 3 << TheCall->getNumArgs() << 0
+               << TheCall->getCallee()->getSourceRange();
+      } else {
+        return Diag(TheCall->getEndLoc(),
+                    diag::err_typecheck_call_too_many_args)
+               << 0 << 3 << TheCall->getNumArgs() << 0
+               << TheCall->getCallee()->getSourceRange();
+      }
+    }
+    auto *Cond = TheCall->getArg(0);
+    auto *A = TheCall->getArg(1);
+    auto *B = TheCall->getArg(2);
+
+    QualType CondTy = Cond->getType();
+    if (!CondTy->isIntegerType()) {
+      return Diag(Cond->getBeginLoc(), diag::err_typecheck_cond_expect_scalar)
+             << CondTy << Cond->getSourceRange();
+    }
+
+    QualType ATy = A->getType();
+    QualType BTy = B->getType();
+
+    // check for scalar or vector scalar type
+    if ((!ATy->isScalarType() && !ATy->isVectorType()) ||
+        (!BTy->isScalarType() && !BTy->isVectorType())) {
+      return Diag(A->getBeginLoc(),
+                  diag::err_typecheck_cond_incompatible_operands)
+             << ATy << BTy << A->getSourceRange() << B->getSourceRange();
+    }
+
+    // Check if both operands have the same type or can be implicitly converted
+    QualType ResultTy;
+    if (Context.hasSameType(ATy, BTy)) {
+      ResultTy = ATy;
+    } else {
+      // Try to find a common type using the same logic as conditional
+      // expressions
+      ExprResult ARes = ExprResult(A);
+      ExprResult BRes = ExprResult(B);
+
+      // For arithmetic types, allow promotions within the same category only
+      if (ATy->isArithmeticType() && BTy->isArithmeticType()) {
+        // Check if both are integer types or both are floating types
+        bool AIsInteger = ATy->isIntegerType();
+        bool BIsInteger = BTy->isIntegerType();
+        bool AIsFloating = ATy->isFloatingType();
+        bool BIsFloating = BTy->isFloatingType();
+
+        if ((AIsInteger && BIsInteger) || (AIsFloating && BIsFloating)) {
+          // Both are in the same category, allow usual arithmetic conversions
+          ResultTy = UsualArithmeticConversions(
+              ARes, BRes, TheCall->getBeginLoc(), ArithConvKind::Conditional);
+          if (ARes.isInvalid() || BRes.isInvalid() || ResultTy.isNull()) {
+            return Diag(A->getBeginLoc(),
+                        diag::err_typecheck_cond_incompatible_operands)
+                   << ATy << BTy << A->getSourceRange() << B->getSourceRange();
+          }
+          // Update the arguments with any necessary implicit casts
+          TheCall->setArg(1, ARes.get());
+          TheCall->setArg(2, BRes.get());
+        } else {
+          // Different categories (int vs float), not allowed
+          return Diag(A->getBeginLoc(),
+                      diag::err_typecheck_cond_incompatible_operands)
+                 << ATy << BTy << A->getSourceRange() << B->getSourceRange();
+        }
+      } else {
+        // For non-arithmetic types, they must be exactly the same
+        return Diag(A->getBeginLoc(),
+                    diag::err_typecheck_cond_incompatible_operands)
+               << ATy << BTy << A->getSourceRange() << B->getSourceRange();
+      }
+    }
+
+    ExprResult CondRes = PerformContextuallyConvertToBool(Cond);
+    if (CondRes.isInvalid())
+      return ExprError();
+
+    TheCall->setArg(0, CondRes.get());
+    TheCall->setType(ResultTy);
+    return TheCall;
+  } break;
----------------
efriedma-quic wrote:

Unnecessary break.

https://github.com/llvm/llvm-project/pull/166703
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to