diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index b5d6c659e9e15041aa6874c9f2d2f92ac190c58f..719147a58e08789a2e3fdb017876a8c3eec41368 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -568,15 +568,23 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, // The glvalue must not be an empty glvalue. llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr); - if (AllowNullPointers) { - // When performing pointer casts, it's OK if the value is null. - // Skip the remaining checks in that case. - Done = createBasicBlock("null"); - llvm::BasicBlock *Rest = createBasicBlock("not.null"); - Builder.CreateCondBr(IsNonNull, Rest, Done); - EmitBlock(Rest); - } else { - Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null)); + // The IR builder can constant-fold the null check if the pointer points to + // a constant. + bool PtrIsNonNull = + IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext()); + + // Skip the null check if the pointer is known to be non-null. + if (!PtrIsNonNull) { + if (AllowNullPointers) { + // When performing pointer casts, it's OK if the value is null. + // Skip the remaining checks in that case. + Done = createBasicBlock("null"); + llvm::BasicBlock *Rest = createBasicBlock("not.null"); + Builder.CreateCondBr(IsNonNull, Rest, Done); + EmitBlock(Rest); + } else { + Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null)); + } } } diff --git a/test/CodeGenCXX/ubsan-suppress-checks.cpp b/test/CodeGenCXX/ubsan-suppress-checks.cpp index a8ca24ba63a03bf9295a64ad88460810a03209dc..d0e7b32ef96c1dd76d823b26c795b2dc86c9dff5 100644 --- a/test/CodeGenCXX/ubsan-suppress-checks.cpp +++ b/test/CodeGenCXX/ubsan-suppress-checks.cpp @@ -10,6 +10,8 @@ void load_non_null_pointers() { int arr[1]; arr[0] = arr[0]; + char c = "foo"[0]; + // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize // CHECK: ret void }