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}} +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits