r368446 - More warnings regarding gsl::Pointer and gsl::Owner attributes

Gabor Horvath via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 9 08:16:35 PDT 2019


Author: xazax
Date: Fri Aug  9 08:16:35 2019
New Revision: 368446

URL: http://llvm.org/viewvc/llvm-project?rev=368446&view=rev
Log:
More warnings regarding gsl::Pointer and gsl::Owner attributes

Differential Revision: https://reviews.llvm.org/D65120

Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/Analysis/inner-pointer.cpp
    cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=368446&r1=368445&r2=368446&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Aug  9 08:16:35 2019
@@ -6564,6 +6564,25 @@ template <typename T> static bool isReco
   return false;
 }
 
+static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
+  if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
+    if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
+      return true;
+  if (!Callee->getParent()->isInStdNamespace() || !Callee->getIdentifier())
+    return false;
+  if (!isRecordWithAttr<PointerAttr>(Callee->getThisObjectType()) &&
+      !isRecordWithAttr<OwnerAttr>(Callee->getThisObjectType()))
+    return false;
+  if (!isRecordWithAttr<PointerAttr>(Callee->getReturnType()) &&
+      !Callee->getReturnType()->isPointerType())
+    return false;
+  return llvm::StringSwitch<bool>(Callee->getName())
+      .Cases("begin", "rbegin", "cbegin", "crbegin", true)
+      .Cases("end", "rend", "cend", "crend", true)
+      .Cases("c_str", "data", "get", true)
+      .Default(false);
+}
+
 static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call,
                                     LocalVisitor Visit) {
   auto VisitPointerArg = [&](const Decl *D, Expr *Arg) {
@@ -6577,10 +6596,9 @@ static void handleGslAnnotatedTypes(Indi
   };
 
   if (auto *MCE = dyn_cast<CXXMemberCallExpr>(Call)) {
-    const FunctionDecl *Callee = MCE->getDirectCallee();
-    if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
-      if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
-        VisitPointerArg(Callee, MCE->getImplicitObjectArgument());
+    const auto *MD = cast_or_null<CXXMethodDecl>(MCE->getDirectCallee());
+    if (MD && shouldTrackImplicitObjectArg(MD))
+      VisitPointerArg(MD, MCE->getImplicitObjectArgument());
     return;
   }
 

Modified: cfe/trunk/test/Analysis/inner-pointer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inner-pointer.cpp?rev=368446&r1=368445&r2=368446&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inner-pointer.cpp (original)
+++ cfe/trunk/test/Analysis/inner-pointer.cpp Fri Aug  9 08:16:35 2019
@@ -1,4 +1,5 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer \
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer   \
+// RUN:   -Wno-dangling -Wno-dangling-field -Wno-return-stack-address \
 // RUN:   %s -analyzer-output=text -verify
 
 #include "Inputs/system-header-simulator-cxx.h"

Modified: cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp?rev=368446&r1=368445&r2=368446&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp (original)
+++ cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp Fri Aug  9 08:16:35 2019
@@ -2,7 +2,6 @@
 struct [[gsl::Owner(int)]] MyIntOwner {
   MyIntOwner();
   int &operator*();
-  int *c_str() const;
 };
 
 struct [[gsl::Pointer(int)]] MyIntPointer {
@@ -52,16 +51,6 @@ long *ownershipTransferToRawPointer() {
   return t.releaseAsRawPointer(); // ok
 }
 
-int *danglingRawPtrFromLocal() {
-  MyIntOwner t;
-  return t.c_str(); // TODO
-}
-
-int *danglingRawPtrFromTemp() {
-  MyIntPointer p;
-  return p.toOwner().c_str(); // TODO
-}
-
 struct Y {
   int a[4];
 };
@@ -103,6 +92,12 @@ MyIntPointer danglingGslPtrFromTemporary
   return MyIntOwner{}; // expected-warning {{returning address of local temporary object}}
 }
 
+MyIntOwner makeTempOwner();
+
+MyIntPointer danglingGslPtrFromTemporary2() {
+  return makeTempOwner(); // expected-warning {{returning address of local temporary object}}
+}
+
 MyLongPointerFromConversion danglingGslPtrFromTemporaryConv() {
   return MyLongOwnerWithConversion{}; // expected-warning {{returning address of local temporary object}}
 }
@@ -124,12 +119,52 @@ void initLocalGslPtrWithTempOwner() {
   global2 = MyLongOwnerWithConversion{}; // TODO ?
 }
 
-struct IntVector {
-  int *begin();
-  int *end();
+namespace std {
+template <typename T>
+struct basic_iterator {};
+
+template <typename T>
+struct vector {
+  typedef basic_iterator<T> iterator;
+  iterator begin();
+  T *data();
+};
+
+template<typename T>
+struct basic_string {
+  const T *c_str() const;
+};
+
+template<typename T>
+struct unique_ptr {
+  T *get() const;
 };
+}
 
 void modelIterators() {
-  int *it = IntVector{}.begin(); // TODO ?
+  std::vector<int>::iterator it = std::vector<int>().begin(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
   (void)it;
 }
+
+std::vector<int>::iterator modelIteratorReturn() {
+  return std::vector<int>().begin(); // expected-warning {{returning address of local temporary object}}
+}
+
+const char *danglingRawPtrFromLocal() {
+  std::basic_string<char> s;
+  return s.c_str(); // expected-warning {{address of stack memory associated with local variable 's' returned}}
+}
+
+const char *danglingRawPtrFromTemp() {
+  return std::basic_string<char>().c_str(); // expected-warning {{returning address of local temporary object}}
+}
+
+std::unique_ptr<int> getUniquePtr();
+
+int *danglingUniquePtrFromTemp() {
+  return getUniquePtr().get(); // expected-warning {{returning address of local temporary object}}
+}
+
+int *danglingUniquePtrFromTemp2() {
+  return std::unique_ptr<int>().get(); // expected-warning {{returning address of local temporary object}}
+}




More information about the cfe-commits mailing list