[LLVMbugs] [Bug 7414] New: Clang loses function attributes between declaration and definition

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Fri Jun 18 14:33:22 PDT 2010


http://llvm.org/bugs/show_bug.cgi?id=7414

           Summary: Clang loses function attributes between declaration
                    and definition
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: dimitry at andric.com
                CC: llvmbugs at cs.uiuc.edu


While chasing a crash bug in FreeBSD's grep, I ran into a problem, which
seems to be related to bug 7025 (although that is about C++).

FreeBSD's grep is based on a quite old GNU grep and regex lib, the
latter using __attribute((regparm(3)),stdcall)) for quite a number of
'internal' functions.

After much debugging, it turned out clang generated completely bogus
argument passing for some of those functions.  This was because the
functions were declared with said attribute, but defined later in the
file without it.  E.g.:

  int re_string_realloc_buffers(re_string_t *pstr, int new_buf_len)
    __attribute__((regparm(3), stdcall));

  [...]

  int
  re_string_realloc_buffers(pstr, new_buf_len)
  re_string_t *pstr;
  {
    [...]
  }

Clang then produces the following llvm definition of the function:

  define x86_stdcallcc i32 @re_string_realloc_buffers(%struct.anon*
  nocapture %pstr, i32 %new_buf_len) nounwind

whereas, if you additionally add the attribute to the function
definition, e.g. use:

  int __attribute__((regparm(3), stdcall)) 
  re_string_realloc_buffers(pstr, new_buf_len)
  re_string_t *pstr;
  {
    [...]
  }

then clang produces:

  define x86_stdcallcc i32 @re_string_realloc_buffers(%struct.anon*
  inreg nocapture %pstr, i32 inreg %new_buf_len) nounwind

which is correct.  So the regparm attribute is dropped, but NOT the
stdcall attribute.  This is most likely because the calling convention
is handled differently from the other function attributes.

A convenient minimal testcase is the following:

  int __attribute__((regparm(3))) foo(int i);

  int
  #ifdef ADD_ATTR_TO_DEF
  __attribute__((regparm(3)))
  #endif
  foo(int i)
  {
    return 42;
  }

which gives the expected result:

  define i32 @foo(i32 inreg %i) nounwind

when ADD_ATTR_TO_DEF is defined, otherwise:

  define i32 @foo(i32 %i) nounwind

which is not expected.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list