[flang-commits] [flang] [flang] Avoid UB in CharBlock::Compare to C string (PR #147329)

David Spickett via flang-commits flang-commits at lists.llvm.org
Mon Jul 7 08:45:13 PDT 2025


https://github.com/DavidSpickett created https://github.com/llvm/llvm-project/pull/147329

The behaviour of strncmp is undefined if either string pointer is null (https://en.cppreference.com/w/cpp/string/byte/strncmp.html).

I've copied the logic over from Compare to another CharBlock, which had code to avoid UB in memcmp.

The test Preprocessing/kind-suffix.F90 was failing with UBSAN enabled, and now passes.

>From 1ac17232a1699f4e217bbd3c4ea36e42f810c9b8 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Mon, 7 Jul 2025 15:31:26 +0000
Subject: [PATCH] [flang] Avoid UB in CharBlock::Compare to C string

The behaviour of strncmp is undefined if either string pointer
is null (https://en.cppreference.com/w/cpp/string/byte/strncmp.html).

I've copied the logic over from Compare to another CharBlock,
which had code to avoid UB in memcmp.

The test Preprocessing/kind-suffix.F90 was failing
with UBSAN enabled, and now passes.
---
 flang/include/flang/Parser/char-block.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/flang/include/flang/Parser/char-block.h b/flang/include/flang/Parser/char-block.h
index 38f4f7b82e1ea..b3b1f04034d3c 100644
--- a/flang/include/flang/Parser/char-block.h
+++ b/flang/include/flang/Parser/char-block.h
@@ -150,7 +150,12 @@ class CharBlock {
 
   int Compare(const char *that) const {
     std::size_t bytes{size()};
-    if (int cmp{std::strncmp(begin(), that, bytes)}) {
+    // strncmp is undefined if either pointer is null.
+    if (!bytes) {
+      return that == nullptr ? 0 : -1;
+    } else if (!that) {
+      return 1;
+    } else if (int cmp{std::strncmp(begin(), that, bytes)}) {
       return cmp;
     }
     return that[bytes] == '\0' ? 0 : -1;



More information about the flang-commits mailing list