[Bug c++/64372] Spurious warning with throw in ternary operator returning const reference

manu at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Dec 22 00:49:00 GMT 2014


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};
    }
}


More information about the Gcc-bugs mailing list