Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2366,6 +2366,9 @@ "cannot use __auto_type with initializer list in C">; def err_auto_bitfield : Error< "cannot pass bit-field as __auto_type initializer in C">; +def warn_auto_creates_copy : Warning< + "variable %0 is a value copy of call's lvalue return; did you mean '&'?">, + InGroup>, DefaultIgnore; // C++1y decltype(auto) type def err_decltype_auto_invalid : Error< Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -12255,8 +12255,17 @@ } Init = Res.get(); + QualType OrigTy = VDecl->getType(); if (DeduceVariableDeclarationType(VDecl, DirectInit, Init)) return; + + if (!DirectInit && isa(Init) + && OrigTy->isUndeducedAutoType() + && OrigTy.isLocalConstQualified() + && Init->getValueKind() == VK_LValue + && isa(Init->getType())) + Diag(VDecl->getLocation(), diag::warn_auto_creates_copy) + << VDecl->getDeclName(); } // dllimport cannot be used on variable definitions. Index: clang/test/SemaCXX/warn-auto-value-copy.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/warn-auto-value-copy.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -verify -fsyntax-only -Wauto-by-value-copy %s + +struct Big { + Big (Big const &) noexcept; + unsigned r[50]; +}; + +Big &Fn (); +Big &(*P) (); + +Big VFn (); +int &SR(); + +void f () { + auto const r = Fn(); // expected-warning{{is a value copy of}} + auto const s = P(); // expected-warning{{is a value copy of}} + + auto const t (Fn()); // paren-init + auto const u {P()}; // brace-init + + auto const v = VFn(); // by-value + auto const w = SR(); // non-class +}