summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-08-23 19:39:04 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-08-23 19:39:04 +0000
commite3a5e8f03d9745764fa516baef37b23978a8fb46 (patch)
tree8a4f8cd892abeceb73349415595a7c4df910bc4a
parent0cb591fc4c5a5c8cf561e8f2b01e88941936578e (diff)
downloadbcm5719-llvm-e3a5e8f03d9745764fa516baef37b23978a8fb46.tar.gz
bcm5719-llvm-e3a5e8f03d9745764fa516baef37b23978a8fb46.zip
[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).
llvm-svn: 311589
-rw-r--r--clang/include/clang/AST/DeclCXX.h5
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp4
-rw-r--r--clang/test/CodeGenCXX/catch-undef-behavior.cpp21
3 files changed, 27 insertions, 3 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 289eb156903..bbd3360d755 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/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/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 4201804e185..0df7d271070 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/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/clang/test/CodeGenCXX/catch-undef-behavior.cpp b/clang/test/CodeGenCXX/catch-undef-behavior.cpp
index 179c3341226..4733556c627 100644
--- a/clang/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/clang/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
OpenPOWER on IntegriCloud