llvm.org GIT mirror llvm / e1433f2
Noting and enforcing that GC intrinsics are valid only within a function with GC. This will catch the error when the inliner inlines a function with GC into a caller with no GC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45350 91177308-0d34-0410-b5e6-96231b3b80d8 Gordon Henriksen 12 years ago
4 changed file(s) with 56 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
39943994
39953995

At runtime, a call to this intrinsics stores a null pointer into the "ptrloc"

39963996 location. At compile-time, the code generator generates information to allow
3997 the runtime to find the pointer at GC safe points.
3998

3997 the runtime to find the pointer at GC safe points. The 'llvm.gcroot'
3998 intrinsic may only be used in a function which specifies a GC
3999 algorithm.

39994000
40004001
40014002
40304031
40314032

The 'llvm.gcread' intrinsic has the same semantics as a load

40324033 instruction, but may be replaced with substantially more complex code by the
4033 garbage collector runtime, as needed.

4034 garbage collector runtime, as needed. The 'llvm.gcread' intrinsic
4035 may only be used in a function which specifies a GC
4036 algorithm.

40344037
40354038
40364039
40654068
40664069

The 'llvm.gcwrite' intrinsic has the same semantics as a store

40674070 instruction, but may be replaced with substantially more complex code by the
4068 garbage collector runtime, as needed.

4071 garbage collector runtime, as needed. The 'llvm.gcwrite' intrinsic
4072 may only be used in a function which specifies a GC
4073 algorithm.

40694074
40704075
40714076
11661166 switch (ID) {
11671167 default:
11681168 break;
1169 case Intrinsic::gcroot: {
1170 Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
1171 *PtrPtrTy = PointerType::getUnqual(PtrTy);
1172 Assert1(CI.getOperand(1)->getType() == PtrPtrTy,
1173 "Intrinsic parameter #1 is not i8**.", &CI);
1174 Assert1(CI.getOperand(2)->getType() == PtrTy,
1175 "Intrinsic parameter #2 is not i8*.", &CI);
1176 Assert1(
1177 isa(IntrinsicInst::StripPointerCasts(CI.getOperand(1))),
1178 "llvm.gcroot parameter #1 must be an alloca.",
1179 &CI);
1180 Assert1(isa(CI.getOperand(2)),
1181 "llvm.gcroot parameter #2 must be a constant.", &CI);
1182 } break;
1183 case Intrinsic::gcwrite: {
1184 Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
1185 *PtrPtrTy = PointerType::getUnqual(PtrTy);
1186 Assert1(CI.getOperand(1)->getType() == PtrTy,
1187 "Intrinsic parameter #1 is not a i8*.", &CI);
1188 Assert1(CI.getOperand(2)->getType() == PtrTy,
1189 "Intrinsic parameter #2 is not a i8*.", &CI);
1190 Assert1(CI.getOperand(3)->getType() == PtrPtrTy,
1191 "Intrinsic parameter #3 is not a i8**.", &CI);
1192 } break;
1169 case Intrinsic::gcroot:
1170 case Intrinsic::gcwrite:
11931171 case Intrinsic::gcread: {
11941172 Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
11951173 *PtrPtrTy = PointerType::getUnqual(PtrTy);
1196 Assert1(CI.getOperand(1)->getType() == PtrTy,
1197 "Intrinsic parameter #1 is not a i8*.", &CI);
1198 Assert1(CI.getOperand(2)->getType() == PtrPtrTy,
1199 "Intrinsic parameter #2 is not a i8**.", &CI);
1174
1175 switch (ID) {
1176 default:
1177 break;
1178 case Intrinsic::gcroot:
1179 Assert1(CI.getOperand(1)->getType() == PtrPtrTy,
1180 "Intrinsic parameter #1 is not i8**.", &CI);
1181 Assert1(CI.getOperand(2)->getType() == PtrTy,
1182 "Intrinsic parameter #2 is not i8*.", &CI);
1183 Assert1(isa(
1184 IntrinsicInst::StripPointerCasts(CI.getOperand(1))),
1185 "llvm.gcroot parameter #1 must be an alloca.", &CI);
1186 Assert1(isa(CI.getOperand(2)),
1187 "llvm.gcroot parameter #2 must be a constant.", &CI);
1188 break;
1189 case Intrinsic::gcwrite:
1190 Assert1(CI.getOperand(1)->getType() == PtrTy,
1191 "Intrinsic parameter #1 is not a i8*.", &CI);
1192 Assert1(CI.getOperand(2)->getType() == PtrTy,
1193 "Intrinsic parameter #2 is not a i8*.", &CI);
1194 Assert1(CI.getOperand(3)->getType() == PtrPtrTy,
1195 "Intrinsic parameter #3 is not a i8**.", &CI);
1196 break;
1197 case Intrinsic::gcread:
1198 Assert1(CI.getOperand(1)->getType() == PtrTy,
1199 "Intrinsic parameter #1 is not a i8*.", &CI);
1200 Assert1(CI.getOperand(2)->getType() == PtrPtrTy,
1201 "Intrinsic parameter #2 is not a i8**.", &CI);
1202 break;
1203 }
1204
1205 Assert1(CI.getParent()->getParent()->hasCollector(),
1206 "Enclosing function does not specify a collector algorithm.",
1207 &CI);
12001208 } break;
12011209 case Intrinsic::init_trampoline:
12021210 Assert1(isa(IntrinsicInst::StripPointerCasts(CI.getOperand(2))),
11
22 %Env = type i8*
33
4 define void @.main(%Env) {
4 define void @.main(%Env) gc "shadow-stack" {
55 %Root = alloca %Env
66 call void @llvm.gcroot( %Env* %Root, %Env null )
77 unreachable
0 ; RUN: not llvm-as < %s
1
2 declare void @llvm.gcroot(i8**, i8*)
3
4 define void @f(i8* %x) {
5 %root = alloca i8*
6 call void @llvm.gcroot(i8** %root, i8* null)
7 store i8* %x, i8** %root
8 ret void
9 }