[clang] [llvm] [Clang] Fix assertion failure when passing wide string literal to __builtin_nanf (PR #205452)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 24 09:23:28 PDT 2026
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 <anshmcs at gmail.com>
Date: Wed, 24 Jun 2026 04:28:01 +0530
Subject: [PATCH 1/2] [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 <anshmcs at gmail.com>
Date: Wed, 24 Jun 2026 21:53:06 +0530
Subject: [PATCH 2/2] 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 at -1 {{incompatible pointer types passing 'int[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'int[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'int[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'unsigned short[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'unsigned short[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'unsigned short[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'unsigned int[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'unsigned int[1]' to parameter of type 'const char *'}}
+// cxx-error at -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 at -1 {{incompatible pointer types passing 'unsigned int[1]' to parameter of type 'const char *'}}
+// cxx-error at -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"");
More information about the cfe-commits
mailing list