From 55abf16c7aec8c3063c368707857795afd06e21d Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sun, 14 Feb 2010 19:08:36 +0000 Subject: [PATCH] Place type-checking static methods at type of file (where they will congregate). No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96180 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Checker/LLVMConventionsChecker.cpp | 70 ++++++++++++++------------ 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/lib/Checker/LLVMConventionsChecker.cpp b/lib/Checker/LLVMConventionsChecker.cpp index 82f6d2c7bd..4e69f2916f 100644 --- a/lib/Checker/LLVMConventionsChecker.cpp +++ b/lib/Checker/LLVMConventionsChecker.cpp @@ -22,8 +22,41 @@ using namespace clang; //===----------------------------------------------------------------------===// -// Check if an llvm::StringRef is bound to temporary std::string whose lifetime -// is shorter than the StringRef's. +// Generic type checking routines. +//===----------------------------------------------------------------------===// + +static bool IsStringRef(QualType T) { + const RecordType *RT = T->getAs(); + if (!RT) + return false; + + return llvm::StringRef(QualType(RT, 0).getAsString()) == + "class llvm::StringRef"; +} + +static bool IsStdString(QualType T) { + if (const QualifiedNameType *QT = T->getAs()) + T = QT->getNamedType(); + + const TypedefType *TT = T->getAs(); + if (!TT) + return false; + + const TypedefDecl *TD = TT->getDecl(); + const NamespaceDecl *ND = dyn_cast(TD->getDeclContext()); + if (!ND) + return false; + const IdentifierInfo *II = ND->getIdentifier(); + if (!II || II->getName() != "std") + return false; + + DeclarationName N = TD->getDeclName(); + return llvm::StringRef(N.getAsString()) == "string"; +} + +//===----------------------------------------------------------------------===// +// CHECK: a llvm::StringRef should not be bound to a temporary std::string whose +// lifetime is shorter than the StringRef's. //===----------------------------------------------------------------------===// namespace { @@ -55,40 +88,11 @@ void StringRefCheckerVisitor::VisitDeclStmt(DeclStmt *S) { VisitVarDecl(VD); } -static bool IsStringRef(QualType T) { - const RecordType *RT = T->getAs(); - if (!RT) - return false; - - return llvm::StringRef(QualType(RT, 0).getAsString()) == - "class llvm::StringRef"; -} - -static bool IsStdString(QualType T) { - if (const QualifiedNameType *QT = T->getAs()) - T = QT->getNamedType(); - - const TypedefType *TT = T->getAs(); - if (!TT) - return false; - - const TypedefDecl *TD = TT->getDecl(); - const NamespaceDecl *ND = dyn_cast(TD->getDeclContext()); - if (!ND) - return false; - const IdentifierInfo *II = ND->getIdentifier(); - if (!II || II->getName() != "std") - return false; - - DeclarationName N = TD->getDeclName(); - return llvm::StringRef(N.getAsString()) == "string"; -} - void StringRefCheckerVisitor::VisitVarDecl(VarDecl *VD) { Expr *Init = VD->getInit(); if (!Init) return; - + // Pattern match for: // llvm::StringRef x = call() (where call returns std::string) if (!IsStringRef(VD->getType())) @@ -111,7 +115,7 @@ void StringRefCheckerVisitor::VisitVarDecl(VarDecl *VD) { CXXBindTemporaryExpr *Ex6 = dyn_cast(Ex5->getSubExpr()); if (!Ex6 || !IsStdString(Ex6->getType())) return; - + // Okay, badness! Report an error. BR.EmitBasicReport("StringRef should not be bound to temporary " "std::string that it outlives", "LLVM Conventions", -- 2.40.0