[clang] 187d096 - [clang] Fix the StringRef assertion failure for non-narrow strings. (#212108)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 27 04:28:21 PDT 2026
Author: Hardik Kumar
Date: 2026-07-27T19:28:17+08:00
New Revision: 187d096d44bfabc0a392d0abf1d87123e67f5efb
URL: https://github.com/llvm/llvm-project/commit/187d096d44bfabc0a392d0abf1d87123e67f5efb
DIFF: https://github.com/llvm/llvm-project/commit/187d096d44bfabc0a392d0abf1d87123e67f5efb.diff
LOG: [clang] Fix the StringRef assertion failure for non-narrow strings. (#212108)
StringRef assertion fires up when passing wide literals to
`__builtin_nanf()`.
The patch updates the `TryEvaluateBuiltinNan` method to reject
non-narrow string literals preventing the downstream assertion failure
caused by `getString()` in cases where the user might pass a non-narrow
/ non 1 byte literal."
Fix #205306
Added:
Modified:
clang/docs/ReleaseNotes.md
clang/lib/AST/ExprConstant.cpp
clang/test/Sema/constexpr.c
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index dbbf1b8e88d74..74df9c88d1185 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -342,6 +342,7 @@ features cannot lower the translation-unit ABI level;
### Bug Fixes in This Version
+- Fixed an assertion failure when passing a wide string literal to `__builtin_nan`. (#GH212108)
- Fixed a constraint comparison bug in partial ordering. (#GH182671)
- Fixed a rejected-valid case that used an explicit object parameter in an out-of-line definition of a nested class member. (#GH136472)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 574dd8b04e779..a3385d3b7318f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -20394,7 +20394,8 @@ static bool TryEvaluateBuiltinNaN(const ASTContext &Context,
bool SNaN,
llvm::APFloat &Result) {
const StringLiteral *S = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
- if (!S) return false;
+ if (!S || !S->isOrdinary())
+ return false;
const llvm::fltSemantics &Sem = Context.getFloatTypeSemantics(ResultTy);
diff --git a/clang/test/Sema/constexpr.c b/clang/test/Sema/constexpr.c
index 51ee62d2495f3..0a9b5724a8343 100644
--- a/clang/test/Sema/constexpr.c
+++ b/clang/test/Sema/constexpr.c
@@ -347,6 +347,10 @@ void f7(int n, int array[n]) {
#define DBL_SNAN __builtin_nans("1")
#define LD_SNAN __builtin_nansl("1")
#define INF __builtin_inf()
+#define WIDE_NAN __builtin_nanf(L"1")
+#define UTF32_NAN __builtin_nanf(U"1")
+#define UTF16_NAN __builtin_nanf(u"1")
+#define UTF8_NAN __builtin_nanf(u8"1")
void infsNaNs() {
// Inf and quiet NaN is always fine, signaling NaN must have the same type.
constexpr float fl0 = INF;
@@ -357,6 +361,18 @@ void infsNaNs() {
constexpr float fl6 = LD_NAN;
constexpr float fl7 = DBL_SNAN; // expected-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const float'}}
constexpr float fl8 = LD_SNAN; // expected-error {{constexpr initializer evaluates to nan which is not exactly representable in type 'const float'}}
+ constexpr float fl9 = WIDE_NAN; // expected-error {{incompatible pointer types passing 'int[2]' to parameter of type 'const char *'}} \
+ // expected-error {{constexpr variable 'fl9' must be initialized by a constant expression}} \
+ // expected-note 0+ {{this conversion is not allowed in a constant expression}}
+ constexpr float fl10 = UTF32_NAN; // expected-error {{incompatible pointer types passing 'unsigned int[2]' to parameter of type 'const char *'}} \
+ // expected-error {{constexpr variable 'fl10' must be initialized by a constant expression}} \
+ // expected-note 0+ {{this conversion is not allowed in a constant expression}}
+ constexpr float fl11 = UTF16_NAN; // expected-error {{incompatible pointer types passing 'unsigned short[2]' to parameter of type 'const char *'}} \
+ // expected-error {{constexpr variable 'fl11' must be initialized by a constant expression}} \
+ // expected-note 0+ {{this conversion is not allowed in a constant expression}}
+ constexpr float fl12 = UTF8_NAN; // expected-warning {{passing 'unsigned char[2]' to parameter of type 'const char *' converts between pointers to integer types where one is of the unique plain 'char' type and the other is not}} \
+ // expected-error {{constexpr variable 'fl12' must be initialized by a constant expression}} \
+ // expected-note 0+ {{this conversion is not allowed in a constant expression}}
constexpr double db0 = FLT_NAN;
constexpr double db2 = DBL_NAN;
More information about the cfe-commits
mailing list