Skip to content

Commit c9ce161

Browse files
committed
Add backport for checking opaque pointer types
1 parent 1d17b26 commit c9ce161

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

backports.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,16 @@ LLVMMemoryBufferRef LLVMGoWriteThinLTOBitcodeToMemoryBuffer(LLVMModuleRef M) {
4848
#endif
4949
return llvm::wrap(llvm::MemoryBuffer::getMemBufferCopy(OS.str()).release());
5050
}
51+
52+
#if LLVM_VERSION_MAJOR < 15
53+
54+
// This is backported because version 14 supports opaque
55+
// pointers but I presume if you try to access the element
56+
// type it will crash. So this backport prevents that by
57+
// allowing to check if the pointer is opaque before trying
58+
// to access the element type.
59+
LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty) {
60+
return llvm::unwrap<llvm::Type>(Ty)->isOpaquePointerTy();
61+
}
62+
63+
#endif

backports.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ LLVMMemoryBufferRef LLVMGoWriteThinLTOBitcodeToMemoryBuffer(LLVMModuleRef M);
1414
LLVMMetadataRef LLVMGoDIBuilderCreateExpression(LLVMDIBuilderRef Builder,
1515
uint64_t *Addr, size_t Length);
1616

17+
#if LLVM_VERSION_MAJOR < 15
18+
/**
19+
* Determine whether a pointer is opaque.
20+
*
21+
* True if this is an instance of an opaque PointerType.
22+
*
23+
* @see llvm::Type::isOpaquePointerTy()
24+
*/
25+
LLVMBool LLVMPointerTypeIsOpaque(LLVMTypeRef Ty);
26+
27+
#endif
28+
29+
1730
#ifdef __cplusplus
1831
}
1932
#endif /* defined(__cplusplus) */

ir.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ package llvm
1919
#include <stdlib.h>
2020
*/
2121
import "C"
22-
import "unsafe"
23-
import "errors"
22+
import (
23+
"errors"
24+
"unsafe"
25+
)
2426

2527
type (
2628
// We use these weird structs here because *Ref types are pointers and
@@ -700,8 +702,23 @@ func VectorType(elementType Type, elementCount int) (t Type) {
700702
return
701703
}
702704

703-
func (t Type) IsPointerOpaque() bool { return C.LLVMPointerTypeIsOpaque(t.C) != 0 }
704-
func (t Type) ElementType() (rt Type) { rt.C = C.LLVMGetElementType(t.C); return }
705+
// IsPointerOpaque checks if the pointer is an opaque pointer.
706+
//
707+
// see llvm::Type::isOpaquePointerTy()
708+
func (t Type) IsPointerOpaque() bool { return C.LLVMPointerTypeIsOpaque(t.C) != 0 }
709+
710+
// ElementType returns the type of the element for arrays, pointers and vectors.
711+
//
712+
// see llvm::SequentialType::getElementType()
713+
func (t Type) ElementType() (rt Type) {
714+
if t.IsPointerOpaque() {
715+
// avoid segfault
716+
return Type{}
717+
}
718+
rt.C = C.LLVMGetElementType(t.C)
719+
return
720+
}
721+
705722
func (t Type) ArrayLength() int { return int(C.LLVMGetArrayLength(t.C)) }
706723
func (t Type) PointerAddressSpace() int { return int(C.LLVMGetPointerAddressSpace(t.C)) }
707724
func (t Type) VectorSize() int { return int(C.LLVMGetVectorSize(t.C)) }

0 commit comments

Comments
 (0)