diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1839,41 +1839,31 @@ V); if (PointerType *PTy = dyn_cast(Ty)) { - SmallPtrSet Visited; - if (!PTy->getElementType()->isSized(&Visited)) { - Assert(!Attrs.hasAttribute(Attribute::ByVal) && - !Attrs.hasAttribute(Attribute::ByRef) && - !Attrs.hasAttribute(Attribute::InAlloca) && - !Attrs.hasAttribute(Attribute::Preallocated), - "Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not " - "support unsized types!", - V); + if (Attrs.hasAttribute(Attribute::ByVal)) { + SmallPtrSet Visited; + Assert(Attrs.getByValType()->isSized(&Visited), + "Attribute 'byval' does not support unsized types!", V); } - if (!isa(PTy->getElementType())) - Assert(!Attrs.hasAttribute(Attribute::SwiftError), - "Attribute 'swifterror' only applies to parameters " - "with pointer to pointer type!", - V); - if (Attrs.hasAttribute(Attribute::ByRef)) { - Assert(Attrs.getByRefType() == PTy->getElementType(), - "Attribute 'byref' type does not match parameter!", V); + SmallPtrSet Visited; + Assert(Attrs.getByRefType()->isSized(&Visited), + "Attribute 'byref' does not support unsized types!", V); } - - if (Attrs.hasAttribute(Attribute::ByVal) && Attrs.getByValType()) { - Assert(Attrs.getByValType() == PTy->getElementType(), - "Attribute 'byval' type does not match parameter!", V); + if (Attrs.hasAttribute(Attribute::InAlloca)) { + SmallPtrSet Visited; + Assert(Attrs.getInAllocaType()->isSized(&Visited), + "Attribute 'inalloca' does not support unsized types!", V); } - if (Attrs.hasAttribute(Attribute::Preallocated)) { - Assert(Attrs.getPreallocatedType() == PTy->getElementType(), - "Attribute 'preallocated' type does not match parameter!", V); - } - - if (Attrs.hasAttribute(Attribute::InAlloca)) { - Assert(Attrs.getInAllocaType() == PTy->getElementType(), - "Attribute 'inalloca' type does not match parameter!", V); + SmallPtrSet Visited; + Assert(Attrs.getPreallocatedType()->isSized(&Visited), + "Attribute 'preallocated' does not support unsized types!", V); } + if (!PTy->isOpaque() && !isa(PTy->getElementType())) + Assert(!Attrs.hasAttribute(Attribute::SwiftError), + "Attribute 'swifterror' only applies to parameters " + "with pointer to pointer type!", + V); } else { Assert(!Attrs.hasAttribute(Attribute::ByVal), "Attribute 'byval' only applies to parameters with pointer type!", diff --git a/llvm/test/Assembler/invalid-byval-type1.ll b/llvm/test/Assembler/invalid-byval-type1.ll deleted file mode 100644 --- a/llvm/test/Assembler/invalid-byval-type1.ll +++ /dev/null @@ -1,4 +0,0 @@ -; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s - -; CHECK: Attribute 'byval' type does not match parameter! -declare void @foo(i32* byval(i8)) diff --git a/llvm/test/Assembler/invalid-byval-type3.ll b/llvm/test/Assembler/invalid-byval-type3.ll --- a/llvm/test/Assembler/invalid-byval-type3.ll +++ b/llvm/test/Assembler/invalid-byval-type3.ll @@ -1,4 +1,4 @@ ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s -; CHECK: Attributes 'byval'{{.*}} do not support unsized types! +; CHECK: Attribute 'byval' does not support unsized types! declare void @foo(void()* byval(void())) diff --git a/llvm/test/Verifier/byref.ll b/llvm/test/Verifier/byref.ll --- a/llvm/test/Verifier/byref.ll +++ b/llvm/test/Verifier/byref.ll @@ -1,20 +1,8 @@ ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s -; CHECK: Attribute 'byref' type does not match parameter! -; CHECK-NEXT: void (i32*)* @byref_mismatched_pointee_type0 -define void @byref_mismatched_pointee_type0(i32* byref(i8)) { - ret void -} - -; CHECK: Attribute 'byref' type does not match parameter! -; CHECK-NEXT: void (i8*)* @byref_mismatched_pointee_type1 -define void @byref_mismatched_pointee_type1(i8* byref(i32)) { - ret void -} - %opaque.ty = type opaque -; CHECK: Attributes 'byval', 'byref', 'inalloca', and 'preallocated' do not support unsized types! +; CHECK: Attribute 'byref' does not support unsized types! ; CHECK-NEXT: void (%opaque.ty*)* @byref_unsized define void @byref_unsized(%opaque.ty* byref(%opaque.ty)) { ret void diff --git a/llvm/test/Verifier/inalloca1.ll b/llvm/test/Verifier/inalloca1.ll --- a/llvm/test/Verifier/inalloca1.ll +++ b/llvm/test/Verifier/inalloca1.ll @@ -16,17 +16,11 @@ ; CHECK: Attributes {{.*}} are incompatible declare void @f(void ()* inalloca(void()) %p) -; CHECK: do not support unsized types +; CHECK: Attribute 'inalloca' does not support unsized types declare void @g(i32* inalloca(i32) %p, i32 %p2) ; CHECK: inalloca isn't on the last parameter! -; CHECK: Attribute 'inalloca' type does not match parameter! -; CHECK-NEXT: void (i32*)* @inalloca_mismatched_pointee_type0 -define void @inalloca_mismatched_pointee_type0(i32* inalloca(i8)) { - ret void -} - ; CHECK: Wrong types for attribute: ; CHECK-NEXT: void (i8)* @inalloca_not_pointer define void @inalloca_not_pointer(i8 byref(i8)) { diff --git a/llvm/test/Verifier/opaque-ptr-invalid.ll b/llvm/test/Verifier/opaque-ptr-invalid.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Verifier/opaque-ptr-invalid.ll @@ -0,0 +1,7 @@ +; RUN: not opt -verify < %s 2>&1 | FileCheck %s + +; CHECK: Attribute 'inalloca' does not support unsized types! +; CHECK-NEXT: void (ptr)* @f +define void @f(ptr inalloca(token)) { + ret void +} diff --git a/llvm/test/Verifier/preallocated-invalid.ll b/llvm/test/Verifier/preallocated-invalid.ll --- a/llvm/test/Verifier/preallocated-invalid.ll +++ b/llvm/test/Verifier/preallocated-invalid.ll @@ -81,15 +81,6 @@ ret void } -; CHECK: Attribute 'preallocated' type does not match parameter -define void @preallocated_attribute_type_mismatch() { - %cs = call token @llvm.call.preallocated.setup(i32 1) - %x = call i8* @llvm.call.preallocated.arg(token %cs, i32 0) preallocated(i32) - %y = bitcast i8* %x to i32* - call void @foo1(i32* preallocated(i8) %y) ["preallocated"(token %cs)] - ret void -} - ; CHECK: preallocated operand either requires a preallocated bundle or the call to be musttail define void @preallocated_require_bundle() { %cs = call token @llvm.call.preallocated.setup(i32 1)