From: Richard Smith Date: Wed, 23 Aug 2017 19:39:04 +0000 (+0000) Subject: [ubsan] PR34266: When sanitizing the 'this' value for a member function that happens... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=da8dca22517ea74afb2c69dae4247388b314cc3b;p=clang [ubsan] PR34266: When sanitizing the 'this' value for a member function that happens to be a lambda call operator, use the lambda's 'this' pointer, not the captured enclosing 'this' pointer (if any). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@311589 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 289eb15690..bbd3360d75 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -2027,7 +2027,10 @@ public: /// \brief Returns the type of the \c this pointer. /// - /// Should only be called for instance (i.e., non-static) methods. + /// Should only be called for instance (i.e., non-static) methods. Note + /// that for the call operator of a lambda closure type, this returns the + /// desugared 'this' type (a pointer to the closure type), not the captured + /// 'this' type. QualType getThisType(ASTContext &C) const; unsigned getTypeQualifiers() const { diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 4201804e18..0df7d27107 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -1014,11 +1014,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, } // Check the 'this' pointer once per function, if it's available. - if (CXXThisValue) { + if (CXXABIThisValue) { SanitizerSet SkippedChecks; SkippedChecks.set(SanitizerKind::ObjectSize, true); QualType ThisTy = MD->getThisType(getContext()); - EmitTypeCheck(TCK_Load, Loc, CXXThisValue, ThisTy, + EmitTypeCheck(TCK_Load, Loc, CXXABIThisValue, ThisTy, getContext().getTypeAlignInChars(ThisTy->getPointeeType()), SkippedChecks); } diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp index 179c334122..4733556c62 100644 --- a/test/CodeGenCXX/catch-undef-behavior.cpp +++ b/test/CodeGenCXX/catch-undef-behavior.cpp @@ -449,6 +449,27 @@ void upcast_to_vbase() { } } +struct ThisAlign { + void this_align_lambda(); +}; +void ThisAlign::this_align_lambda() { + // CHECK-LABEL: define {{.*}}@"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv" + // CHECK-SAME: (%{{.*}}* %[[this:[^)]*]]) + // CHECK: %[[this_addr:.*]] = alloca + // CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]], + // CHECK: %[[this_inner:.*]] = load %{{.*}}*, %{{.*}}** %[[this_addr]], + // CHECK: %[[this_outer_addr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %[[this_inner]], i32 0, i32 0 + // CHECK: %[[this_outer:.*]] = load %{{.*}}*, %{{.*}}** %[[this_outer_addr]], + // + // CHECK: %[[this_inner_isnonnull:.*]] = icmp ne %{{.*}}* %[[this_inner]], null + // CHECK: %[[this_inner_asint:.*]] = ptrtoint %{{.*}}* %[[this_inner]] to i + // CHECK: %[[this_inner_misalignment:.*]] = and i{{32|64}} %[[this_inner_asint]], {{3|7}}, + // CHECK: %[[this_inner_isaligned:.*]] = icmp eq i{{32|64}} %[[this_inner_misalignment]], 0 + // CHECK: %[[this_inner_valid:.*]] = and i1 %[[this_inner_isnonnull]], %[[this_inner_isaligned]], + // CHECK: br i1 %[[this_inner_valid:.*]] + [&] { return this; } (); +} + namespace CopyValueRepresentation { // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S3aSERKS0_ // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value