https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64372
Manuel López-Ibáñez <manu at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |glisse at gcc dot gnu.org, | |manu at gcc dot gnu.org Known to fail| |4.9.2, 5.0 --- Comment #1 from Manuel López-Ibáñez <manu at gcc dot gnu.org> --- I think *p creates a temporary that only lasts until the end of the function, so the code is undefined. Probably even: const char& foz(const char* p) { return *p; } is undefined. However, G++ and Clang currently handles this as returning p: ;; Function const char& foz(const char*) (null) ;; enabled by -tree-original return <retval> = (const char &) NON_LVALUE_EXPR <p>; ;; Function const char& foo(const char*, const char*) (null) ;; enabled by -tree-original return <retval> = (const char &) (p != 0B ? NON_LVALUE_EXPR <p> : NON_LVALUE_EXPR <q>); ;; Function const char& fzz(const char*) (null) ;; enabled by -tree-original <<cleanup_point return <retval> = (const char &) &TARGET_EXPR <D.2338, p != 0B ? (char) *p : <<< Unknown tree: throw_expr <<cleanup_point TARGET_EXPR <D.2335, __cxa_allocate_exception (8)>;, *(const char * *) D.2335 = p;>>;, __cxa_throw (D.2335, (void *) &_ZTIPKc, 0B); >>>>;, 0>>; Note that in the testcase that throws, the gimple indicates that the reference is set to null even when not throwing, which leads to a segmentation fault. const char& fzz(const char*) (const char * p) { const charD.10 & D.2348; const charD.10 D.2338; charD.10 iftmp.1D.2349; voidD.45 * D.2335; [test.cc:18:24] if (pD.2330 != 0B) goto <D.2350>; else goto <D.2351>; <D.2350>: [test.cc:18:24] iftmp.1D.2349 = [test.cc:18:24] *pD.2330; goto <D.2352>; <D.2351>: [test.cc:18:24] # USE = anything # CLB = anything D.2335 = __cxa_allocate_exceptionD.2334 (8); [test.cc:18:24] try { [test.cc:18:24] [test.cc:18:24] MEM[(const charD.10 * *)D.2335] = pD.2330; } catch { [test.cc:18:24] # USE = anything # CLB = anything __cxa_free_exceptionD.2336 (D.2335); } [test.cc:18:24] # USE = anything # CLB = anything __cxa_throwD.2333 (D.2335, &_ZTIPKcD.2337, 0B); <D.2352>: [test.cc:18:24] D.2338 = iftmp.1D.2349; [test.cc:18:24] try { [test.cc:18:24] D.2348 = 0; [test.cc:18:24] return D.2348; } finally { [test.cc:18:24] D.2338 = {CLOBBER}; } }