Re: [PATCH] D12616: Failing test highlighting no poisoning if dtor undeclared.

2015-09-08 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34220.
nmusgrave marked an inline comment as done.
nmusgrave added a comment.

- Rename test.


http://reviews.llvm.org/D12616

Files:
  test/CodeGenCXX/sanitize-dtor-trivial.cpp

Index: test/CodeGenCXX/sanitize-dtor-trivial.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-trivial.cpp
@@ -0,0 +1,15 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+
+// TODO Success pending on resolution of issue:
+//https://github.com/google/sanitizers/issues/596
+// XFAIL: *
+
+struct Trivial {
+  int a;
+  int b;
+};
+Trivial t;
+
+// CHECK: call void @__sanitizer_dtor_callback


Index: test/CodeGenCXX/sanitize-dtor-trivial.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-trivial.cpp
@@ -0,0 +1,15 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// TODO Success pending on resolution of issue:
+//https://github.com/google/sanitizers/issues/596
+// XFAIL: *
+
+struct Trivial {
+  int a;
+  int b;
+};
+Trivial t;
+
+// CHECK: call void @__sanitizer_dtor_callback
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r247025 - Failing test highlighting no poisoning if dtor undeclared.

2015-09-08 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Tue Sep  8 11:38:17 2015
New Revision: 247025

URL: http://llvm.org/viewvc/llvm-project?rev=247025&view=rev
Log:
Failing test highlighting no poisoning if dtor undeclared.

