[LLVMbugs] [Bug 9277] New: Clang generates duplicated Win32 APIs definitions, causing linking error

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sun Feb 20 21:28:53 PST 2011


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

           Summary: Clang generates duplicated Win32 APIs definitions,
                    causing linking error
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Frontend
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: art.oriented at gmail.com
                CC: llvmbugs at cs.uiuc.edu


Created an attachment (id=6194)
 --> (http://llvm.org/bugs/attachment.cgi?id=6194)
An example of the bitcode of a.c

I'm using clang on Windows. This bug can be reproduced by the following steps:
(1) Make two files: say a.c and b.c.
(2) Both of the files include <windows.h>
(3) Both files call a simple Win32 API such as GetTickCount();
(4) Try to compile (w/o optimizations), then we will get a bunch of duplication
linking error.

==========
error LNK2005: _Int64ShllMod32 at 12 already defined in cc-000000.o
error LNK2005: _Int64ShraMod32 at 12 already defined in cc-000000.o
error LNK2005: _Int64ShrlMod32 at 12 already defined in cc-000000.o
error LNK2005: _InterlockedBitTestAndSet already defined in cc-000000.o
error LNK2005: _InterlockedBitTestAndReset already defined in cc-000000.o
error LNK2005: _InterlockedBitTestAndComplement already defined in cc-000000.o
error LNK2005: _MemoryBarrier already defined in cc-000000.o
error LNK2005: _ReadPMC already defined in cc-000000.o
error LNK2005: _ReadTimeStampCounter already defined in cc-000000.o
error LNK2005: _DbgRaiseAssertionFailure already defined in cc-000000.o
error LNK2005: _HEAP_MAKE_TAG_FLAGS already defined in cc-000000.o
error LNK2005: _RtlSecureZeroMemory already defined in cc-000000.o
error LNK2005: _TpInitializeCallbackEnviron already defined in cc-000000.o
error LNK2005: _TpSetCallbackThreadpool already defined in cc-000000.o
error LNK2005: _TpSetCallbackCleanupGroup already defined in cc-000000.o
error LNK2005: _TpSetCallbackActivationContext already defined in cc-000000.o
error LNK2005: _TpSetCallbackNoActivationContext already defined in cc-000000.o
error LNK2005: _TpSetCallbackLongFunction already defined in cc-000000.o
error LNK2005: _TpSetCallbackRaceWithDll already defined in cc-000000.o
error LNK2005: _TpSetCallbackFinalizationCallback already defined in
cc-000000.o
error LNK2005: _TpSetCallbackPriority already defined in cc-000000.o
error LNK2005: _TpSetCallbackPersistent already defined in cc-000000.o
error LNK2005: _TpDestroyCallbackEnviron already defined in cc-000000.o
error LNK2005: _InterlockedAnd64 already defined in cc-000000.o
error LNK2005: _InterlockedOr64 already defined in cc-000000.o
error LNK2005: _InterlockedXor64 already defined in cc-000000.o
error LNK2005: _InterlockedIncrement64 already defined in cc-000000.o
error LNK2005: _InterlockedDecrement64 already defined in cc-000000.o
error LNK2005: _InterlockedExchange64 already defined in cc-000000.o
error LNK2005: _InterlockedExchangeAdd64 already defined in cc-000000.o
error LNK2005: _InitializeThreadpoolEnvironment already defined in cc-000000.o
error LNK2005: _SetThreadpoolCallbackPool already defined in cc-000000.o
error LNK2005: _SetThreadpoolCallbackCleanupGroup already defined in
cc-000000.o
error LNK2005: _SetThreadpoolCallbackRunsLong already defined in cc-000000.o
error LNK2005: _SetThreadpoolCallbackLibrary already defined in cc-000000.o
error LNK2005: _SetThreadpoolCallbackPriority already defined in cc-000000.o
error LNK2005: _SetThreadpoolCallbackPersistent already defined in cc-000000.o
error LNK2005: _DestroyThreadpoolEnvironment already defined in cc-000000.o
error LNK2005: _HRESULT_FROM_WIN32 already defined in cc-000000.o
==========

(Both MSVC's link.exe and gcc linker generate the errors. So, it's the problem
of the front end.)

I checked how the bitcode was generated by clang when <windows.h> is included.
Then, each bit code contains a number of Win32 API's definitions (while many of
them are inline hints). For example:

======== 
define x86_stdcallcc i64 @Int64ShraMod32(i64 %Value, i32 %ShiftCount) nounwind
inlinehint {
  %1 = alloca i64, align 8
  %2 = alloca i64, align 8
  %3 = alloca i32, align 4
  store i64 %Value, i64* %2, align 8
  call void @llvm.dbg.declare(metadata !{i64* %2}, metadata !97), !dbg !98
  store i32 %ShiftCount, i32* %3, align 4
  call void @llvm.dbg.declare(metadata !{i32* %3}, metadata !99), !dbg !100
  call void asm sideeffect "/*FIXME: not done*/",
"~{dirflag},~{fpsr},~{flags}"() nounwind, !dbg !101, !srcloc !95
  %4 = load i64* %1, !dbg !103
  ret i64 %4, !dbg !103
=======

These definitions exist in every object files that use <windows.h>, resulting
in duplication linking errors.

My current workaround is killing these functions' definition via a module pass
where just call Function::deleteBody().

I don't have deep knowledge of front end, so I can't figure it out the reason
further.


I'm attaching the bitcode of a simple file:
=========================
// a.c
#include <windows.h>

unsigned int foo()
{
  return GetTickCount();
}
=========================

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