namespace ParameterScopes { const int k = 42; constexpr const int &ObscureTheTruth(const int &a) { return a; } // expected-note 3{{reference to 'a' cannot be returned from a constexpr function}} constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}} return ObscureTheTruth(b ? a : k); // expected-note 2{{in call to 'ObscureTheTruth(a)'}} } static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{in call to 'MaybeReturnJunk(1, 0)'}} constexpr const int MaybeReturnNonstaticRef(bool b, const int a) { // expected-note {{here}} // If ObscureTheTruth returns a reference to 'a', the result is not a // constant expression even though 'a' is still in scope. return ObscureTheTruth(b ? a : k); // expected-note {{in call to 'ObscureTheTruth(a)'}} } static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok constexpr int b = MaybeReturnNonstaticRef(true, 0); // expected-error {{constant expression}} expected-note {{in call to 'MaybeReturnNonstaticRef(1, 0)'}} constexpr int InternalReturnJunk(int n) { // FIXME: We should reject this: it never produces a constant expression. return MaybeReturnJunk(true, n); // expected-note {{in call to 'MaybeReturnJunk(1, 0)'}} } constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}} constexpr int LToR(int &n) { return n; } constexpr int GrabCallersArgument(bool which, int a, int b) { return LToR(which ? b : a); } static_assert(GrabCallersArgument(false, 1, 2) == 1, ""); static_assert(GrabCallersArgument(true, 4, 8) == 8, ""); }
namespace ParameterScopes { const int k = 42; constexpr const int &ObscureTheTruth(const int &a) { return a; } constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}} return ObscureTheTruth(b ? a : k); } static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{read of variable whose lifetime has ended}} constexpr const int MaybeReturnNonstaticRef(bool b, const int a) { return ObscureTheTruth(b ? a : k); } static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok constexpr int b = MaybeReturnNonstaticRef(true, 0); // ok constexpr int InternalReturnJunk(int n) { return MaybeReturnJunk(true, n); // expected-note {{read of variable whose lifetime has ended}} } constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}} constexpr int LToR(int &n) { return n; } constexpr int GrabCallersArgument(bool which, int a, int b) { return LToR(which ? b : a); } static_assert(GrabCallersArgument(false, 1, 2) == 1, ""); static_assert(GrabCallersArgument(true, 4, 8) == 8, ""); }