[LLVMbugs] [Bug 10647] New: memcpy called when memory areas of source and destination overlap

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Fri Aug 12 11:56:43 PDT 2011


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

           Summary: memcpy called when memory areas of source and
                    destination overlap
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: ahatanak at gmail.com
                CC: llvmbugs at cs.uiuc.edu


Created an attachment (id=7062)
 --> (http://llvm.org/bugs/attachment.cgi?id=7062)
source file

pr22237 taken from gcc test-suite fails.

$ clang pr22237.c pr22237-lib.c main.c  -w  -O0   -fPIC  -lm   -o pr22237.x0
$ ./pr22237.x0
Aborted

Running gdb reveals that it aborts when the memcpy function defined in
pr22237-lib.c finds that dst and src ares are not disjoint: 

(gdb) 
#2  0x0000000000400865 in memcpy (dst=0x60104c, src=0x601048, n=256)
    at pr22237-lib.c:20
20        abort ();

(gdb) up
#3  0x00000000004007f8 in rp ()
    at pr22237.c:10
10    static inline struct s rp (void) { return *p; }


The problem seems to be that function rp calls memcpy to copy *p to %agg.result
without checking whether the source and destination areas overlap.

(line 44 in pr22237.c)
static inline struct s rp (void) { return *p; }

$ clang pr22237.c -emit-llvm -S   -w  -O0   -fPIC  -lm -o - 
...
define internal void @rp(%struct.s* sret %agg.result) nounwind uwtable
inlinehint {
entry:
  %tmp = load %struct.s** @p, align 8
  %tmp1 = bitcast %struct.s* %agg.result to i8*
  %tmp2 = bitcast %struct.s* %tmp to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp1, i8* %tmp2, i64 256, i32 1, i1
false)
  ret void
}

Note that the test also fails without the memcpy defined in pr22237-lib.c:
$ clang pr22237.c main.c  -w  -O0   -fPIC  -lm   -o pr22237.x0
$ ./pr22237.x0
Aborted

I also studied the assembly code generated with gcc.
x86-gcc uses memmove which checks overlaps.
mips-gcc uses memcpy but does something equivalent to the following to avoid
abortion:

tmp = rp()
*q = tmp

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