http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54197
Bug #: 54197 Summary: [4.7/4.8 regression] Lifetime of reference not properly extended Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: ppluzhni...@google.com We've noticed this with 4.7 branch, confirmed present in current trunk (rev. 190209). When calling a static member function returning an object (string below) through an unnamed function pointer, and binding the result to a reference, the lifetime of the returned temporary is not properly extended. --- cut --- #include <stdlib.h> #include <string.h> #include <stdio.h> struct string { string(const char *s) { s_ = strdup(s); } ~string() { memset((void*)s_, 'a', strlen(s_)); } string(const string& rhs) { s_ = strdup(rhs.s_); } string& operator=(const string& rhs) { if (&rhs != this) { free((void*)s_); s_ = strdup(rhs.s_); } return *this; } const char *c_str() const { return s_; } const char *s_; }; struct Foo { static string foo() { return "abcd"; } }; Foo foo_g; struct scoped_ptr { Foo* operator->() const { return &foo_g; } Foo* get() const { return &foo_g; } }; Foo *get() { return &foo_g; } int main() { scoped_ptr f; const string& ref1 = f->foo(); // BAD const string& ref2 = f.get()->foo(); // BAD const string& ref3 = get()->foo(); // BAD const string& ref4 = Foo::foo(); // OK Foo *pf = f.get(); const string& ref5 = pf->foo(); // OK printf("ref1: %p (%s)\n", ref1.c_str(), ref1.c_str()); printf("ref2: %p (%s)\n", ref2.c_str(), ref2.c_str()); printf("ref3: %p (%s)\n", ref3.c_str(), ref3.c_str()); printf("ref4: %p (%s)\n", ref4.c_str(), ref4.c_str()); printf("ref5: %p (%s)\n", ref5.c_str(), ref5.c_str()); } --- cut --- Result from gcc-4.6: ref1: 0x5a8030 (abcd) ref2: 0x5a8070 (abcd) ref3: 0x5a80b0 (abcd) ref4: 0x5a80d0 (abcd) ref5: 0x5a80f0 (abcd) Result from gcc-4.7 / 4.8 ref1: 0xe18010 (aaaa) << BUG ref2: 0xe18030 (aaaa) << BUG ref3: 0xe18050 (aaaa) << BUG ref4: 0xe18070 (abcd) ref5: 0xe18090 (abcd) Changing Foo::foo to be non-static (and commenting out ref4), the bug disappears: ref1: 0x1eb3010 (abcd) ref2: 0x1eb3030 (abcd) ref3: 0x1eb3050 (abcd) ref5: 0x1eb3070 (abcd) Google ref: b/6946758