Index: lib/CodeGen/CGClass.cpp =================================================================== --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -1750,8 +1750,7 @@ // C++11 [class.mfct.non-static]p2: // If a non-static member function of a class X is called for an object that // is not of type X, or of a type derived from X, the behavior is undefined. - // FIXME: Provide a source location here. - EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(), This, + EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, E->getExprLoc(), This, getContext().getRecordType(D->getParent())); if (D->isTrivial() && D->isDefaultConstructor()) { Index: test/CodeGen/ubsan-constructor-type-mismatch.cpp =================================================================== --- test/CodeGen/ubsan-constructor-type-mismatch.cpp +++ test/CodeGen/ubsan-constructor-type-mismatch.cpp @@ -0,0 +1,25 @@ +// Verify ubsan type mismatch checking works with correct source location +// RUN: %clang -target armv7l-unknown-linux-gnueabihf -S %s -o - -emit-llvm -g -fsanitize=alignment -O3 -W0 | FileCheck %s + +struct S { + S() {} + int k; + + void* operator new (unsigned int, void* p) { return p; } +}; + +int f(char x) +{ + char c[] __attribute__((aligned(8))) = { 0, 0, 0, 0, 1, 2, 3, 4, 5 }; + + // Pointer value may be unspecified here, but behavior is not undefined. + int *p = (int*)&c[4 + x - '0']; + S *s1 = (S*)p; + +// CHECK: @1 = private unnamed_addr global { { [98 x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i32, i8 } { { [98 x i8]*, i32, i32 } { [98 x i8]* @.src, i32 22, i32 20 }, { i16, i16, [4 x i8] }* @0, i32 4, i8 5 } +// CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({ { [98 x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i32, i8 }* @1 to i8*) + + S *s2 = new (s1) S; + + return s2->k && 0; +}