Summary:
If class or struct has not declared a destructor,
no destructor is emitted, and members are not poisoned
after destruction. This case highlights bug in current
implementation of use-after-dtor poisoning (detailed
in https://github.com/google/sanitizers/issues/596).

Reviewers: eugenis, kcc

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D12616

Only check simplest object for existence of sanitizing callback.

Rename test.

Added:
cfe/trunk/test/CodeGenCXX/sanitize-dtor-trivial.cpp

Added: cfe/trunk/test/CodeGenCXX/sanitize-dtor-trivial.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sanitize-dtor-trivial.cpp?rev=247025&view=auto
==
--- cfe/trunk/test/CodeGenCXX/sanitize-dtor-trivial.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/sanitize-dtor-trivial.cpp Tue Sep  8 11:38:17 2015
@@ -0,0 +1,15 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+
+// TODO Success pending on resolution of issue:
+//https://github.com/google/sanitizers/issues/596
+// XFAIL: *
+
+struct Trivial {
+  int a;
+  int b;
+};
+Trivial t;
+
+// CHECK: call void @__sanitizer_dtor_callback


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-08 Thread Naomi Musgrave via cfe-commits
nmusgrave created this revision.
nmusgrave added reviewers: eugenis, kcc.
nmusgrave added a subscriber: cfe-commits.

After destruction, invocation of virtual functions prevented
by poisoning vtable pointer.

http://reviews.llvm.org/D12712

Files:
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  test/CodeGenCXX/sanitize-dtor-vtable.cpp

Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -52,13 +52,17 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
 // CHECK-NOT: call void @__sanitizer_dtor_callback
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1668,9 +1668,20 @@
   // Prevent the current stack frame from disappearing from the stack 
trace.
   CGF.CurFn->addFnAttr("disable-tail-calls", "true");
 
+  ASTContext &Context = CGF.getContext();
+  // Poison vtable and vtable ptr if they exist for this class.
+  if (Dtor->getParent()->isDynamicClass()) {
+llvm::Value *VTablePtr = CGF.LoadCXXThis();
+
+CharUnits::QuantityType PoisonSize =
+Context.toCharUnitsFromBits(CGF.PointerWidthInBits).getQuantity();
+// Pass in void pointer and size of region as arguments to runtime
+// function
+Poison(CGF, VTablePtr, PoisonSize);
+  }
+
   // Construct pointer to region to begin poisoning, and calculate poison
   // size, so that only members declared in this class are poisoned.
-  ASTContext &Context = CGF.getContext();
   unsigned fieldIndex = 0;
   int startIndex = -1;
   // RecordDecl::field_iterator Field;
@@ -1732,10 +1743,16 @@
   if (PoisonSize == 0)
 return;
 
+  Poison(CGF, OffsetPtr, PoisonSize);
+}
+
+void Poison(CodeGenFunction &CGF, llvm::Value *OffsetPtr,
+CharUnits::QuantityType PoisonSize) {
   // Pass in void pointer and size of region as arguments to runtime
   // function
-  llvm::Value *Args[] = {CGF.Builder.CreateBitCast(OffsetPtr, 
CGF.VoidPtrTy),
- llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+  llvm::Value *Args[] = {
+  CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
+  llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
 
   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
 


Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -52,13 +52,17 @@
 // CHECK-NOT: call void @__s

Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-09 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34357.
nmusgrave added a comment.

- Fixed testing callback emission order to account for vptr. Vptr poisoned 
after all virtual and member destructors are invoked, in order to prevent a 
data race an on the virtual function invoked by a class instance. 
(https://github.com/google/sanitizers/wiki/ThreadSanitizerPopularDataRaces#data-race-on-vptr)


http://reviews.llvm.org/D12712

Files:
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  test/CodeGenCXX/sanitize-dtor-vtable.cpp

Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -52,14 +52,17 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK: ret void
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1648,11 +1648,15 @@
 }
   };
 
-  class SanitizeDtor final : public EHScopeStack::Cleanup {
+
+ static void Poison(CodeGenFunction &CGF, llvm::Value *OffsetPtr,
+CharUnits::QuantityType PoisonSize);
+
+  class SanitizeDtorMembers final : public EHScopeStack::Cleanup {
 const CXXDestructorDecl *Dtor;
 
   public:
-SanitizeDtor(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
+SanitizeDtorMembers(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
 
 // Generate function call for handling object poisoning.
 // Disables tail call elimination, to prevent the current stack frame
@@ -1668,9 +1672,21 @@
   // Prevent the current stack frame from disappearing from the stack trace.
   CGF.CurFn->addFnAttr("disable-tail-calls", "true");
 
+  ASTContext &Context = CGF.getContext();
+  /*
+  // Poison vtable and vtable ptr if they exist for this class.
+  if (Dtor->getParent()->isDynamicClass()) {
+llvm::Value *VTablePtr = CGF.LoadCXXThis();
+
+CharUnits::QuantityType PoisonSize =
+Context.toCharUnitsFromBits(CGF.PointerWidthInBits).getQuantity();
+// Pass in void pointer and size of region as arguments to runtime
+// function
+Poison(CGF, VTablePtr, PoisonSize);
+  }
+  */
   // Construct pointer to region to begin poisoning, and calculate poison
   // size, so that only members declared in this class are poisoned.
-  ASTContext &Context = CGF.getContext();
   unsigned fieldIndex = 0;
   int startIndex = -1;
   // RecordDecl::field_iterator Field;
@@ -1684,11 +1700,11 @@
   // Currently on the last field, and it must be poisoned with the
   // current block.
   if (fieldIndex == Layout.getFieldCount() - 1) {
-PoisonBlock(CGF, startIndex, Layout.getFieldCount());
+PoisonMembers(CGF, startIndex, Layout.getFieldCount());
   }
 } else if (startIndex >= 0) {
   // No longer within a block of memory to poison, so poison the block
-  PoisonBlock(CGF, startIndex, fieldIndex);
+  PoisonMembers(CGF, startIndex, fieldIndex);
   // Re-set the start index
   startIndex = -1;
 }
@@ -1701,7 +1717,7 @@
 /// start poisoning (inclusive)
 /// \param layoutEndOffset index of the ASTRecordLayout field to
 /// end poisoning (exclusive)
-void PoisonBlock(CodeGenFunction &CGF, unsigned layoutStartOffset,
+void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset,
   

Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-09 Thread Naomi Musgrave via cfe-commits
nmusgrave marked an inline comment as done.
nmusgrave added a comment.

http://reviews.llvm.org/D12712



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-09 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34373.
nmusgrave added a comment.

- Cleaned up impl.


http://reviews.llvm.org/D12712

Files:
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  test/CodeGenCXX/sanitize-dtor-vtable.cpp

Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -52,14 +52,17 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK: ret void
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1648,11 +1648,15 @@
 }
   };
 
-  class SanitizeDtor final : public EHScopeStack::Cleanup {
+
+ static void Poison(CodeGenFunction &CGF, llvm::Value *OffsetPtr,
+CharUnits::QuantityType PoisonSize);
+
+  class SanitizeDtorMembers final : public EHScopeStack::Cleanup {
 const CXXDestructorDecl *Dtor;
 
   public:
-SanitizeDtor(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
+SanitizeDtorMembers(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
 
 // Generate function call for handling object poisoning.
 // Disables tail call elimination, to prevent the current stack frame
@@ -1684,11 +1688,11 @@
   // Currently on the last field, and it must be poisoned with the
   // current block.
   if (fieldIndex == Layout.getFieldCount() - 1) {
-PoisonBlock(CGF, startIndex, Layout.getFieldCount());
+PoisonMembers(CGF, startIndex, Layout.getFieldCount());
   }
 } else if (startIndex >= 0) {
   // No longer within a block of memory to poison, so poison the block
-  PoisonBlock(CGF, startIndex, fieldIndex);
+  PoisonMembers(CGF, startIndex, fieldIndex);
   // Re-set the start index
   startIndex = -1;
 }
@@ -1701,7 +1705,7 @@
 /// start poisoning (inclusive)
 /// \param layoutEndOffset index of the ASTRecordLayout field to
 /// end poisoning (exclusive)
-void PoisonBlock(CodeGenFunction &CGF, unsigned layoutStartOffset,
+void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset,
  unsigned layoutEndOffset) {
   ASTContext &Context = CGF.getContext();
   const ASTRecordLayout &Layout =
@@ -1732,20 +1736,46 @@
   if (PoisonSize == 0)
 return;
 
-  // Pass in void pointer and size of region as arguments to runtime
-  // function
-  llvm::Value *Args[] = {CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
- llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+  Poison(CGF, OffsetPtr, PoisonSize);
+}
+  };
+
+ class SanitizeDtorVTable final : public EHScopeStack::Cleanup {
+const CXXDestructorDecl *Dtor;
 
-  llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+  public:
+SanitizeDtorVTable(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
+
+// Generate function call for handling vtable pointer poisoning.
+void Emit(CodeGenFunction &CGF, Flags flags) override {
+  assert(Dtor->getParent()->isDynamicClass());
+  ASTContext &Context = CGF.getContext();
+  // Poison vtable and vtable ptr if they exist for this class.
+  llvm::Value *VTablePtr = CGF.LoadCXXThis();
 
-  llvm::FunctionType *FnType =
-  llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
-  llvm::Value *Fn =
-  CGF.CGM.CreateRuntimeFunction(FnType

Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-09 Thread Naomi Musgrave via cfe-commits
nmusgrave marked an inline comment as done.


Comment at: lib/CodeGen/CGClass.cpp:1685
@@ -1680,3 +1684,3 @@
   // Start sanitizing at this field
   if (startIndex < 0)
 startIndex = fieldIndex;

compiler-rt/test/msan/dtor-multiple-inheritance.cc checks that vtable is still 
accessible within dtors.


http://reviews.llvm.org/D12712



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-10 Thread Naomi Musgrave via cfe-commits
nmusgrave marked 2 inline comments as done.


Comment at: lib/CodeGen/CGClass.cpp:1652
@@ +1651,3 @@
+
+ static void Poison(CodeGenFunction &CGF, llvm::Value *OffsetPtr,
+CharUnits::QuantityType PoisonSize);

eugenis wrote:
> If it's a global function, it should have a more descriptive name, like 
> EmitSanitizerDtorCallback.
> OffsetPtr => just Ptr
> And move the body of the function to this line to avoid unnecessary 
> redeclaration.
It's inside of a namespace- is it still global?


http://reviews.llvm.org/D12712



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-11 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34614.
nmusgrave marked 2 inline comments as done.
nmusgrave added a comment.

- Fixed testing callback emission order to account for vptr.


http://reviews.llvm.org/D12712

Files:
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  test/CodeGenCXX/sanitize-dtor-vtable.cpp

Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -52,14 +52,17 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK: ret void
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1648,11 +1648,27 @@
 }
   };
 
-  class SanitizeDtor final : public EHScopeStack::Cleanup {
+ static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
+ CharUnits::QuantityType PoisonSize) {
+   // Pass in void pointer and size of region as arguments to runtime
+   // function
+   llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
+  llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+
+   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+
+   llvm::FunctionType *FnType =
+   llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
+   llvm::Value *Fn =
+   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+   CGF.EmitNounwindRuntimeCall(Fn, Args);
+ }
+
+  class SanitizeDtorMembers final : public EHScopeStack::Cleanup {
 const CXXDestructorDecl *Dtor;
 
   public:
-SanitizeDtor(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
+SanitizeDtorMembers(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
 
 // Generate function call for handling object poisoning.
 // Disables tail call elimination, to prevent the current stack frame
@@ -1684,11 +1700,11 @@
   // Currently on the last field, and it must be poisoned with the
   // current block.
   if (fieldIndex == Layout.getFieldCount() - 1) {
-PoisonBlock(CGF, startIndex, Layout.getFieldCount());
+PoisonMembers(CGF, startIndex, Layout.getFieldCount());
   }
 } else if (startIndex >= 0) {
   // No longer within a block of memory to poison, so poison the block
-  PoisonBlock(CGF, startIndex, fieldIndex);
+  PoisonMembers(CGF, startIndex, fieldIndex);
   // Re-set the start index
   startIndex = -1;
 }
@@ -1701,7 +1717,7 @@
 /// start poisoning (inclusive)
 /// \param layoutEndOffset index of the ASTRecordLayout field to
 /// end poisoning (exclusive)
-void PoisonBlock(CodeGenFunction &CGF, unsigned layoutStartOffset,
+void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset,
  unsigned layoutEndOffset) {
   ASTContext &Context = CGF.getContext();
   const ASTRecordLayout &Layout =
@@ -1732,20 +1748,30 @@
   if (PoisonSize == 0)
 return;
 
-  // Pass in void pointer and size of region as arguments to runtime
-  // function
-  llvm::Value *Args[] = {CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
- llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+  EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize);
+}
+  };
+
+ class SanitizeDtorVTable final : public EHScopeStack::Cleanup {
+const CXXDestructorDecl *Dtor;
+

Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-11 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34617.
nmusgrave added a comment.

- Poison vtable in either complete or base dtor.


http://reviews.llvm.org/D12712

Files:
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  test/CodeGenCXX/sanitize-dtor-vtable.cpp

Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -1,8 +1,9 @@
 // RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
-// Only the last dtor of a class invokes the sanitizing callback
-// Sanitizing callback emited prior to base class dtor invocations
+// Base dtor poisons members
+// Complete dtor poisons vtable ptr after destroying members and
+// virtual bases
 
 class Base {
  public:
@@ -52,14 +53,17 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison member and vtable pointer.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK: ret void
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1648,11 +1648,27 @@
 }
   };
 
-  class SanitizeDtor final : public EHScopeStack::Cleanup {
+ static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
+ CharUnits::QuantityType PoisonSize) {
+   // Pass in void pointer and size of region as arguments to runtime
+   // function
+   llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
+  llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+
+   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+
+   llvm::FunctionType *FnType =
+   llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
+   llvm::Value *Fn =
+   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+   CGF.EmitNounwindRuntimeCall(Fn, Args);
+ }
+
+  class SanitizeDtorMembers final : public EHScopeStack::Cleanup {
 const CXXDestructorDecl *Dtor;
 
   public:
-SanitizeDtor(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
+SanitizeDtorMembers(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
 
 // Generate function call for handling object poisoning.
 // Disables tail call elimination, to prevent the current stack frame
@@ -1684,11 +1700,11 @@
   // Currently on the last field, and it must be poisoned with the
   // current block.
   if (fieldIndex == Layout.getFieldCount() - 1) {
-PoisonBlock(CGF, startIndex, Layout.getFieldCount());
+PoisonMembers(CGF, startIndex, Layout.getFieldCount());
   }
 } else if (startIndex >= 0) {
   // No longer within a block of memory to poison, so poison the block
-  PoisonBlock(CGF, startIndex, fieldIndex);
+  PoisonMembers(CGF, startIndex, fieldIndex);
   // Re-set the start index
   startIndex = -1;
 }
@@ -1701,7 +1717,7 @@
 /// start poisoning (inclusive)
 /// \param layoutEndOffset index of the ASTRecordLayout field to
 /// end poisoning (exclusive)
-void PoisonBlock(CodeGenFunction &CGF, unsigned layoutStartOffset,
+void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset,
  unsigned layoutEndOffset) {
   ASTContext &Context = C

Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-15 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34822.
nmusgrave added a comment.

- Re-checking testing for poisoning vtable.


http://reviews.llvm.org/D12712

Files:
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  test/CodeGenCXX/sanitize-dtor-vtable.cpp

Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+class B : virtual public A {
+ public:
+  int y;
+  B() {}
+  ~B() {}
+};
+B b;
+
+// CHECK-LABEL: define {{.*}}AD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}AD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// After invoking base dtor and dtor for virtual base, poison vtable ptr.
+// CHECK-LABEL: define {{.*}}BD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}BD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Since no virtual bases, poison vtable ptr here.
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Poison members
+// CHECK-LABEL: define {{.*}}BD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -1,8 +1,9 @@
 // RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
-// Only the last dtor of a class invokes the sanitizing callback
-// Sanitizing callback emited prior to base class dtor invocations
+// Base dtor poisons members
+// Complete dtor poisons vtable ptr after destroying members and
+// virtual bases
 
 class Base {
  public:
@@ -28,6 +29,7 @@
 
 Derived d;
 
+// Invoke base destructor. No vtable pointer to poison.
 // CHECK-LABEL: define {{.*}}DerivedD1Ev
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}DerivedD2Ev
@@ -40,6 +42,7 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Invokes base destructor, and poison vtable pointer.
 // CHECK-LABEL: define {{.*}}BaseD1Ev
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
@@ -52,14 +55,17 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison members and vtable ptr.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison members and destroy non-virtual base.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK: ret void
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1648,11 +1648,27 @@
 }
   };
 
-  class SanitizeDtor final : public EHScopeStack::Cleanup {
+ static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
+ CharUnits::QuantityType PoisonSize) {
+   // Pass in void pointer and size of region as arguments to runtime
+   // function
+   llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
+  llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+
+   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+
+   llvm::FunctionType *FnType =
+   llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
+   llvm::Value *Fn =
+   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+   CGF.EmitNounwindRuntimeCall(Fn, Args);
+ }
+
+  class

Re: [PATCH] D12712: Implementation and testing for poisoning vtable ptr in dtor.

2015-09-15 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34851.
nmusgrave added a comment.

- Remove commented-out block.


http://reviews.llvm.org/D12712

Files:
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-derived-class.cpp
  test/CodeGenCXX/sanitize-dtor-vtable.cpp

Index: test/CodeGenCXX/sanitize-dtor-vtable.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-vtable.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+class A {
+ public:
+  int x;
+  A() {}
+  virtual ~A() {}
+};
+A a;
+
+class B : virtual public A {
+ public:
+  int y;
+  B() {}
+  ~B() {}
+};
+B b;
+
+// CHECK-LABEL: define {{.*}}AD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}AD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// After invoking base dtor and dtor for virtual base, poison vtable ptr.
+// CHECK-LABEL: define {{.*}}BD1Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}BD2Ev
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Since no virtual bases, poison vtable ptr here.
+// CHECK-LABEL: define {{.*}}AD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// Poison members
+// CHECK-LABEL: define {{.*}}BD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-derived-class.cpp
===
--- test/CodeGenCXX/sanitize-dtor-derived-class.cpp
+++ test/CodeGenCXX/sanitize-dtor-derived-class.cpp
@@ -1,8 +1,9 @@
 // RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
-// Only the last dtor of a class invokes the sanitizing callback
-// Sanitizing callback emited prior to base class dtor invocations
+// Base dtor poisons members
+// Complete dtor poisons vtable ptr after destroying members and
+// virtual bases
 
 class Base {
  public:
@@ -28,6 +29,7 @@
 
 Derived d;
 
+// Invoke base destructor. No vtable pointer to poison.
 // CHECK-LABEL: define {{.*}}DerivedD1Ev
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}DerivedD2Ev
@@ -40,6 +42,7 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Invokes base destructor, and poison vtable pointer.
 // CHECK-LABEL: define {{.*}}BaseD1Ev
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
@@ -52,14 +55,17 @@
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison members and vtable ptr.
 // CHECK-LABEL: define {{.*}}BaseD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
+// Poison members and destroy non-virtual base.
 // CHECK-LABEL: define {{.*}}DerivedD2Ev
 // CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: call void {{.*}}BaseD2Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void @__sanitizer_dtor_callback{{.*}}i64 8
 // CHECK: ret void
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1648,11 +1648,27 @@
 }
   };
 
-  class SanitizeDtor final : public EHScopeStack::Cleanup {
+ static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
+ CharUnits::QuantityType PoisonSize) {
+   // Pass in void pointer and size of region as arguments to runtime
+   // function
+   llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
+  llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+
+   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+
+   llvm::FunctionType *FnType =
+   llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
+   llvm::Value *Fn =
+   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+   CGF.EmitNounwindRuntimeCall(Fn, Args);
+ }
+
+  class SanitizeDtorM

r247762 - Implementation and testing for poisoning vtable

2015-09-15 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Tue Sep 15 19:38:22 2015
New Revision: 247762

URL: http://llvm.org/viewvc/llvm-project?rev=247762&view=rev
Log:
Implementation and testing for poisoning vtable
ptr in dtor.

Summary:
After destruction, invocation of virtual functions prevented
by poisoning vtable pointer.

Reviewers: eugenis, kcc

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D12712

Fixed testing callback emission order to account for vptr.
Poison vtable in either complete or base dtor, depending on
if virtual bases exist. If virtual bases exist, poison in
complete dtor. Otherwise, poison in base.
Remove commented-out block.

Added:
cfe/trunk/test/CodeGenCXX/sanitize-dtor-vtable.cpp
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-derived-class.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=247762&r1=247761&r2=247762&view=diff
==
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue Sep 15 19:38:22 2015
@@ -1676,11 +1676,27 @@ namespace {
 }
   };
 
-  class SanitizeDtor final : public EHScopeStack::Cleanup {
+ static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
+ CharUnits::QuantityType PoisonSize) {
+   // Pass in void pointer and size of region as arguments to runtime
+   // function
+   llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
+  llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+
+   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+
+   llvm::FunctionType *FnType =
+   llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
+   llvm::Value *Fn =
+   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
+   CGF.EmitNounwindRuntimeCall(Fn, Args);
+ }
+
+  class SanitizeDtorMembers final : public EHScopeStack::Cleanup {
 const CXXDestructorDecl *Dtor;
 
   public:
-SanitizeDtor(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
+SanitizeDtorMembers(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
 
 // Generate function call for handling object poisoning.
 // Disables tail call elimination, to prevent the current stack frame
@@ -1712,11 +1728,11 @@ namespace {
   // Currently on the last field, and it must be poisoned with the
   // current block.
   if (fieldIndex == Layout.getFieldCount() - 1) {
-PoisonBlock(CGF, startIndex, Layout.getFieldCount());
+PoisonMembers(CGF, startIndex, Layout.getFieldCount());
   }
 } else if (startIndex >= 0) {
   // No longer within a block of memory to poison, so poison the block
-  PoisonBlock(CGF, startIndex, fieldIndex);
+  PoisonMembers(CGF, startIndex, fieldIndex);
   // Re-set the start index
   startIndex = -1;
 }
@@ -1729,7 +1745,7 @@ namespace {
 /// start poisoning (inclusive)
 /// \param layoutEndOffset index of the ASTRecordLayout field to
 /// end poisoning (exclusive)
-void PoisonBlock(CodeGenFunction &CGF, unsigned layoutStartOffset,
+void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset,
  unsigned layoutEndOffset) {
   ASTContext &Context = CGF.getContext();
   const ASTRecordLayout &Layout =
@@ -1760,20 +1776,30 @@ namespace {
   if (PoisonSize == 0)
 return;
 
-  // Pass in void pointer and size of region as arguments to runtime
-  // function
-  llvm::Value *Args[] = {CGF.Builder.CreateBitCast(OffsetPtr, 
CGF.VoidPtrTy),
- llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+  EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize);
+}
+  };
+
+ class SanitizeDtorVTable final : public EHScopeStack::Cleanup {
+const CXXDestructorDecl *Dtor;
 
-  llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
+  public:
+SanitizeDtorVTable(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
 
-  llvm::FunctionType *FnType =
-  llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
-  llvm::Value *Fn =
-  CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
-  CGF.EmitNounwindRuntimeCall(Fn, Args);
+// Generate function call for handling vtable pointer poisoning.
+void Emit(CodeGenFunction &CGF, Flags flags) override {
+  assert(Dtor->getParent()->isDynamicClass());
+  ASTContext &Context = CGF.getContext();
+  // Poison vtable and vtable ptr if they exist for this class.
+  llvm::Value *VTablePtr = CGF.LoadCXXThis();
+
+  CharUnits::QuantityType PoisonSize =
+  Context.toCharUnitsFromBits(CGF.PointerWidthInBits).getQuantity();
+  // Pass in void pointer and size of region as arguments to runtime
+  // function
+  EmitSanitizerDtorCallback(CGF, VTab

r247871 - Updating docs for MSan to describe poison-in-dtor.

2015-09-16 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Wed Sep 16 19:10:59 2015
New Revision: 247871

URL: http://llvm.org/viewvc/llvm-project?rev=247871&view=rev
Log:
Updating docs for MSan to describe poison-in-dtor.

Summary:
Describe the compile and runtime flags to enable MemorySanitizer
detection of use-after-destroy.

Reviewers: eugenis

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D12914

Revise doc description of use-after-dtor.

Change wording to specify memory no longer readable.

Modified:
cfe/trunk/docs/UsersManual.rst

Modified: cfe/trunk/docs/UsersManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=247871&r1=247870&r2=247871&view=diff
==
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Wed Sep 16 19:10:59 2015
@@ -1065,6 +1065,16 @@ are listed below.
   order of memory stores the uninitialized value went
   through. This mode may use extra memory in programs that copy
   uninitialized memory a lot.
+   -  ``-fsanitize-memory-use-after-dtor``: Enables use-after-destruction
+  detection in MemorySanitizer. After invocation of the destructor,
+  the object is considered no longer readable. Facilitates the
+  detection of use-after-destroy bugs.
+
+  Setting the MSAN_OPTIONS=poison_in_dtor=1 enables the poisoning of
+  memory at runtime. Any subsequent access to the destroyed object
+  fails at runtime. This feature is still experimental, but this
+  environment variable must be set to 1 in order for the above flag
+  to have any effect.
 
The ``-fsanitize=`` argument must also be provided when linking, in
order to link to the appropriate runtime library. When using


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r244819 - Implement poisoning of only class members in dtor, as opposed to also poisoning fields inherited from base classes.

2015-08-12 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Wed Aug 12 16:37:40 2015
New Revision: 244819

URL: http://llvm.org/viewvc/llvm-project?rev=244819&view=rev
Log:
Implement poisoning of only class members in dtor, as opposed to also poisoning 
fields inherited from base classes.
Verify emitted code for derived class with virtual destructor sanitizes its 
members only once.
Changed emission order for dtor callback, so only the last dtor for a class 
emits the sanitizing callback, while ensuring that class members are poisoned 
before base class destructors are invoked.
Skip poisoning of members, if class has no fields.
Removed patch file containing extraneous changes.

Summary: Poisoning applied to only class members, and before dtors for base 
class invoked

Reviewers: eugenis, kcc

Differential Revision: http://reviews.llvm.org/D11951

Added:
cfe/trunk/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-fn-attribute.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=244819&r1=244818&r2=244819&view=diff
==
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Aug 12 16:37:40 2015
@@ -1376,9 +1376,30 @@ static void EmitDtorSanitizerCallback(Co
   const ASTRecordLayout &Layout =
   CGF.getContext().getASTRecordLayout(Dtor->getParent());
 
+  // Nothing to poison
+  if(Layout.getFieldCount() == 0)
+return;
+
+  // Construct pointer to region to begin poisoning, and calculate poison
+  // size, so that only members declared in this class are poisoned.
+  llvm::Value *OffsetPtr;
+  CharUnits::QuantityType PoisonSize;
+  ASTContext &Context = CGF.getContext();
+
+  llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
+  CGF.SizeTy, Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).
+  getQuantity());
+
+  OffsetPtr = CGF.Builder.CreateGEP(CGF.Builder.CreateBitCast(
+  CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr);
+
+  PoisonSize = Layout.getSize().getQuantity() -
+  Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).getQuantity();
+
   llvm::Value *Args[] = {
-  CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.VoidPtrTy),
-  llvm::ConstantInt::get(CGF.SizeTy, Layout.getSize().getQuantity())};
+CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
+llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+
   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
 
   llvm::FunctionType *FnType =
@@ -1386,6 +1407,8 @@ static void EmitDtorSanitizerCallback(Co
   llvm::Value *Fn =
   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
 
+  // Disables tail call elimination, to prevent the current stack frame from
+  // disappearing from the stack trace.
   CGF.CurFn->addFnAttr("disable-tail-calls", "true");
   CGF.EmitNounwindRuntimeCall(Fn, Args);
 }
@@ -1468,6 +1491,13 @@ void CodeGenFunction::EmitDestructorBody
 // the caller's body.
 if (getLangOpts().AppleKext)
   CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
+
+// Insert memory-poisoning instrumentation, before final clean ups,
+// to ensure this class's members are protected from invalid access.
+if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
+&& SanOpts.has(SanitizerKind::Memory))
+  EmitDtorSanitizerCallback(*this, Dtor);
+
 break;
   }
 
@@ -1477,11 +1507,6 @@ void CodeGenFunction::EmitDestructorBody
   // Exit the try if applicable.
   if (isTryBody)
 ExitCXXTryStmt(*cast(Body), true);
-
-  // Insert memory-poisoning instrumentation.
-  if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
-  && SanOpts.has(SanitizerKind::Memory))
-EmitDtorSanitizerCallback(*this, Dtor);
 }
 
 void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList 
&Args) {

Modified: cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp?rev=244819&r1=244818&r2=244819&view=diff
==
--- cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp Wed Aug 12 16:37:40 
2015
@@ -7,7 +7,8 @@ struct Simple {
 Simple s;
 // Simple internal member is poisoned by compiler-generated dtor
 // CHECK-LABEL: define {{.*}}SimpleD1Ev
-// CHECK: call void @__sanitizer_dtor_callback
+// CHECK-NOT: call void @__sanitizer_dtor_callback
+// CHECK: call void {{.*}}SimpleD2Ev
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
@@ -17,7 +18,8 @@ struct Inlined {
 Inlined i;
 // Simple internal member is poisoned by compiler-generated dtor
 // CHECK-LABEL: define {{.*}}InlinedD1Ev
-// CHECK: call void @__sanitizer_dt

r244820 - Revert "Implement poisoning of only class members in dtor, as opposed to also poisoning fields inherited from base classes."

2015-08-12 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Wed Aug 12 17:07:24 2015
New Revision: 244820

URL: http://llvm.org/viewvc/llvm-project?rev=244820&view=rev
Log:
Revert "Implement poisoning of only class members in dtor, as opposed to also 
poisoning fields inherited from base classes."

This reverts commit 8dbbf3578a9a5d063232b59e558e5fe46e2cd42c.
Rolled back due to buildbot failures on 'ninja check-clang'.

Removed:
cfe/trunk/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-fn-attribute.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=244820&r1=244819&r2=244820&view=diff
==
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Aug 12 17:07:24 2015
@@ -1376,30 +1376,9 @@ static void EmitDtorSanitizerCallback(Co
   const ASTRecordLayout &Layout =
   CGF.getContext().getASTRecordLayout(Dtor->getParent());
 
-  // Nothing to poison
-  if(Layout.getFieldCount() == 0)
-return;
-
-  // Construct pointer to region to begin poisoning, and calculate poison
-  // size, so that only members declared in this class are poisoned.
-  llvm::Value *OffsetPtr;
-  CharUnits::QuantityType PoisonSize;
-  ASTContext &Context = CGF.getContext();
-
-  llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
-  CGF.SizeTy, Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).
-  getQuantity());
-
-  OffsetPtr = CGF.Builder.CreateGEP(CGF.Builder.CreateBitCast(
-  CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr);
-
-  PoisonSize = Layout.getSize().getQuantity() -
-  Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).getQuantity();
-
   llvm::Value *Args[] = {
-CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
-llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
-
+  CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.VoidPtrTy),
+  llvm::ConstantInt::get(CGF.SizeTy, Layout.getSize().getQuantity())};
   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
 
   llvm::FunctionType *FnType =
@@ -1407,8 +1386,6 @@ static void EmitDtorSanitizerCallback(Co
   llvm::Value *Fn =
   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
 
-  // Disables tail call elimination, to prevent the current stack frame from
-  // disappearing from the stack trace.
   CGF.CurFn->addFnAttr("disable-tail-calls", "true");
   CGF.EmitNounwindRuntimeCall(Fn, Args);
 }
@@ -1491,13 +1468,6 @@ void CodeGenFunction::EmitDestructorBody
 // the caller's body.
 if (getLangOpts().AppleKext)
   CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
-
-// Insert memory-poisoning instrumentation, before final clean ups,
-// to ensure this class's members are protected from invalid access.
-if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
-&& SanOpts.has(SanitizerKind::Memory))
-  EmitDtorSanitizerCallback(*this, Dtor);
-
 break;
   }
 
@@ -1507,6 +1477,11 @@ void CodeGenFunction::EmitDestructorBody
   // Exit the try if applicable.
   if (isTryBody)
 ExitCXXTryStmt(*cast(Body), true);
+
+  // Insert memory-poisoning instrumentation.
+  if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
+  && SanOpts.has(SanitizerKind::Memory))
+EmitDtorSanitizerCallback(*this, Dtor);
 }
 
 void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList 
&Args) {

Modified: cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp?rev=244820&r1=244819&r2=244820&view=diff
==
--- cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp Wed Aug 12 17:07:24 
2015
@@ -7,8 +7,7 @@ struct Simple {
 Simple s;
 // Simple internal member is poisoned by compiler-generated dtor
 // CHECK-LABEL: define {{.*}}SimpleD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}SimpleD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
@@ -18,8 +17,7 @@ struct Inlined {
 Inlined i;
 // Simple internal member is poisoned by compiler-generated dtor
 // CHECK-LABEL: define {{.*}}InlinedD1Ev
-// CHECK-NOT: call void @__sanitizer_dtor_callback
-// CHECK: call void {{.*}}InlinedD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
 // CHECK-NOT: call void @__sanitizer_dtor_callback
 // CHECK: ret void
 
@@ -46,8 +44,7 @@ Defaulted_Non_Trivial def_non_trivial;
 // By including a Simple member in the struct, the compiler is
 // forced to generate a non-trivial destructor.
 // CHECK-LABEL: define {{.*}}Defaulted_Non_TrivialD1Ev
-// CHECK-NOT: call void @__sa

r244933 - Fix previous commit: poison only class members, simpler tests

2015-08-13 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Thu Aug 13 13:35:11 2015
New Revision: 244933

URL: http://llvm.org/viewvc/llvm-project?rev=244933&view=rev
Log:
Fix previous commit: poison only class members, simpler tests

Summary: Poisoning applied to only class members, and before dtors for base 
class invoked

Implement poisoning of only class members in dtor, as opposed to also
poisoning fields inherited from base classes. Members are poisoned
only once, by the last dtor for a class. Skip poisoning if class has
no fields.
Verify emitted code for derived class with virtual destructor sanitizes
its members only once.
Removed patch file containing extraneous changes.

Reviewers: eugenis, kcc

Differential Revision: http://reviews.llvm.org/D11951


Simplified test cases for use-after-dtor

Summary: Simplified test cases to focus on one feature at time.
Tests updated to align with new emission order for sanitizing
callback.

Reviewers: eugenis, kcc

Differential Revision: http://reviews.llvm.org/D12003

Added:
cfe/trunk/test/CodeGenCXX/sanitize-dtor-derived-class.cpp
Modified:
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-fn-attribute.cpp

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=244933&r1=244932&r2=244933&view=diff
==
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Aug 13 13:35:11 2015
@@ -1376,9 +1376,30 @@ static void EmitDtorSanitizerCallback(Co
   const ASTRecordLayout &Layout =
   CGF.getContext().getASTRecordLayout(Dtor->getParent());
 
+  // Nothing to poison
+  if(Layout.getFieldCount() == 0)
+return;
+
+  // Construct pointer to region to begin poisoning, and calculate poison
+  // size, so that only members declared in this class are poisoned.
+  llvm::Value *OffsetPtr;
+  CharUnits::QuantityType PoisonSize;
+  ASTContext &Context = CGF.getContext();
+
+  llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
+  CGF.SizeTy, Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).
+  getQuantity());
+
+  OffsetPtr = CGF.Builder.CreateGEP(CGF.Builder.CreateBitCast(
+  CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr);
+
+  PoisonSize = Layout.getSize().getQuantity() -
+  Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).getQuantity();
+
   llvm::Value *Args[] = {
-  CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.VoidPtrTy),
-  llvm::ConstantInt::get(CGF.SizeTy, Layout.getSize().getQuantity())};
+CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
+llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
+
   llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
 
   llvm::FunctionType *FnType =
@@ -1386,6 +1407,8 @@ static void EmitDtorSanitizerCallback(Co
   llvm::Value *Fn =
   CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
 
+  // Disables tail call elimination, to prevent the current stack frame from
+  // disappearing from the stack trace.
   CGF.CurFn->addFnAttr("disable-tail-calls", "true");
   CGF.EmitNounwindRuntimeCall(Fn, Args);
 }
@@ -1468,6 +1491,13 @@ void CodeGenFunction::EmitDestructorBody
 // the caller's body.
 if (getLangOpts().AppleKext)
   CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
+
+// Insert memory-poisoning instrumentation, before final clean ups,
+// to ensure this class's members are protected from invalid access.
+if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
+&& SanOpts.has(SanitizerKind::Memory))
+  EmitDtorSanitizerCallback(*this, Dtor);
+
 break;
   }
 
@@ -1477,11 +1507,6 @@ void CodeGenFunction::EmitDestructorBody
   // Exit the try if applicable.
   if (isTryBody)
 ExitCXXTryStmt(*cast(Body), true);
-
-  // Insert memory-poisoning instrumentation.
-  if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
-  && SanOpts.has(SanitizerKind::Memory))
-EmitDtorSanitizerCallback(*this, Dtor);
 }
 
 void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList 
&Args) {

Modified: cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp?rev=244933&r1=244932&r2=244933&view=diff
==
--- cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp Thu Aug 13 13:35:11 
2015
@@ -1,24 +1,26 @@
 // Test -fsanitize-memory-use-after-dtor
 // RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
+// Sanitizing dtor is emitted in dtor for every class
+
 struct Simple {
+  int x;
   ~Simple() {}
 };
 Simple s;
 // Simple internal member is poisoned by compiler-generated dt

r245124 - clarified test comment

2015-08-14 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Fri Aug 14 18:22:03 2015
New Revision: 245124

URL: http://llvm.org/viewvc/llvm-project?rev=245124&view=rev
Log:
clarified test comment

Modified:
cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp

Modified: cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp?rev=245124&r1=245123&r2=245124&view=diff
==
--- cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/sanitize-dtor-callback.cpp Fri Aug 14 18:22:03 
2015
@@ -1,7 +1,8 @@
 // Test -fsanitize-memory-use-after-dtor
 // RUN: %clang_cc1 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
 
-// Sanitizing dtor is emitted in dtor for every class
+// Sanitizing dtor is emitted in dtor for every class, and only
+// poisons once.
 
 struct Simple {
   int x;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-19 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 32600.
nmusgrave added a comment.

- CFE test for dtor aliasing, and repression of aliasing in dtor code 
generation.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,26 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int y;
+  Derived() { y = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Declaration of virtual function table
+// CHECK: $_ZTV7Derived = comdat any
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1367,52 +1367,6 @@
   return true;
 }
 
-// Generates function call for handling object poisoning, passing in
-// references to 'this' and its size as arguments.
-// Disables tail call elimination, to prevent the current stack frame from
-// disappearing from the stack trace.
-static void EmitDtorSanitizerCallback(CodeGenFunction &CGF,
-  const CXXDestructorDecl *Dtor) {
-  const ASTRecordLayout &Layout =
-  CGF.getContext().getASTRecordLayout(Dtor->getParent());
-
-  // Nothing to poison
-  if(Layout.getFieldCount() == 0)
-return;
-
-  // Construct pointer to region to begin poisoning, and calculate poison
-  // size, so that only members declared in this class are poisoned.
-  llvm::Value *OffsetPtr;
-  CharUnits::QuantityType PoisonSize;
-  ASTContext &Context = CGF.getContext();
-
-  llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
-  CGF.SizeTy, Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).
-  getQuantity());
-
-  OffsetPtr = CGF.Builder.CreateGEP(CGF.Builder.CreateBitCast(
-  CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr);
-
-  PoisonSize = Layout.getSize().getQuantity() -
-  Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).getQuantity();
-
-  llvm::Value *Args[] = {
-CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
-llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
-
-  llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
-
-  llvm::FunctionType *FnType =
-  llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
-  llvm::Value *Fn =
-  CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
-
-  // Disables tail call elimination, to prevent the current stack frame from
-  // disappearing from the stack trace.
-  CGF.CurFn->addFnAttr("disable-tail-calls", "true");
-  CGF.EmitNounwindRuntimeCall(Fn, Args);
-}
-
 /// EmitDestructorBody - Emits the body of the current destructor.
 void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
   const CXXDestructorDecl *Dtor = cast(CurGD.getDecl());
@@ -1492,12 +1446,6 @@
 if (getLangOpts().AppleKext)
   CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
 
-// Insert memory-poisoning instrumentation, before final clean ups,
-// to ensure this class's members are protected from invalid access.
-if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor
-&& SanOpts.has(SanitizerKind::Memory))
-  EmitDtorSanitizerCallback(*this, Dtor);
-
 break;
   }
 
