https://github.com/divyansh-1009 updated 
https://github.com/llvm/llvm-project/pull/205452

>From 30ef9df38f27f6511fea3aa378f42e5eccf8f489 Mon Sep 17 00:00:00 2001
From: Divyansh <[email protected]>
Date: Wed, 24 Jun 2026 04:28:01 +0530
Subject: [PATCH 1/4] [Clang] Fix assertion failure when passing wide string
 literal to __builtin_nanf

Fixes #205306.
---
 clang/lib/AST/ExprConstant.cpp            | 2 ++
 clang/test/Sema/builtin-nan-wide-string.c | 3 +++
 2 files changed, 5 insertions(+)
 create mode 100644 clang/test/Sema/builtin-nan-wide-string.c

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 8efceff7e8c31..02afad4096655 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -19999,6 +19999,8 @@ static bool TryEvaluateBuiltinNaN(const ASTContext 
&Context,
   const StringLiteral *S = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
   if (!S) return false;
 
+  if (!S->isOrdinary() && !S->isUTF8()) return false;
+
   const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
 
   llvm::APInt fill;
diff --git a/clang/test/Sema/builtin-nan-wide-string.c 
b/clang/test/Sema/builtin-nan-wide-string.c
new file mode 100644
index 0000000000000..52e1b4a17db94
--- /dev/null
+++ b/clang/test/Sema/builtin-nan-wide-string.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+char hello = __builtin_nanf(L""); // expected-error {{incompatible pointer 
types passing 'int[1]' to parameter of type 'const char *'}}

>From 2c461a63e4fcefb14ebebb416b89212dd5603906 Mon Sep 17 00:00:00 2001
From: Divyansh <[email protected]>
Date: Wed, 24 Jun 2026 21:53:06 +0530
Subject: [PATCH 2/4] update release notes, add comprehensive test coverages,
 restrict support to ordinary string literals, add run directives for C and
 C++

---
 clang/docs/ReleaseNotes.rst               |  1 +
 clang/lib/AST/ExprConstant.cpp            |  2 +-
 clang/test/Sema/builtin-nan-wide-string.c | 47 ++++++++++++++++++++++-
 clang/test/Sema/constant-builtins-2.c     |  4 ++
 test_nan_u8.c                             |  1 +
 test_nan_u8.cpp                           |  1 +
 test_nan_wide.c                           |  1 +
 test_nan_wide2.c                          |  1 +
 8 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100644 test_nan_u8.c
 create mode 100644 test_nan_u8.cpp
 create mode 100644 test_nan_wide.c
 create mode 100644 test_nan_wide2.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0ff8e8f5afd3c..829f919f892af 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -744,6 +744,7 @@ Bug Fixes to Compiler Builtins
   crash when using it with ``-fms-extensions`` on other platforms. (#GH184318)
 - Fixed a compiler crash due to an unresolved overloaded function type when
   calling ``__builtin_bit_cast``. (#GH200112)
+- Fixed an assertion failure when passing a wide string literal to 
``__builtin_nan`` and related builtins. (#GH205306)
 
 Bug Fixes to Attribute Support
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 02afad4096655..fa34c4ff3a9a2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -19999,7 +19999,7 @@ static bool TryEvaluateBuiltinNaN(const ASTContext 
&Context,
   const StringLiteral *S = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
   if (!S) return false;
 
-  if (!S->isOrdinary() && !S->isUTF8()) return false;
+  if (!S->isOrdinary()) return false;
 
   const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
 
diff --git a/clang/test/Sema/builtin-nan-wide-string.c 
b/clang/test/Sema/builtin-nan-wide-string.c
index 52e1b4a17db94..d97af1c7ad898 100644
--- a/clang/test/Sema/builtin-nan-wide-string.c
+++ b/clang/test/Sema/builtin-nan-wide-string.c
@@ -1,3 +1,46 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c -x c %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx -x c++ %s
+// RUN: %clang_cc1 -fsyntax-only -verify=c -x c 
-fexperimental-new-constant-interpreter %s
+// RUN: %clang_cc1 -fsyntax-only -verify=cxx -x c++ 
-fexperimental-new-constant-interpreter %s
 
-char hello = __builtin_nanf(L""); // expected-error {{incompatible pointer 
types passing 'int[1]' to parameter of type 'const char *'}}
+#ifdef __cplusplus
+#define CONSTEXPR constexpr
+#else
+#define CONSTEXPR
+#endif
+
+CONSTEXPR float f1 = __builtin_nanf(L"");
+// c-warning@-1 {{incompatible pointer types passing 'int[1]' to parameter of 
type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const wchar_t[1]'}}
+
+CONSTEXPR double d1 = __builtin_nan(L"");
+// c-warning@-1 {{incompatible pointer types passing 'int[1]' to parameter of 
type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const wchar_t[1]'}}
+
+CONSTEXPR long double ld1 = __builtin_nanl(L"");
+// c-warning@-1 {{incompatible pointer types passing 'int[1]' to parameter of 
type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const wchar_t[1]'}}
+
+CONSTEXPR float f2 = __builtin_nanf(u"");
+// c-warning@-1 {{incompatible pointer types passing 'unsigned short[1]' to 
parameter of type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const char16_t[1]'}}
+
+CONSTEXPR double d2 = __builtin_nan(u"");
+// c-warning@-1 {{incompatible pointer types passing 'unsigned short[1]' to 
parameter of type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const char16_t[1]'}}
+
+CONSTEXPR long double ld2 = __builtin_nanl(u"");
+// c-warning@-1 {{incompatible pointer types passing 'unsigned short[1]' to 
parameter of type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const char16_t[1]'}}
+
+CONSTEXPR float f3 = __builtin_nanf(U"");
+// c-warning@-1 {{incompatible pointer types passing 'unsigned int[1]' to 
parameter of type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const char32_t[1]'}}
+
+CONSTEXPR double d3 = __builtin_nan(U"");
+// c-warning@-1 {{incompatible pointer types passing 'unsigned int[1]' to 
parameter of type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const char32_t[1]'}}
+
+CONSTEXPR long double ld3 = __builtin_nanl(U"");
+// c-warning@-1 {{incompatible pointer types passing 'unsigned int[1]' to 
parameter of type 'const char *'}}
+// cxx-error@-2 {{cannot initialize a parameter of type 'const char *' with an 
lvalue of type 'const char32_t[1]'}}
diff --git a/clang/test/Sema/constant-builtins-2.c 
b/clang/test/Sema/constant-builtins-2.c
index fd3643bbdb7c8..4890ff0ecc1cc 100644
--- a/clang/test/Sema/constant-builtins-2.c
+++ b/clang/test/Sema/constant-builtins-2.c
@@ -19,6 +19,10 @@ __float128   g5_2 = __builtin_inff128();
 double       g6  = __builtin_nan("");
 float        g7  = __builtin_nanf("");
 long double  g8  = __builtin_nanl("");
+
+double       g6_u8  = __builtin_nan(u8"");
+float        g7_u8  = __builtin_nanf(u8"");
+long double  g8_u8  = __builtin_nanl(u8"");
 #if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
 __float128   g8_2 = __builtin_nanf128("");
 #endif
diff --git a/test_nan_u8.c b/test_nan_u8.c
new file mode 100644
index 0000000000000..6859499504725
--- /dev/null
+++ b/test_nan_u8.c
@@ -0,0 +1 @@
+float g8 = __builtin_nanf(u8"");
diff --git a/test_nan_u8.cpp b/test_nan_u8.cpp
new file mode 100644
index 0000000000000..1016b5b948ef3
--- /dev/null
+++ b/test_nan_u8.cpp
@@ -0,0 +1 @@
+constexpr float g8 = __builtin_nanf(u8"");
diff --git a/test_nan_wide.c b/test_nan_wide.c
new file mode 100644
index 0000000000000..6c8abecf78d31
--- /dev/null
+++ b/test_nan_wide.c
@@ -0,0 +1 @@
+float g8 = __builtin_nanf(L"");
diff --git a/test_nan_wide2.c b/test_nan_wide2.c
new file mode 100644
index 0000000000000..657ef0ac7ad19
--- /dev/null
+++ b/test_nan_wide2.c
@@ -0,0 +1 @@
+char hello = __builtin_nanf(L"");

