r277889 - Fix two false positives in -Wreturn-stack-address

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 5 16:24:47 PDT 2016


Author: rtrieu
Date: Fri Aug  5 18:24:47 2016
New Revision: 277889

URL: http://llvm.org/viewvc/llvm-project?rev=277889&view=rev
Log:
Fix two false positives in -Wreturn-stack-address

If the return type is a pointer and the function returns the reference to a
pointer, don't warn since only the value is returned, not the reference.

If a reference function parameter appears in the reference chain, don't warn
since binding happens at the caller scope, so addresses returned are not
to local stack.  This includes default arguments as well.

Modified:
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/SemaCXX/return-stack-addr-2.cpp

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=277889&r1=277888&r2=277889&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Aug  5 18:24:47 2016
@@ -6572,6 +6572,12 @@ CheckReturnStackAddr(Sema &S, Expr *RetV
   if (!stackE)
     return; // Nothing suspicious was found.
 
+  // Parameters are initalized in the calling scope, so taking the address
+  // of a parameter reference doesn't need a warning.
+  for (auto *DRE : refVars)
+    if (isa<ParmVarDecl>(DRE->getDecl()))
+      return;
+
   SourceLocation diagLoc;
   SourceRange diagRange;
   if (refVars.empty()) {
@@ -6595,6 +6601,13 @@ CheckReturnStackAddr(Sema &S, Expr *RetV
   } else if (isa<AddrLabelExpr>(stackE)) { // address of label.
     S.Diag(diagLoc, diag::warn_ret_addr_label) << diagRange;
   } else { // local temporary.
+    // If there is an LValue->RValue conversion, then the value of the
+    // reference type is used, not the reference.
+    if (auto *ICE = dyn_cast<ImplicitCastExpr>(RetValExp)) {
+      if (ICE->getCastKind() == CK_LValueToRValue) {
+        return;
+      }
+    }
     S.Diag(diagLoc, diag::warn_ret_local_temp_addr_ref)
      << lhsType->isReferenceType() << diagRange;
   }

Modified: cfe/trunk/test/SemaCXX/return-stack-addr-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/return-stack-addr-2.cpp?rev=277889&r1=277888&r2=277889&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/return-stack-addr-2.cpp (original)
+++ cfe/trunk/test/SemaCXX/return-stack-addr-2.cpp Fri Aug  5 18:24:47 2016
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
 
 namespace PR26599 {
 template <typename>
@@ -20,3 +19,66 @@ void *&pointer() {
 }
 }
 
+namespace LocalTemporary {
+
+template <class T>
+class QMap {
+public:
+  T value(const T &t = T()) const {
+    return t;
+  }
+};
+
+struct A {};
+
+void test() {
+  QMap<A *> map;
+  map.value();
+}
+
+typedef int* ptr;
+ptr int1(const ptr &p = ptr()) {
+  return (p);
+}
+
+ptr int2(const ptr &p = nullptr) {
+  return p;
+}
+
+ptr int3() {
+  const ptr &p = ptr();
+  return p;
+}
+
+const int *int4(const int &x = 5) {
+  return &x;
+}
+
+const int *int5(const int &x) {
+  return &x;
+}
+
+const int *int6() {
+  const int &x = 11;  //expected-note{{binding reference variable 'x' here}}
+  return &x;  //expected-warning{{returning address of local temporary object}}
+}
+
+const int *int7(int x) {
+  const int &x2 = x;  // expected-note{{binding reference variable 'x2' here}}
+  const int &x3 = x2;
+  return &x2;  //  expected-warning{{address of stack memory associated with local variable 'x' returned}}
+}
+
+const int *int8(const int &x = 5) {
+  const int &x2 = x;
+  const int &x3 = x2;
+  return &x2;
+}
+
+const int *int9() {
+  const int &x = 5;  // expected-note{{binding reference variable 'x' here}}
+  const int &x2 = x;  // expected-note{{binding reference variable 'x2' here}}
+  const int &x3 = x2;
+  return &x2;  // expected-warning{{returning address of local temporary object}}
+}
+}




More information about the cfe-commits mailing list