Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -6284,9 +6284,7 @@ // If evaluating the argument has side-effects, we can't determine the size // of the object, and so we lower it to unknown now. CodeGen relies on us to // handle all cases where the expression has side-effects. - // Likewise, if Type is 3, we must handle this because CodeGen cannot give a - // conservatively correct answer in that case. - if (E->getArg(0)->HasSideEffects(Info.Ctx) || Type == 3) + if (E->getArg(0)->HasSideEffects(Info.Ctx)) return Success((Type & 2) ? 0 : -1, E); // Expression had no side effects, but we couldn't statically determine the Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -509,13 +509,12 @@ // figure out the object size in more complex cases. llvm::Type *ResType = ConvertType(E->getType()); - // LLVM only supports 0 and 2, make sure that we pass along that - // as a boolean. + // LLVM supports 0 - 3; pass that along as an int Value *Ty = EmitScalarExpr(E->getArg(1)); ConstantInt *CI = dyn_cast(Ty); assert(CI); - uint64_t val = CI->getZExtValue(); - CI = ConstantInt::get(Builder.getInt1Ty(), (val & 0x2) >> 1); + uint64_t Val = CI->getZExtValue(); + CI = ConstantInt::get(Int8Ty, Val & 3); // FIXME: Get right address space. llvm::Type *Tys[] = { ResType, Builder.getInt8PtrTy(0) }; Value *F = CGM.getIntrinsic(Intrinsic::objectsize, Tys); Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -534,10 +534,10 @@ // FIXME: Get object address space llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy }; llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys); - llvm::Value *Min = Builder.getFalse(); + llvm::Value *Type = Builder.getInt8(0); llvm::Value *CastAddr = Builder.CreateBitCast(Address, Int8PtrTy); llvm::Value *LargeEnough = - Builder.CreateICmpUGE(Builder.CreateCall(F, {CastAddr, Min}), + Builder.CreateICmpUGE(Builder.CreateCall(F, {CastAddr, Type}), llvm::ConstantInt::get(IntPtrTy, Size)); Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize)); } Index: test/CodeGen/catch-undef-behavior.c =================================================================== --- test/CodeGen/catch-undef-behavior.c +++ test/CodeGen/catch-undef-behavior.c @@ -41,7 +41,7 @@ // CHECK-COMMON: %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null // CHECK-COMMON: %[[I8PTR:.*]] = bitcast i32* %[[PTR]] to i8* - // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false) + // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i8 0) // CHECK-COMMON-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4 // CHECK-COMMON: %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64 Index: test/CodeGen/object-size.c =================================================================== --- test/CodeGen/object-size.c +++ test/CodeGen/object-size.c @@ -40,7 +40,7 @@ // CHECK-LABEL: define void @test5 void test5() { // CHECK: = load i8*, i8** @gp - // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false) + // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i8 0) strcpy(gp, "Hi there"); } @@ -227,16 +227,13 @@ // CHECK: @test23 void test23(struct Test22Ty *p) { - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i8 0) gi = __builtin_object_size(p, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i8 1) gi = __builtin_object_size(p, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i8 2) gi = __builtin_object_size(p, 2); - - // Note: this is currently fixed at 0 because LLVM doesn't have sufficient - // data to correctly handle type=3 - // CHECK: store i32 0 + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i8 3) gi = __builtin_object_size(p, 3); } @@ -244,39 +241,33 @@ // PR24493 -- ICE if __builtin_object_size called with NULL and (Type & 1) != 0 // CHECK @test24 void test24() { - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 0) gi = __builtin_object_size((void*)0, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 1) gi = __builtin_object_size((void*)0, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 2) gi = __builtin_object_size((void*)0, 2); - // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. - // Hopefully will be lowered properly in the future. - // CHECK: store i32 0 + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 3) gi = __builtin_object_size((void*)0, 3); } // CHECK @test25 void test25() { - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 0) gi = __builtin_object_size((void*)0x1000, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 1) gi = __builtin_object_size((void*)0x1000, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 2) gi = __builtin_object_size((void*)0x1000, 2); - // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. - // Hopefully will be lowered properly in the future. - // CHECK: store i32 0 + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 3) gi = __builtin_object_size((void*)0x1000, 3); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 0) gi = __builtin_object_size((void*)0 + 0x1000, 0); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 1) gi = __builtin_object_size((void*)0 + 0x1000, 1); - // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true) + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 2) gi = __builtin_object_size((void*)0 + 0x1000, 2); - // Note: Currently fixed at zero because LLVM can't handle type=3 correctly. - // Hopefully will be lowered properly in the future. - // CHECK: store i32 0 + // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 3) gi = __builtin_object_size((void*)0 + 0x1000, 3); } Index: test/CodeGen/sanitize-recover.c =================================================================== --- test/CodeGen/sanitize-recover.c +++ test/CodeGen/sanitize-recover.c @@ -21,7 +21,7 @@ u.i=1; // PARTIAL: %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null - // PARTIAL: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false) + // PARTIAL: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i8 0) // PARTIAL-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4 // PARTIAL: %[[MISALIGN:.*]] = and i64 {{.*}}, 3