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()) {
} 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;
}
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
namespace PR26599 {
template <typename>
}
}
+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}}
+}
+}