]> granicus.if.org Git - clang/commitdiff
[CodeGen] Handle __func__ inside __finally
authorShoaib Meenai <smeenai@fb.com>
Wed, 11 Apr 2018 18:17:35 +0000 (18:17 +0000)
committerShoaib Meenai <smeenai@fb.com>
Wed, 11 Apr 2018 18:17:35 +0000 (18:17 +0000)
When we enter a __finally block, the CGF's CurCodeDecl will be null
(because CodeGenFunction::StartFunction is given an empty GlobalDecl for
a __finally block), and so the dyn_cast here will result in an assertion
failure. Change it to dyn_cast_or_null to handle this case.

Differential Revision: https://reviews.llvm.org/D45523

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@329836 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
test/CodeGen/exceptions-seh-finally.c

index ba34208230f0777cadaf57c4eef606f8f347172a..55b67db6d0e8934d734a4804bba3f481f9e62de9 100644 (file)
@@ -2611,7 +2611,7 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
   StringRef NameItems[] = {
       PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName};
   std::string GVName = llvm::join(NameItems, NameItems + 2, ".");
-  if (auto *BD = dyn_cast<BlockDecl>(CurCodeDecl)) {
+  if (auto *BD = dyn_cast_or_null<BlockDecl>(CurCodeDecl)) {
     std::string Name = SL->getString();
     if (!Name.empty()) {
       unsigned Discriminator =
index 555e3ac25a81e5f932a132770c75735cbe815b1f..d863eb1bb47e65e7f10ba79d632a49d582a7446e 100644 (file)
@@ -268,6 +268,18 @@ void finally_within_finally() {
 // CHECK-LABEL: define internal void @"?fin$1@0@finally_within_finally@@"({{[^)]*}})
 // CHECK-SAME: [[finally_attrs]]
 
+void cleanup_with_func(const char *);
+void finally_with_func() {
+  __try {
+    might_crash();
+  } __finally {
+    cleanup_with_func(__func__);
+  }
+}
+
+// CHECK-LABEL: define internal void @"?fin$0@0@finally_with_func@@"({{[^)]*}})
+// CHECK: call void @cleanup_with_func(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@COAGBPGM@finally_with_func?$AA@", i32 0, i32 0))
+
 // Look for the absence of noinline. Enum attributes come first, so check that
 // a string attribute is the first to verify that no enum attributes are
 // present.