[clang] be48c0d - [-Wunsafe-buffer-usage] Fix a bug that wrongly assumed CXXMethodDecl always has an identifier (#137248)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 24 17:03:10 PDT 2025


Author: Ziqing Luo
Date: 2025-04-24T17:03:06-07:00
New Revision: be48c0df77413a237565a339c9ccc275b8256631

URL: https://github.com/llvm/llvm-project/commit/be48c0df77413a237565a339c9ccc275b8256631
DIFF: https://github.com/llvm/llvm-project/commit/be48c0df77413a237565a339c9ccc275b8256631.diff

LOG: [-Wunsafe-buffer-usage] Fix a bug that wrongly assumed CXXMethodDecl always has an identifier (#137248)

Fix a bug in UnsafeBufferUsage.cpp that wrongly assumed that
CXXMethodDecl always has an identifier.

rdar://149071318

Added: 
    clang/test/SemaCXX/bug149071318.cpp

Modified: 
    clang/lib/Analysis/UnsafeBufferUsage.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 4eaf8ba61eaec..5b72382ca9772 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -675,7 +675,7 @@ static bool isNullTermPointer(const Expr *Ptr) {
     const CXXMethodDecl *MD = MCE->getMethodDecl();
     const CXXRecordDecl *RD = MCE->getRecordDecl()->getCanonicalDecl();
 
-    if (MD && RD && RD->isInStdNamespace())
+    if (MD && RD && RD->isInStdNamespace() && MD->getIdentifier())
       if (MD->getName() == "c_str" && RD->getName() == "basic_string")
         return true;
   }

diff  --git a/clang/test/SemaCXX/bug149071318.cpp b/clang/test/SemaCXX/bug149071318.cpp
new file mode 100644
index 0000000000000..596d0e238dfba
--- /dev/null
+++ b/clang/test/SemaCXX/bug149071318.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \
+// RUN:            -verify %s
+
+// This example uncovered a bug in UnsafeBufferUsage.cpp, where the
+// code assumed that a CXXMethodDecl always have an identifier.
+
+int printf( const char* format, char *); // <-- Fake decl of `printf`; to reproduce the bug, this example needs an implicit cast within a printf call.
+
+namespace std { // fake std namespace; to reproduce the bug, a CXXConversionDecl needs to be in std namespace.
+  class X {
+    char * p;
+  public:    
+    operator char*() {return p;}
+  };
+
+  class Y {
+  public:
+    X x;
+  };
+
+}
+
+void test(std::Y &y) {
+  // Here `y.x` involves an implicit cast and calls the overloaded cast operator, which has no identifier:
+  printf("%s", y.x); // expected-warning{{function 'printf' is unsafe}} expected-note{{}}
+}


        


More information about the cfe-commits mailing list