[clang] d94bacb - [WebAssembly] Handle exception specifications

Heejin Ahn via cfe-commits cfe-commits at lists.llvm.org
Tue May 19 01:18:32 PDT 2020


Author: Heejin Ahn
Date: 2020-05-19T01:16:09-07:00
New Revision: d94bacbcf87a06abc0c1fc3405406399460debc3

URL: https://github.com/llvm/llvm-project/commit/d94bacbcf87a06abc0c1fc3405406399460debc3
DIFF: https://github.com/llvm/llvm-project/commit/d94bacbcf87a06abc0c1fc3405406399460debc3.diff

LOG: [WebAssembly] Handle exception specifications

Summary:
Wasm currently does not fully handle exception specifications. Rather
than crashing,
- This treats `throw()` in the same way as `noexcept`.
- This ignores and prints a warning for `throw(type, ..)`, for a
  temporary measure. This warning is controlled by
  `-Wwasm-exception-spec`, which is on by default. You can suppress the
  warning by using `-Wno-wasm-exception-spec`.

Reviewers: dschuff

Subscribers: sbc100, jgravelle-google, sunfish, cfe-commits

Tags: #clang

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

Added: 
    

Modified: 
    clang/docs/DiagnosticsReference.rst
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/CodeGen/CGException.cpp
    clang/test/CodeGenCXX/wasm-eh.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/DiagnosticsReference.rst b/clang/docs/DiagnosticsReference.rst
index 402ec9d4eba6..2fab8b5f3026 100644
--- a/clang/docs/DiagnosticsReference.rst
+++ b/clang/docs/DiagnosticsReference.rst
@@ -14010,3 +14010,10 @@ This diagnostic is enabled by default.
 +------------------------------------------------------------------------+
 
 
+-Wwasm-exception-spec
+---------------------
+**Diagnostic text:**
+
++----------------------------------------------------------------------------------------------------------------+
+|:warning:`warning:` |nbsp| :diagtext:`dynamic exception specifications with types are currently ignored in wasm`|
++----------------------------------------------------------------------------------------------------------------+

diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index c9104da66f1f..3f0521615a5e 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1207,3 +1207,5 @@ Note that the warning is disabled by default, so -Wmax-tokens must be used
 in addition with the pragmas or -fmax-tokens flag to get any warnings.
 }];
 }
+
+def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 55d35be8f939..d415802916b6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1590,6 +1590,9 @@ def err_exception_spec_cycle : Error<
   "exception specification of %0 uses itself">;
 def err_exception_spec_incomplete_type : Error<
   "exception specification needed for member of incomplete class %0">;
+def warn_wasm_dynamic_exception_spec_ignored : ExtWarn<
+  "dynamic exception specifications with types are currently ignored in wasm">,
+  InGroup<WebAssemblyExceptionSpec>;
 
 // C++ access checking
 def err_class_redeclared_with_
diff erent_access : Error<

diff  --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index a5dae1b32e69..d821eb2d5595 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/Intrinsics.h"
@@ -468,6 +469,18 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
     // encode these in an object file but MSVC doesn't do anything with it.
     if (getTarget().getCXXABI().isMicrosoft())
       return;
+    // In wasm we currently treat 'throw()' in the same way as 'noexcept'. In
+    // case of throw with types, we ignore it and print a warning for now.
+    // TODO Correctly handle exception specification in wasm
+    if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly) {
+      if (EST == EST_DynamicNone)
+        EHStack.pushTerminate();
+      else
+        CGM.getDiags().Report(D->getLocation(),
+                              diag::warn_wasm_dynamic_exception_spec_ignored)
+            << FD->getExceptionSpecSourceRange();
+      return;
+    }
     unsigned NumExceptions = Proto->getNumExceptions();
     EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
 
@@ -544,6 +557,14 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
     // encode these in an object file but MSVC doesn't do anything with it.
     if (getTarget().getCXXABI().isMicrosoft())
       return;
+    // In wasm we currently treat 'throw()' in the same way as 'noexcept'. In
+    // case of throw with types, we ignore it and print a warning for now.
+    // TODO Correctly handle exception specification in wasm
+    if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly) {
+      if (EST == EST_DynamicNone)
+        EHStack.popTerminate();
+      return;
+    }
     EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
     emitFilterDispatchBlock(*this, filterScope);
     EHStack.popFilter();

diff  --git a/clang/test/CodeGenCXX/wasm-eh.cpp b/clang/test/CodeGenCXX/wasm-eh.cpp
index 17f325bd9eba..cd18ed406d7e 100644
--- a/clang/test/CodeGenCXX/wasm-eh.cpp
+++ b/clang/test/CodeGenCXX/wasm-eh.cpp
@@ -7,7 +7,6 @@
 // RUN: rm -f %S/wasm-eh.ll
 // RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
 // RUN: %clang_cc1 %s -triple wasm64-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 | FileCheck %s
-// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -S -o - -std=c++11 | FileCheck %s --check-prefix=ASSEMBLY
 
 void may_throw();
 void dont_throw() noexcept;
@@ -391,9 +390,34 @@ void test8() {
 
 // CHECK:   unreachable
 
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-DEFAULT
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -Wwasm-exception-spec -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-ON
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -Wno-wasm-exception-spec -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-OFF
+
+// Wasm ignores dynamic exception specifications with types at the moment. This
+// is controlled by -Wwasm-exception-spec, which is on by default. This warning
+// can be suppressed with -Wno-wasm-exception-spec.
+// Checks if a warning message is correctly printed or not printed depending on
+// the options.
+void test9() throw(int) {
+}
+// WARNING-DEFAULT: warning: dynamic exception specifications with types are currently ignored in wasm
+// WARNING-ON: warning: dynamic exception specifications with types are currently ignored in wasm
+// WARNING-OFF-NOT: warning: dynamic exception specifications with types are currently ignored in wasm
+
+// Wasm curremtly treats 'throw()' in the same way as 'noexept'. Check if the
+// same warning message is printed as if when a 'noexcept' function throws.
+void test10() throw() {
+  throw 3;
+}
+// WARNING-DEFAULT: warning: 'test10' has a non-throwing exception specification but can still throw
+// WARNING-DEFAULT: function declared non-throwing here
+
 // Here we only check if the command enables wasm exception handling in the
 // backend so that exception handling instructions can be generated in .s file.
 
+// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -fwasm-exceptions -target-feature +exception-handling -S -o - -std=c++11 | FileCheck %s --check-prefix=ASSEMBLY
+
 // ASSEMBLY: try
 // ASSEMBLY: catch
 // ASSEMBLY: rethrow


        


More information about the cfe-commits mailing list