diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -135,8 +135,8 @@ // down to whether we know it's a complete object or not. auto &Layout = CGF.getContext().getASTRecordLayout(MD->getParent()); if (MD->getParent()->getNumVBases() == 0 || // avoid vcall in common case - MD->getParent()->hasAttr() || - !isThisCompleteObject(CGF.CurGD)) { + MD->getParent()->isEffectivelyFinal() || + isThisCompleteObject(CGF.CurGD)) { CGF.CXXABIThisAlignment = Layout.getAlignment(); } else { CGF.CXXABIThisAlignment = Layout.getNonVirtualAlignment(); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1137,11 +1137,9 @@ MD->getParent()->getLambdaCaptureDefault() == LCD_None) SkippedChecks.set(SanitizerKind::Null, true); - EmitTypeCheck(isa(MD) ? TCK_ConstructorCall - : TCK_MemberCall, - Loc, CXXABIThisValue, ThisTy, - getContext().getTypeAlignInChars(ThisTy->getPointeeType()), - SkippedChecks); + EmitTypeCheck( + isa(MD) ? TCK_ConstructorCall : TCK_MemberCall, + Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks); } } diff --git a/clang/test/CodeGenCXX/catch-undef-behavior.cpp b/clang/test/CodeGenCXX/catch-undef-behavior.cpp --- a/clang/test/CodeGenCXX/catch-undef-behavior.cpp +++ b/clang/test/CodeGenCXX/catch-undef-behavior.cpp @@ -430,8 +430,8 @@ // Note: C is laid out such that offsetof(C, B) + sizeof(B) extends outside // the C object. struct alignas(16) A { void *a1, *a2; }; - struct B : virtual A { void *b; }; - struct C : virtual A, virtual B {}; + struct B : virtual A { void *b; void* g(); }; + struct C : virtual A, virtual B { }; // CHECK-LABEL: define {{.*}} @_ZN15VBaseObjectSize1fERNS_1BE( B &f(B &b) { // Size check: check for nvsize(B) == 16 (do not require size(B) == 32) @@ -443,6 +443,15 @@ // CHECK: and i64 [[PTRTOINT]], 7, return b; } + + // CHECK-LABEL: define {{.*}} @_ZN15VBaseObjectSize1B1gEv( + void *B::g() { + // Ensure that the check on the "this" pointer also uses the proper + // alignment. We should be using nvalign(B) == 8, not 16. + // CHECK: [[PTRTOINT:%.+]] = ptrtoint {{.*}} to i64, + // CHECK: and i64 [[PTRTOINT]], 7 + return nullptr; + } } namespace FunctionSanitizerVirtualCalls {