[PATCH] D97687: [SEH] Fix capture of this in lambda functions

2021-05-06 Thread Olivier Goffart via Phabricator via cfe-commits
ogoffart added a comment.

Looks like changing CurCodeDecl was not a good idea.
Fixed in https://reviews.llvm.org/D102027


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97687/new/

https://reviews.llvm.org/D97687

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


[PATCH] D97687: [SEH] Fix capture of this in lambda functions

2021-05-06 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Bisecting shows that this started to break

  $ cat test.cc
  void f() noexcept { __try {} __finally {} }
  $ clang-cl -EHs -c test.cc
  clang-cl: ~/github.com/llvm/llvm-project/clang/lib/CodeGen/CGCleanup.h:568: 
void clang::CodeGen::EHScopeStack::popTerminate(): Assertion `!empty() && 
"popping exception stack when not empty"' failed.
  PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash 
backtrace, preprocessed source, and associated run script.
  Stack dump:
  0.Program arguments: ~/llvm/inst/bin/clang-cl -EHs -c test.cc
  1. parser at end of file
  2.test.cc:1:6: LLVM IR generation of declaration 'f'
  3.test.cc:1:6: Generating code for declaration 'f'
   #0 0x7f2fd211624d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) 
~/github.com/llvm/llvm-project/llvm/lib/Support/Unix/Signals.inc:569:3
   #1 0x7f2fd2114174 llvm::sys::RunSignalHandlers() 
~/github.com/llvm/llvm-project/llvm/lib/Support/Signals.cpp:71:20
   #2 0x7f2fd20368c8 HandleCrash 
~/github.com/llvm/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:75:5
   #3 0x7f2fd20368c8 CrashRecoverySignalHandler(int) 
~/github.com/llvm/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp:388:62
   #4 0x7f2fd68f91e0 __restore_rt sigaction.c:0:0
   #5 0x7f2fd1a4b9d5 raise 
/usr/src/debug/glibc-2.32-37-g760e1d2878/signal/../sysdeps/unix/sysv/linux/raise.c:50:1
   #6 0x7f2fd1a348a4 abort 
/usr/src/debug/glibc-2.32-37-g760e1d2878/stdlib/abort.c:81:7
   #7 0x7f2fd1a34789 get_sysdep_segment_value 
/usr/src/debug/glibc-2.32-37-g760e1d2878/intl/loadmsgcat.c:509:8
   #8 0x7f2fd1a34789 _nl_load_domain.cold 
/usr/src/debug/glibc-2.32-37-g760e1d2878/intl/loadmsgcat.c:970:34
   #9 0x7f2fd1a44026 .annobin___GI___assert_fail.end assert.c:0:0
  #10 0x7f2fd5871973 
(~/llvm/inst/bin/../lib/libclangCodeGen.so.13git+0x44b973)
  #11 0x7f2fd587612a 
(~/llvm/inst/bin/../lib/libclangCodeGen.so.13git+0x45012a)
  #12 0x7f2fd5a85bbc 
clang::CodeGen::CodeGenFunction::FinishFunction(clang::SourceLocation) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:405:3
  #13 0x7f2fd587f703 
clang::CodeGen::CodeGenFunction::GenerateSEHFinallyFunction(clang::CodeGen::CodeGenFunction&,
 clang::SEHFinallyStmt const&) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CGException.cpp:2005:10
  #14 0x7f2fd587f776 pushCleanup<(anonymous namespace)::PerformSEHFinally, 
llvm::Function*> 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/EHScopeStack.h:273:31
  #15 0x7f2fd587f776 
clang::CodeGen::CodeGenFunction::EnterSEHTryStmt(clang::SEHTryStmt const&) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CGException.cpp:2082:43
  #16 0x7f2fd587fa87 
clang::CodeGen::CodeGenFunction::getJumpDestInCurrentScope(llvm::StringRef) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenFunction.h:1096:59
  #17 0x7f2fd587fa87 
clang::CodeGen::CodeGenFunction::EmitSEHTryStmt(clang::SEHTryStmt const&) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CGException.cpp:1605:65
  #18 0x7f2fd5a21de4 
clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt
 const&, bool, clang::CodeGen::AggValueSlot) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CGStmt.cpp:447:31
  #19 0x7f2fd5a8499b 
clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::Stmt const*) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:1185:36
  #20 0x7f2fd5a9214a clang::CodeGen::CodeGenModule::getLangOpts() const 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenModule.h:686:51
  #21 0x7f2fd5a9214a clang::CodeGen::CodeGenFunction::getLangOpts() const 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenFunction.h:1921:67
  #22 0x7f2fd5a9214a 
clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, 
llvm::Function*, clang::CodeGen::CGFunctionInfo const&) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp:1352:19
  #23 0x7f2fd5ad447c 
clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, 
llvm::GlobalValue*) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:4791:3
  #24 0x7f2fd5ad0f7b 
clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, 
llvm::GlobalValue*) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:3177:47
  #25 0x7f2fd5ad8c8a 
clang::CodeGen::CodeGenModule::EmitTopLevelDecl(clang::Decl*) (.part.0) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp:5895:1
  #26 0x7f2fd5b4e9a1 (anonymous 
namespace)::CodeGeneratorImpl::HandleTopLevelDecl(clang::DeclGroupRef) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp:169:67
  #27 0x7f2fd5a70b13 
clang::BackendConsumer::HandleTopLevelDecl(clang::DeclGroupRef) 
~/github.com/llvm/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:217:7
  #28 0x7f2fcfbbd814 clang::ParseAST(clang::Sema&, bool, bool) 
~/githu

[PATCH] D97687: [SEH] Fix capture of this in lambda functions

2021-03-11 Thread Olivier Goffart via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5baea0560160: [SEH] Fix capture of this in lambda functions 
(authored by ogoffart).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97687/new/

https://reviews.llvm.org/D97687

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp


Index: clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
===
--- clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
+++ clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -123,3 +123,25 @@
 // CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]]
 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]]
 // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]], i32 %[[l2]])
+
+struct U {
+  void this_in_lambda();
+};
+
+void U::this_in_lambda() {
+  auto lambda = [=]() {
+__try {
+  might_crash();
+} __except (basic_filter(0, this)) {
+}
+  };
+  lambda();
+}
+
+// CHECK-LABEL: define internal i32 
@"?filt$0@0@?R@?0??this_in_lambda@U@@QEAAXXZ@"(i8* 
%exception_pointers, i8* %frame_pointer)
+// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void 
(%class.anon.0*)* @"??R@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ" to 
i8*), i8* %[[fp:[^ ]*]], i32 0)
+// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0**
+// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** 
%[[this_ptr]], align 8
+// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, 
%class.anon.0* %[[this]], i32 0, i32 0
+// CHECK: %[[actual_this:[^ ]*]] = load %struct.U*, %struct.U** 
%[[actual_this_ptr]], align 8
+// CHECK: call i32 (i32, ...) @basic_filter(i32 0, %struct.U* %[[actual_this]])
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1879,8 +1879,24 @@
 setAddrOfLocalVar(VD, Recovered);
 
 if (isa(VD)) {
-  CXXThisValue = Builder.CreateLoad(Recovered, "this");
-  CXXABIThisValue = CXXThisValue;
+  CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
+  CXXThisAlignment = ParentCGF.CXXThisAlignment;
+  CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
+  if (ParentCGF.LambdaThisCaptureField) {
+LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;
+// We are in a lambda function where "this" is captured so the
+// CXXThisValue need to be loaded from the lambda capture
+LValue ThisFieldLValue =
+EmitLValueForLambdaField(LambdaThisCaptureField);
+if (!LambdaThisCaptureField->getType()->isPointerType()) {
+  CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer();
+} else {
+  CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
+ .getScalarVal();
+}
+  } else {
+CXXThisValue = CXXABIThisValue;
+  }
 }
   }
 
@@ -1949,6 +1965,7 @@
   StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
 OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
   CurSEHParent = ParentCGF.CurSEHParent;
+  CurCodeDecl = ParentCGF.CurCodeDecl;
 
   CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);
   EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);


Index: clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
===
--- clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
+++ clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -123,3 +123,25 @@
 // CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]]
 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]]
 // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]], i32 %[[l2]])
+
+struct U {
+  void this_in_lambda();
+};
+
+void U::this_in_lambda() {
+  auto lambda = [=]() {
+__try {
+  might_crash();
+} __except (basic_filter(0, this)) {
+}
+  };
+  lambda();
+}
+
+// CHECK-LABEL: define internal i32 @"?filt$0@0@?R@?0??this_in_lambda@U@@QEAAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
+// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon.0*)* @"??R@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ" to i8*), i8* %[[fp:[^ ]*]], i32 0)
+// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0**
+// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** %[[this_ptr]], align 8
+// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, %class.anon.0* %[[this]], i32 0, i32 0
+// CHECK: %[[actual_this:[^ ]*]] = load %struct.U*, %struct.U** %[[actual_this_ptr]], align 8
+// CHECK: call i32 (i32, ...) @basic_filter(i32 0, %struct.U* %[[actual_this]])
Index: clang/lib/CodeGen/CGException.cpp
=

[PATCH] D97687: [SEH] Fix capture of this in lambda functions

2021-03-10 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

lgtm


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97687/new/

https://reviews.llvm.org/D97687

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


[PATCH] D97687: [SEH] Fix capture of this in lambda functions

2021-03-03 Thread Olivier Goffart via Phabricator via cfe-commits
ogoffart added a comment.

Ping?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97687/new/

https://reviews.llvm.org/D97687

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


[PATCH] D97687: [SEH] Fix capture of this in lambda functions

2021-03-01 Thread Olivier Goffart via Phabricator via cfe-commits
ogoffart created this revision.
ogoffart added a reviewer: rnk.
ogoffart requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Commit 1b04bdc2f3ffaa7a0e1e3dbdc3a0cd08f0b9a4ce 
 added 
support for
capturing the 'this' pointer in a SEH context (__finally or __except),
But the case in which the 'this' pointer is part of a lamdda capture
was not handled properly


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D97687

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp


Index: clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
===
--- clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
+++ clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -123,3 +123,25 @@
 // CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]]
 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]]
 // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]], i32 %[[l2]])
+
+struct U {
+  void this_in_lambda();
+};
+
+void U::this_in_lambda() {
+  auto lambda = [=]() {
+__try {
+  might_crash();
+} __except (basic_filter(0, this)) {
+}
+  };
+  lambda();
+}
+
+// CHECK-LABEL: define internal i32 
@"?filt$0@0@?R@?0??this_in_lambda@U@@QEAAXXZ@"(i8* 
%exception_pointers, i8* %frame_pointer)
+// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void 
(%class.anon.0*)* @"??R@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ" to 
i8*), i8* %[[fp:[^ ]*]], i32 0)
+// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0**
+// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** 
%[[this_ptr]], align 8
+// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, 
%class.anon.0* %[[this]], i32 0, i32 0
+// CHECK: %[[actual_this:[^ ]*]] = load %struct.U*, %struct.U** 
%[[actual_this_ptr]], align 8
+// CHECK: call i32 (i32, ...) @basic_filter(i32 0, %struct.U* %[[actual_this]])
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1888,8 +1888,24 @@
 setAddrOfLocalVar(VD, Recovered);
 
 if (isa(VD)) {
-  CXXThisValue = Builder.CreateLoad(Recovered, "this");
-  CXXABIThisValue = CXXThisValue;
+  CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
+  CXXThisAlignment = ParentCGF.CXXThisAlignment;
+  CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
+  if (ParentCGF.LambdaThisCaptureField) {
+LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;
+// We are in a lambda function where "this" is captured so the
+// CXXThisValue need to be loaded from the lambda capture
+LValue ThisFieldLValue =
+EmitLValueForLambdaField(LambdaThisCaptureField);
+if (!LambdaThisCaptureField->getType()->isPointerType()) {
+  CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer();
+} else {
+  CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
+ .getScalarVal();
+}
+  } else {
+CXXThisValue = CXXABIThisValue;
+  }
 }
   }
 
@@ -1958,6 +1974,7 @@
   StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
 OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
   CurSEHParent = ParentCGF.CurSEHParent;
+  CurCodeDecl = ParentCGF.CurCodeDecl;
 
   CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);
   EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);


Index: clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
===
--- clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
+++ clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -123,3 +123,25 @@
 // CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]]
 // CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]]
 // CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]], i32 %[[l2]])
+
+struct U {
+  void this_in_lambda();
+};
+
+void U::this_in_lambda() {
+  auto lambda = [=]() {
+__try {
+  might_crash();
+} __except (basic_filter(0, this)) {
+}
+  };
+  lambda();
+}
+
+// CHECK-LABEL: define internal i32 @"?filt$0@0@?R@?0??this_in_lambda@U@@QEAAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
+// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon.0*)* @"??R@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ" to i8*), i8* %[[fp:[^ ]*]], i32 0)
+// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0**
+// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** %[[this_ptr]], align 8
+// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, %class.anon.0* %[[this]], i32 0, i32