>From 8b0428b3c34ed8f95b57f50ab8216164d72b4e1b Mon Sep 17 00:00:00 2001
From: Divyansh <[email protected]>
Date: Thu, 25 Jun 2026 00:02:05 +0530
Subject: [PATCH 3/4] fix: validate that arguments to __builtin_nan functions
 are ordinary string literals

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 ++
 clang/lib/Sema/SemaChecking.cpp               | 23 +++++++++++++++++++
 test_cxx17_u8.cpp                             |  1 +
 test_nan_all.c                                |  5 ++++
 test_nan_u8_c.c                               |  1 +
 5 files changed, 32 insertions(+)
 create mode 100644 test_cxx17_u8.cpp
 create mode 100644 test_nan_all.c
 create mode 100644 test_nan_u8_c.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cde99dfb16ec5..062d0c5384dfd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -171,6 +171,8 @@ def err_ice_too_large : Error<
   "integer constant expression evaluates to value %0 that cannot be "
   "represented in a %1-bit %select{signed|unsigned}2 integer type">;
 def err_expr_not_string_literal : Error<"expression is not a string literal">;
+def err_expected_ordinary_string_literal : Error<
+  "argument to %0 must be an ordinary string literal">;
 def note_constexpr_assert_failed : Note<
   "assertion failed during evaluation of constant expression">;
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index fa0ec55a63bb7..4343af146b147 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3001,6 +3001,29 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 
   FPOptions FPO;
   switch (BuiltinID) {
+  case Builtin::BI__builtin_nan:
+  case Builtin::BI__builtin_nanf:
+  case Builtin::BI__builtin_nanl:
+  case Builtin::BI__builtin_nanf16:
+  case Builtin::BI__builtin_nanf128:
+  case Builtin::BI__builtin_nans:
+  case Builtin::BI__builtin_nansf:
+  case Builtin::BI__builtin_nansl:
+  case Builtin::BI__builtin_nansf16:
+  case Builtin::BI__builtin_nansf128: {
+    if (TheCall->getNumArgs() > 0) {
+      Expr *Arg = TheCall->getArg(0)->IgnoreParenCasts();
+      if (StringLiteral *S = dyn_cast<StringLiteral>(Arg)) {
+        if (!S->isOrdinary()) {
+          Diag(Arg->getBeginLoc(), diag::err_expected_ordinary_string_literal)
+              << Context.BuiltinInfo.getQuotedName(BuiltinID)
+              << Arg->getSourceRange();
+          return ExprError();
+        }
+      }
+    }
+    break;
+  }
   case Builtin::BI__builtin___get_unsafe_stack_start:
   case Builtin::BI__builtin___get_unsafe_stack_bottom:
     Diag(TheCall->getBeginLoc(), diag::warn_deprecated_builtin)
diff --git a/test_cxx17_u8.cpp b/test_cxx17_u8.cpp
new file mode 100644
index 0000000000000..1016b5b948ef3
--- /dev/null
+++ b/test_cxx17_u8.cpp
@@ -0,0 +1 @@
+constexpr float g8 = __builtin_nanf(u8"");
diff --git a/test_nan_all.c b/test_nan_all.c
new file mode 100644
index 0000000000000..3c9dddda8597a
--- /dev/null
+++ b/test_nan_all.c
@@ -0,0 +1,5 @@
+float f1 = __builtin_nanf(u8"");
+float f2 = __builtin_nanf(L"");
+float f3 = __builtin_nanf(u"");
+float f4 = __builtin_nanf(U"");
+float f5 = __builtin_nanf("");
diff --git a/test_nan_u8_c.c b/test_nan_u8_c.c
new file mode 100644
index 0000000000000..6859499504725
--- /dev/null
+++ b/test_nan_u8_c.c
@@ -0,0 +1 @@
+float g8 = __builtin_nanf(u8"");

>From 40fe99030be11023f800ef1750bd934951eea4b2 Mon Sep 17 00:00:00 2001
From: Divyansh <[email protected]>
Date: Fri, 26 Jun 2026 00:16:14 +0530
Subject: [PATCH 4/4] Revert changes related to disallowing u8 string literals

This focuses the PR exclusively on fixing the failed assertion for wide strings,
keeping the changes for u8 literals for a separate PR. Also updates the new
constant evaluator to properly handle unsigned 8-bit character arrays.
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 --
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      | 12 ++++++++--
 clang/lib/AST/ExprConstant.cpp                |  2 +-
 clang/lib/Sema/SemaChecking.cpp               | 23 -------------------
 test_cxx17_u8.cpp                             |  1 -
 test_nan_all.c                                |  5 ----
 test_nan_u8_c.c                               |  1 -
 7 files changed, 11 insertions(+), 35 deletions(-)
 delete mode 100644 test_cxx17_u8.cpp
 delete mode 100644 test_nan_all.c
 delete mode 100644 test_nan_u8_c.c

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 062d0c5384dfd..cde99dfb16ec5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -171,8 +171,6 @@ def err_ice_too_large : Error<
   "integer constant expression evaluates to value %0 that cannot be "
   "represented in a %1-bit %select{signed|unsigned}2 integer type">;
 def err_expr_not_string_literal : Error<"expression is not a string literal">;
-def err_expected_ordinary_string_literal : Error<
-  "argument to %0 must be an ordinary string literal">;
 def note_constexpr_assert_failed : Note<
   "assertion failed during evaluation of constant expression">;
 
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index e59d14db896a2..bf0be2a817701 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -441,11 +441,19 @@ static bool interp__builtin_nan(InterpState &S, CodePtr 
OpPC,
     if (!Arg.isElementInitialized(I))
       return false;
 
-    if (Arg.elem<int8_t>(I) == 0) {
+    char C;
+    if (Arg.getFieldDesc()->getPrimType() == PT_Sint8)
+      C = Arg.elem<int8_t>(I);
+    else if (Arg.getFieldDesc()->getPrimType() == PT_Uint8)
+      C = Arg.elem<uint8_t>(I);
+    else
+      return false;
+
+    if (C == 0) {
       FoundZero = true;
       break;
     }
-    Str += Arg.elem<char>(I);
+    Str += C;
   }
 
   // If we didn't find a NUL byte, diagnose as a one-past-the-end read.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d6de806722661..5368de32f4316 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -19999,7 +19999,7 @@ static bool TryEvaluateBuiltinNaN(const ASTContext 
&Context,
   const StringLiteral *S = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
   if (!S) return false;
 
-  if (!S->isOrdinary()) return false;
+  if (!S->isOrdinary() && !S->isUTF8()) return false;
 
   const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4343af146b147..fa0ec55a63bb7 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3001,29 +3001,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, 
unsigned BuiltinID,
 
   FPOptions FPO;
   switch (BuiltinID) {
-  case Builtin::BI__builtin_nan:
-  case Builtin::BI__builtin_nanf:
-  case Builtin::BI__builtin_nanl:
-  case Builtin::BI__builtin_nanf16:
-  case Builtin::BI__builtin_nanf128:
-  case Builtin::BI__builtin_nans:
-  case Builtin::BI__builtin_nansf:
-  case Builtin::BI__builtin_nansl:
-  case Builtin::BI__builtin_nansf16:
-  case Builtin::BI__builtin_nansf128: {
-    if (TheCall->getNumArgs() > 0) {
-      Expr *Arg = TheCall->getArg(0)->IgnoreParenCasts();
-      if (StringLiteral *S = dyn_cast<StringLiteral>(Arg)) {
-        if (!S->isOrdinary()) {
-          Diag(Arg->getBeginLoc(), diag::err_expected_ordinary_string_literal)
-              << Context.BuiltinInfo.getQuotedName(BuiltinID)
-              << Arg->getSourceRange();
-          return ExprError();
-        }
-      }
-    }
-    break;
-  }
   case Builtin::BI__builtin___get_unsafe_stack_start:
   case Builtin::BI__builtin___get_unsafe_stack_bottom:
     Diag(TheCall->getBeginLoc(), diag::warn_deprecated_builtin)
diff --git a/test_cxx17_u8.cpp b/test_cxx17_u8.cpp
deleted file mode 100644
index 1016b5b948ef3..0000000000000
--- a/test_cxx17_u8.cpp
+++ /dev/null
@@ -1 +0,0 @@
-constexpr float g8 = __builtin_nanf(u8"");
diff --git a/test_nan_all.c b/test_nan_all.c
deleted file mode 100644
index 3c9dddda8597a..0000000000000
--- a/test_nan_all.c
+++ /dev/null
@@ -1,5 +0,0 @@
-float f1 = __builtin_nanf(u8"");
-float f2 = __builtin_nanf(L"");
-float f3 = __builtin_nanf(u"");
-float f4 = __builtin_nanf(U"");
-float f5 = __builtin_nanf("");
diff --git a/test_nan_u8_c.c b/test_nan_u8_c.c
deleted file mode 100644
index 6859499504725..0000000000000
--- a/test_nan_u8_c.c
+++ /dev/null
@@ -1 +0,0 @@
-float g8 = __builtin_nanf(u8"");

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to