[-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
This commit is contained in:
Ziqing Luo 2025-04-24 17:03:06 -07:00 committed by GitHub
parent 7122d9c562
commit be48c0df77
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 1 deletions

View File

@ -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;
}

View File

@ -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{{}}
}