[cfe-dev] Mixed 32b/64b pointers in same translation unit

Reid Kleckner via cfe-dev cfe-dev at lists.llvm.org
Thu Feb 2 09:04:52 PST 2017


I think you're on the right track with address spaces, but you need to
modify clang/lib/Basic/Targets.cpp to override TargetInfo::getPointerWidthV
to give a different size.

If you go down this road, consider making __ptr32 and __ptr64 work better.
MSVC accepts this code but clang rejects:

struct Foo { int *__ptr32 p; };
int *__ptr32 p;
int *__ptr64 q;
static_assert(sizeof(Foo) == 4, "Foo");
static_assert(sizeof(p) == 4, "p");
static_assert(sizeof(q) == 8, "q");

On Thu, Feb 2, 2017 at 8:05 AM, Patrik Eklöf via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Dear community,
>
>
>
> I am looking at trying to use clang in such a way that it is possible to
> use both 32-bit and 64-bit pointers in the same translation unit. Is this
> currently supported?
>
>
>
> I would like to enable it on a per-pointer basis, and it would be ideal if
> it is part of the type. I am thinking that one would do something like…
>
>
>
> [[ptr_32]] int* p;
>
>
>
> …or the like to tell the compiler specifically that it is a 32-bit pointer
> (the rest will be 64-bit). I am compiling to a 64-bit target, so all
> pointers should natively be 64-bit.
>
>
>
> I’ve been looking over the source a little, and see references to address
> space and an attribute __address_space__ that enables one to choose the
> address space for variables. It seems that depending on the address space,
> different sizes for pointers can be used. I tried modifying the
> DataLayout::reset function (I realize I should probably modify the targets
> instead of the layout class itself) to add another entry to the Pointers
> vector:
>
>
>
> setPointerAlignment(0, 8, 8, 8);
>
> setPointerAlignment(4, 4, 4, 4);
>
>
>
> …and using the address space extension to pick out the right size for some
> pointers:
>
>
>
> __attribute__((address_space(0))) int* HiIAmA64BitPtr{
> (int*)0xFFFF'FFFF'FFFF'FFFF };
>
> __attribute__((address_space(4))) int* HiIAmA32BitPtr{
> (__attribute__((address_space(4))) int*)0xFFFF'FFFF'FFFF'FFFF };
>
>
>
> But that did not appear to work. When running the code and printing the
> size of the variables, I see that they are both 8 bytes:
>
>
>
> std::cout << "Size of 64-bit ptr: " << sizeof(HiIAmA64BitPtr) <<
> std::endl; // Prints 8
>
> std::cout << "Size of 32-bit ptr: " << sizeof(HiIAmA32BitPtr) <<
> std::endl; // Prints 8
>
>
>
> Furthermore, for some strange reason, if I print the LLVM IR using clang++
> -S -emit-llvm, I see that all pointers seem to be 32 bits long even without
> using the address space extension. Yet, a long long variable (called Test
> here) has a 64-bit size:
>
>
>
> target triple = "x86_64-pc-windows-msvc19.0.0"
>
>
>
> @"\01?HiIAmA64BitPtr@@3PEAHEA" = global i32* inttoptr (i64 -1 to i32*),
> align 8
>
> @"\01?HiIAmA32BitPtr@@3PEAHEA" = global i32 addrspace(4)* inttoptr (i64
> -1 to i32 addrspace(4)*), align 8
>
> @"\01?g_Test@@3_KA" = global i64 0, align 8
>
>
>
> This seems very odd to me. Can someone point me in the right direction on
> how to approach this?
>
>
>
> My command line for compiling:
>
>
>
> clang++ "Test.cpp" -std=c++1z -Wall -fms-compatibility-version=19 -c -o
> Test.o && "link.exe" -out:Test.exe -defaultlib:libcmt -nologo Test.o
>
>
>
> (For some reason, clang is unable to invoke the linker correctly on its
> own.)
>
> Regards,
> Patrik Eklöf
>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170202/9e4fe316/attachment.html>


More information about the cfe-dev mailing list