@@ -1586,6 +1534,59 @@
   flags.isForNormalCleanup() && useEHCleanupForArray);
 }
   };
+
+class SanitizeDtor : public EHScopeStack::Cleanup {
+  const CXXDestructorDecl *Dtor;
+ public:
+  SanitizeDtor(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
+
+  // Generate function call for handling object poisoning.
+  // Disables tail call elimination, to prevent the current stack frame
+  // from disappearing from the stack trace.
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+// Check flags to determine if allowed to emit.
+if (!CGF.CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor ||
+!CGF.SanOpts.has(SanitizerKind::Memory))
+  return;
+
+const ASTRecordLayout &Layout =
+CGF.getContext().getASTRecordLayout(Dtor->get

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-19 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 32608.
nmusgrave added a comment.

- More complex testing for destruction order. Tests class with base, virtual 
base, trivial, and nontrivial member to ensure destruction order is correct.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,84 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int y;
+  VirtualBase() { y = 10; }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int z;
+  Vector v;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// Declaration of virtual function table
+// CHECK: $_ZTV7Derived = comdat any
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: call void {{.*}}ZN7DerivedD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback(i8* %{{[0-9]*}}, i64 4)
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN4BaseD1Ev
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN4BaseD0Ev
+// CHECK: call void {{.*}}ZN4BaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback(i8* %{{[0-9]*}}, i64 4)
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback(i8* %{{[0-9]*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1367,52 +1367,6 @@
   return true;
 }
 
-// Generates function call for handling object poisoning, passing in
-// references to 'this' and its size as arguments.
-// Disables tail call elimination, to prevent the current stack frame from
-// disappearing from the stack trace.
-static void EmitDtorSanitizerCallback(CodeGenFunction &CGF,
-  const CXXDestructorDecl *Dtor) {
-  const ASTRecordLayout &Layout =
-  CGF.getContext().getASTRecordLayout(Dtor->getParent());
-
-  // Nothing to poison
-  if(Layout.getFieldCount() == 0)
-return;
-
-  // Construct pointer to region to begin poisoning, and calculate poison
-  // size, so that only members declared in this class are poisoned.
-  llvm::Value *OffsetPtr;
-  CharUnits::QuantityType PoisonSize;
-  ASTContext &Context = CGF.getContext();
-
-  llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
-  CGF.SizeTy, Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).
-  getQuantity());
-
-  OffsetPtr = CGF.Builder.CreateGEP(CGF.Builder.CreateBitCast(
-  CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr);
-
-  PoisonSize = Layout.getSize().getQuantity() -
-  Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).getQuantity();
-
-  llvm::Value *Args[] = {
-CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrTy),
-llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
-
-  llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
-
-  llvm::FunctionType *FnType =
-  llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
-  llvm::Value *Fn =
-  CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
-
-  // Disables tail call elimination, to prevent the current stack frame from
-  // disappearing

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-21 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 32873.
nmusgrave marked 2 inline comments as done.
nmusgrave added a comment.

- Poisoning on field-by-field basis, with collective poisoning of trivial 
members when possible.
- Cleaned up implementation of calculating region to poison in dtor.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,14 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
 

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-21 Thread Naomi Musgrave via cfe-commits
nmusgrave added inline comments.


Comment at: lib/CodeGen/CGCXX.cpp:41
@@ +40,3 @@
+  if (getCodeGenOpts().SanitizeMemoryUseAfterDtor && Layout.getFieldCount() > 0
+  && HasTrivialDestructorBody(Context, D->getParent(), D->getParent())) {
+return true;

eugenis wrote:
> I'm not sure this is correct. It says not to use an alias if D has trivial 
> body. Should not it be the other way around?
It's counter-intuitive:
TryEmitBaseDestructorAsAlias returns false when TryEmitDefinitionAsAlias 
returns false.
TryEmitDefinitionAsAlias returns false when an alias is successfully created 
(line 216 in this CL)


http://reviews.llvm.org/D12022



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-21 Thread Naomi Musgrave via cfe-commits
nmusgrave added inline comments.


Comment at: lib/CodeGen/CGCXX.cpp:41
@@ +40,3 @@
+  if (getCodeGenOpts().SanitizeMemoryUseAfterDtor && Layout.getFieldCount() > 0
+  && HasTrivialDestructorBody(Context, D->getParent(), D->getParent())) {
+return true;

nmusgrave wrote:
> eugenis wrote:
> > I'm not sure this is correct. It says not to use an alias if D has trivial 
> > body. Should not it be the other way around?
> It's counter-intuitive:
> TryEmitBaseDestructorAsAlias returns false when TryEmitDefinitionAsAlias 
> returns false.
> TryEmitDefinitionAsAlias returns false when an alias is successfully created 
> (line 216 in this CL)
For example: line 3711 of clang/lib/CodeGen/MicrosoftCXXABI.cpp
 bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true); 

^uses the negation of the function's return value


http://reviews.llvm.org/D12022



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-21 Thread Naomi Musgrave via cfe-commits
nmusgrave added inline comments.


Comment at: lib/CodeGen/CGClass.cpp:1578
@@ +1577,3 @@
+if (CGF.CGM.FieldHasTrivialDestructorBody(Context, Field) ||
+Field->getType()->isPointerType()) {
+  // Start sanitizing at this field

eugenis wrote:
> Why do you need to special-case pointers?
FieldHasTrivialDestructorBody doesn't catch pointers- it identifies their base 
type as some class, and returns false


http://reviews.llvm.org/D12022



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-23 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 32930.
nmusgrave added a comment.

- Refactoring dtor sanitizing emission order
- support for virtual functions & virtual bases WIP
- Repress dtor aliasing when sanitizing in dtor
- CFE test for dtor aliasing, and repression of aliasing in dtor code 
generation.
- More complex testing for destruction order.
- Poison trivial members one-by-one.
- Poisoning on field-by-field basis, with collective poisoning of trivial 
members when possible.
- Cleaned up implementation of calculating region to poison in dtor.
- Checking for existence of a single trivial field.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-24 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 32986.
nmusgrave added a comment.

- Refactored for simpler trivial field checking


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClassDecl)
 {
@@ -1332,10 +1328,12 @@
   return true;
 }
 
-static

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-24 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33037.
nmusgrave marked 4 inline comments as done.
nmusgrave added a comment.

- Simplify function invocations


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClassDecl)
 {
@@ -1332,10 +1328,12 @@

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-25 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33100.
nmusgrave marked an inline comment as done.
nmusgrave added a comment.

- Check flags before dtor sanitizing


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClassDecl)
 {
@@ -1332,10 +1328,1

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-25 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33115.
nmusgrave added a comment.

- Simplify parameters, rename function, for examining fields of class to 
destroy.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClassDecl)
 {
@@ -1332,10 +1328

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-28 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33436.
nmusgrave added a comment.

- Checking for existence of fields to poison in alias emission.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClassDecl)
 {
@@ -1332,10 +1328,12 @@
   return tr

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-28 Thread Naomi Musgrave via cfe-commits
nmusgrave marked 3 inline comments as done.
nmusgrave added a comment.

http://reviews.llvm.org/D12022



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-28 Thread Naomi Musgrave via cfe-commits
nmusgrave added inline comments.


Comment at: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp:30
@@ +29,2 @@
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}(void (%struct.Derived*)* @_ZN7DerivedD1Ev to 
i8*){{.*}}(void (%struct.Derived*)* @_ZN7DerivedD0Ev to i8*)

Its checking that my aliasing is repressed when appropriate.Should I keep or 
get rid of this test case?


http://reviews.llvm.org/D12022



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-08-28 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33463.
nmusgrave marked an inline comment as done.
nmusgrave added a comment.

- Alias-repressing test case ignores casting of pointers.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1098,6 +1098,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClassDecl)
 {
@@ -1332,10 +1328,12 @@
   return true;
 }
 
-static bool
-FieldHa

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-09-01 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33752.
nmusgrave marked 13 inline comments as done.
nmusgrave added a comment.

- Simplified implementation of class field poisoning, to avoid redundant 
counting and conditional checks. Expensive checks delayed.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1099,6 +1099,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClas

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-09-01 Thread Naomi Musgrave via cfe-commits
nmusgrave added inline comments.


Comment at: lib/CodeGen/CGCXX.cpp:42-44
@@ -33,1 +41,5 @@
 bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
+  // If sanitizing memory to check for use-after-dtor, do not emit as
+  // an alias, unless it has no fields or has only fields with non-trivial
+  // destructors.
+  if (getCodeGenOpts().SanitizeMemoryUseAfterDtor)

vptr poisoning will be implemented in another CL after this is approved


http://reviews.llvm.org/D12022



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-09-02 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33887.
nmusgrave marked 4 inline comments as done.
nmusgrave added a comment.

- Update comments, consistent style for attribute checking.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: lib/CodeGen/CodeGenModule.h
===
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1099,6 +1099,13 @@
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool
+  HasTrivialDestructorBody(ASTContext &Context,
+   const CXXRecordDecl *BaseClassDecl,
+   const CXXRecordDecl *MostDerivedClassDecl);
+  bool
+  FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
+
   bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
 bool InEveryTU);
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -1286,11 +1286,7 @@
   CM.finish();
 }
 
-static bool
-FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
-
-static bool
-HasTrivialDestructorBody(ASTContext &Context,
+bool CodeGenModule::HasTrivialDestructorBody(ASTContext &Context,
  const CXXRecordDecl *BaseClassDecl,
  const CXXRecordDecl *MostDerivedClassDecl)
 {
@@ -1332,9 +1328,8 @@
   return true;
 }
 
-static bool
-FieldHa

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-09-03 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33956.
nmusgrave marked 4 inline comments as done.
nmusgrave added a comment.

- Testing sanitizing bit fields.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-bit-field.cpp
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-bit-field.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -0,0 +1,66 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// 24 bytes total
+struct Packed {
+  // Packed into 4 bytes
+  unsigned int a : 1;
+  unsigned int b : 1;
+  //unsigned int c : 1;
+  // Force alignment to next 4 bytes
+  unsigned int   : 0;
+  unsigned int d : 1;
+  // Force alignment, 8 more bytes
+  double e = 5.0;
+  // 4 bytes
+  unsigned int f : 1;
+};
+Packed p;
+
+
+// 1 byte total
+struct Empty {
+  unsigned int : 0;
+};
+Empty e;
+
+
+// 4 byte total
+struct Simple {
+  unsigned int a : 1;
+};
+Simple s;
+
+
+// 8 bytes total
+struct Anon {
+  // 1 byte
+  unsigned int a : 1;
+  unsigned int b : 2;
+  // Force alignment to next byte
+  unsigned int   : 0;
+  unsigned int c : 1;
+};
+Anon a;
+
+struct Foo {
+  int f;
+};
+Foo f;
+
+// CHECK-LABEL: define {{.*}}PackedD2Ev
+//

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-09-03 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33959.
nmusgrave added a comment.

- Refined testing for bit fields.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-bit-field.cpp
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-bit-field.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -0,0 +1,65 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// 24 bytes total
+struct Packed {
+  // Packed into 4 bytes
+  unsigned int a : 1;
+  unsigned int b : 1;
+  //unsigned int c : 1;
+  // Force alignment to next 4 bytes
+  unsigned int   : 0;
+  unsigned int d : 1;
+  // Force alignment, 8 more bytes
+  double e = 5.0;
+  // 4 bytes
+  unsigned int f : 1;
+  ~Packed() {}
+};
+Packed p;
+
+
+// 1 byte total
+struct Empty {
+  unsigned int : 0;
+  ~Empty() {}
+};
+Empty e;
+
+
+// 4 byte total
+struct Simple {
+  unsigned int a : 1;
+  ~Simple() {}
+};
+Simple s;
+
+
+// 8 bytes total
+struct Anon {
+  // 1 byte
+  unsigned int a : 1;
+  unsigned int b : 2;
+  // Force alignment to next byte
+  unsigned int   : 0;
+  unsigned int c : 1;
+  ~Anon() {}
+};
+Anon a;
+
+// CHECK-LABEL: define {{.*}}PackedD2Ev
+// CHECK: call void @_

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-09-03 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33978.
nmusgrave marked 4 inline comments as done.
nmusgrave added a comment.

- Simplified fields and checks for aliasing.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-bit-field.cpp
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-bit-field.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -0,0 +1,84 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// 24 bytes total
+struct Packed {
+  // Packed into 4 bytes
+  unsigned int a : 1;
+  unsigned int b : 1;
+  //unsigned int c : 1;
+  // Force alignment to next 4 bytes
+  unsigned int   : 0;
+  unsigned int d : 1;
+  // Force alignment, 8 more bytes
+  double e = 5.0;
+  // 4 bytes
+  unsigned int f : 1;
+  ~Packed() {}
+};
+Packed p;
+
+
+// 1 byte total
+struct Empty {
+  unsigned int : 0;
+  ~Empty() {}
+};
+Empty e;
+
+
+// 4 byte total
+struct Simple {
+  unsigned int a : 1;
+  ~Simple() {}
+};
+Simple s;
+
+
+// 8 bytes total
+struct Anon {
+  // 1 byte
+  unsigned int a : 1;
+  unsigned int b : 2;
+  // Force alignment to next byte
+  unsigned int   : 0;
+  unsigned int c : 1;
+  ~Anon() {}
+};
+Anon an;
+
+
+struc

Re: [PATCH] D12022: Refactored dtor sanitizing into EHScopeStack

2015-09-03 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 33982.
nmusgrave marked 2 inline comments as done.
nmusgrave added a comment.

- Clean method headers, style.


http://reviews.llvm.org/D12022

Files:
  lib/CodeGen/CGCXX.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGenCXX/sanitize-dtor-bit-field.cpp
  test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
  test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp

Index: test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
@@ -0,0 +1,30 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O2 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {}
+};
+
+// Virtual function table for the derived class only contains
+// its own destructors, with no aliasing to base class dtors.
+struct Base {
+  Vector v;
+  int x;
+  Base() { x = 5; }
+  virtual ~Base() {}
+};
+
+struct Derived : public Base {
+  int z;
+  Derived() { z = 10; }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Definition of virtual function table
+// CHECK: @_ZTV7Derived = {{.*}}@_ZN7DerivedD1Ev{{.*}}@_ZN7DerivedD0Ev
Index: test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsanitize=memory -O0 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=memory -O1 -fsanitize-memory-use-after-dtor -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+template 
+class Vector {
+public:
+  int size;
+  ~Vector() {
+size += 1;
+  }
+};
+
+struct Base {
+  int b1;
+  double b2;
+  Base() {
+b1 = 5;
+b2 = 10.989;
+  }
+  virtual ~Base() {}
+};
+
+struct VirtualBase {
+  int vb1;
+  int vb2;
+  VirtualBase() {
+vb1 = 10;
+vb2 = 11;
+  }
+  virtual ~VirtualBase() {}
+};
+
+struct Derived : public Base, public virtual VirtualBase {
+  int d1;
+  Vector v;
+  int d2;
+  Derived() {
+d1 = 10;
+  }
+  ~Derived() {}
+};
+
+Derived d;
+
+// Destruction order:
+// Derived: int, Vector, Base, VirtualBase
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD1Ev
+// CHECK: call void {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN7DerivedD0Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD1Ev
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD0Ev
+// CHECK: ret void
+
+// poison 2 ints
+// CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 8)
+// CHECK: ret void
+
+// poison int and double
+// CHECK-LABEL: define {{.*}}ZN4BaseD2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 16)
+// CHECK: ret void
+
+// poison int, ignore vector, poison int
+// CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev
+// CHECK: call void {{.*}}ZN6VectorIiED1Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: call void {{.*}}ZN4BaseD2Ev
+// CHECK: ret void
+
+// poison int
+// CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev
+// CHECK: call void {{.*}}sanitizer_dtor_callback({{.*}}, i64 4)
+// CHECK: ret void
Index: test/CodeGenCXX/sanitize-dtor-bit-field.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-bit-field.cpp
@@ -0,0 +1,84 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// 24 bytes total
+struct Packed {
+  // Packed into 4 bytes
+  unsigned int a : 1;
+  unsigned int b : 1;
+  //unsigned int c : 1;
+  // Force alignment to next 4 bytes
+  unsigned int   : 0;
+  unsigned int d : 1;
+  // Force alignment, 8 more bytes
+  double e = 5.0;
+  // 4 bytes
+  unsigned int f : 1;
+  ~Packed() {}
+};
+Packed p;
+
+
+// 1 byte total
+struct Empty {
+  unsigned int : 0;
+  ~Empty() {}
+};
+Empty e;
+
+
+// 4 byte total
+struct Simple {
+  unsigned int a : 1;
+  ~Simple() {}
+};
+Simple s;
+
+
+// 8 bytes total
+struct Anon {
+  // 1 byte
+  unsigned int a : 1;
+  unsigned int b : 2;
+  // Force alignment to next byte
+  unsigned int   : 0;
+  unsigned int c : 1;
+  ~Anon() {}
+};
+Anon an;
+
+
+struct CharStruct {

r246815 - Refactored dtor sanitizing into EHScopeStack

2015-09-03 Thread Naomi Musgrave via cfe-commits
Author: nmusgrave
Date: Thu Sep  3 18:02:30 2015
New Revision: 246815

URL: http://llvm.org/viewvc/llvm-project?rev=246815&view=rev
Log:
Refactored dtor sanitizing into EHScopeStack

Summary:
Dtor sanitization handled amidst other dtor cleanups,
between cleaning bases and fields. Sanitizer call pushed onto
stack of cleanup operations.

Reviewers: eugenis, kcc

Differential Revision: http://reviews.llvm.org/D12022

Refactoring dtor sanitizing emission order.

- Support multiple inheritance by poisoning after
 member destructors are invoked, and before base
 class destructors are invoked.
- Poison for virtual destructor and virtual bases.
- Repress dtor aliasing when sanitizing in dtor.
- CFE test for dtor aliasing, and repression of aliasing in dtor
 code generation.
- Poison members on field-by-field basis, with collective poisoning
 of trivial members when possible.
- Check msan flags and existence of fields, before dtor sanitizing,
 and when determining if aliasing is allowed.
- Testing sanitizing bit fields.

Added:
cfe/trunk/test/CodeGenCXX/sanitize-dtor-bit-field.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp
cfe/trunk/test/CodeGenCXX/sanitize-dtor-repress-aliasing.cpp
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=246815&r1=246814&r2=246815&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Sep  3 18:02:30 2015
@@ -39,6 +39,12 @@ bool CodeGenModule::TryEmitBaseDestructo
   if (getCodeGenOpts().OptimizationLevel == 0)
 return true;
 
+  // If sanitizing memory to check for use-after-dtor, do not emit as
+  //  an alias, unless this class owns no members.
+  if (getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
+  !D->getParent()->field_empty())
+return true;
+
   // If the destructor doesn't have a trivial body, we have to emit it
   // separately.
   if (!D->hasTrivialBody())

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=246815&r1=246814&r2=246815&view=diff
==
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Sep  3 18:02:30 2015
@@ -1334,7 +1334,7 @@ HasTrivialDestructorBody(ASTContext &Con
 
 static bool
 FieldHasTrivialDestructorBody(ASTContext &Context,
-  const FieldDecl *Field)
+  const FieldDecl *Field)
 {
   QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
 
@@ -1353,7 +1353,7 @@ FieldHasTrivialDestructorBody(ASTContext
 
 /// CanSkipVTablePointerInitialization - Check whether we need to initialize
 /// any vtable pointers before calling this destructor.
-static bool CanSkipVTablePointerInitialization(ASTContext &Context,
+static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor) {
   if (!Dtor->hasTrivialBody())
 return false;
@@ -1361,58 +1361,12 @@ static bool CanSkipVTablePointerInitiali
   // Check the fields.
   const CXXRecordDecl *ClassDecl = Dtor->getParent();
   for (const auto *Field : ClassDecl->fields())
-if (!FieldHasTrivialDestructorBody(Context, Field))
+if (!FieldHasTrivialDestructorBody(CGF.getContext(), Field))
   return false;
 
   return true;
 }
 
-// Generates function call for handling object poisoning, passing in
-// references to 'this' and its size as arguments.
-// Disables tail call elimination, to prevent the current stack frame from
-// disappearing from the stack trace.
-static void EmitDtorSanitizerCallback(CodeGenFunction &CGF,
-  const CXXDestructorDecl *Dtor) {
-  const ASTRecordLayout &Layout =
-  CGF.getContext().getASTRecordLayout(Dtor->getParent());
-
-  // Nothing to poison
-  if(Layout.getFieldCount() == 0)
-return;
-
-  // Construct pointer to region to begin poisoning, and calculate poison
-  // size, so that only members declared in this class are poisoned.
-  llvm::Value *OffsetPtr;
-  CharUnits::QuantityType PoisonSize;
-  ASTContext &Context = CGF.getContext();
-
-  llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
-  CGF.SizeTy, Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).
-  getQuantity());
-
-  OffsetPtr = CGF.Builder.CreateGEP(CGF.Builder.CreateBitCast(
-  CGF.LoadCXXThis(), CGF.Int8PtrTy), OffsetSizePtr);
-
-  PoisonSize = Layout.getSize().getQuantity() -
-  Context.toCharUnitsFromBits(Layout.getFieldOffset(0)).getQuantity();
-
-  llvm::Value *Args[] = {
-CGF.Builder.CreateBitCast(OffsetPtr, CGF.VoidPtrT

[PATCH] D12616: Failing test highlighting no poisoning if dtor undeclared.

2015-09-03 Thread Naomi Musgrave via cfe-commits
nmusgrave created this revision.
nmusgrave added reviewers: eugenis, kcc.
nmusgrave added a subscriber: cfe-commits.

If class or struct has not declared a destructor,
no destsructor is emitted, and members are not poisoned
after destruction. This case highlights bug in current
implementation of use-after-dtor poisoning.

http://reviews.llvm.org/D12616

Files:
  test/CodeGenCXX/sanitize-dtor-generated.cpp

Index: test/CodeGenCXX/sanitize-dtor-generated.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-generated.cpp
@@ -0,0 +1,32 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+
+// TODO Success pending on resolution of issue 596
+// XFAIL: *
+
+template  class Vector {
+ public:
+  int size;
+  ~Vector() {}
+};
+
+struct NonTrivial {
+  int a;
+  Vector v;
+};
+NonTrivial nt;
+
+struct Trivial {
+  int a;
+  int b;
+};
+Trivial t;
+
+// CHECK-LABEL: define {{.*}}NonTrivialD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}TrivialD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: ret void


Index: test/CodeGenCXX/sanitize-dtor-generated.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-generated.cpp
@@ -0,0 +1,32 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// TODO Success pending on resolution of issue 596
+// XFAIL: *
+
+template  class Vector {
+ public:
+  int size;
+  ~Vector() {}
+};
+
+struct NonTrivial {
+  int a;
+  Vector v;
+};
+NonTrivial nt;
+
+struct Trivial {
+  int a;
+  int b;
+};
+Trivial t;
+
+// CHECK-LABEL: define {{.*}}NonTrivialD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: ret void
+
+// CHECK-LABEL: define {{.*}}TrivialD2Ev
+// CHECK: call void @__sanitizer_dtor_callback
+// CHECK: ret void
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12616: Failing test highlighting no poisoning if dtor undeclared.

2015-09-04 Thread Naomi Musgrave via cfe-commits
nmusgrave updated this revision to Diff 34094.
nmusgrave marked an inline comment as done.
nmusgrave added a comment.

- Only check simplest object for existence of sanitizing callback.


http://reviews.llvm.org/D12616

Files:
  test/CodeGenCXX/sanitize-dtor-generated.cpp

Index: test/CodeGenCXX/sanitize-dtor-generated.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-generated.cpp
@@ -0,0 +1,15 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor 
-disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | 
FileCheck %s
+
+// TODO Success pending on resolution of issue:
+//https://github.com/google/sanitizers/issues/596
+// XFAIL: *
+
+struct Trivial {
+  int a;
+  int b;
+};
+Trivial t;
+
+// CHECK: call void @__sanitizer_dtor_callback


Index: test/CodeGenCXX/sanitize-dtor-generated.cpp
===
--- /dev/null
+++ test/CodeGenCXX/sanitize-dtor-generated.cpp
@@ -0,0 +1,15 @@
+// Test -fsanitize-memory-use-after-dtor
+// RUN: %clang_cc1 -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -disable-llvm-optzns -std=c++11 -triple=x86_64-pc-linux -emit-llvm -o - %s | FileCheck %s
+
+// TODO Success pending on resolution of issue:
+//https://github.com/google/sanitizers/issues/596
+// XFAIL: *
+
+struct Trivial {
+  int a;
+  int b;
+};
+Trivial t;
+
+// CHECK: call void @__sanitizer_dtor_callback
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits