[cfe-commits] r166404 - in /cfe/trunk: include/clang/Sema/Sema.h lib/AST/DumpXML.cpp test/CXX/except/except.spec/p14.cpp

Richard Smith richard-llvm at metafoo.co.uk
Sun Oct 21 16:00:34 PDT 2012


Author: rsmith
Date: Sun Oct 21 18:00:34 2012
New Revision: 166404

URL: http://llvm.org/viewvc/llvm-project?rev=166404&view=rev
Log:
PR14141 (part of DR1351): An implicitly-deduced "any" exception specification
produces an exception of 'noexcept(false)' and is thus compatible with an
explicit exception specification of 'noexcept(false)'.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/DumpXML.cpp
    cfe/trunk/test/CXX/except/except.spec/p14.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=166404&r1=166403&r2=166404&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Oct 21 18:00:34 2012
@@ -3376,18 +3376,11 @@
     // Pointer to allow copying
     Sema *Self;
     // We order exception specifications thus:
-    // noexcept is the most restrictive, but is only used in C++0x.
+    // noexcept is the most restrictive, but is only used in C++11.
     // throw() comes next.
     // Then a throw(collected exceptions)
-    // Finally no specification.
+    // Finally no specification, which is expressed as noexcept(false).
     // throw(...) is used instead if any called function uses it.
-    //
-    // If this exception specification cannot be known yet (for instance,
-    // because this is the exception specification for a defaulted default
-    // constructor and we haven't finished parsing the deferred parts of the
-    // class yet), the C++0x standard does not specify how to behave. We
-    // record this as an 'unknown' exception specification, which overrules
-    // any other specification (even 'none', to keep this rule simple).
     ExceptionSpecificationType ComputedEST;
     llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen;
     SmallVector<QualType, 4> Exceptions;
@@ -3427,8 +3420,17 @@
     /// computed exception specification.
     void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const {
       EPI.ExceptionSpecType = getExceptionSpecType();
-      EPI.NumExceptions = size();
-      EPI.Exceptions = data();
+      if (EPI.ExceptionSpecType == EST_Dynamic) {
+        EPI.NumExceptions = size();
+        EPI.Exceptions = data();
+      } else if (EPI.ExceptionSpecType == EST_None) {
+        /// C++11 [except.spec]p14:
+        ///   The exception-specification is noexcept(false) if the set of
+        ///   potential exceptions of the special member function contains "any"
+        EPI.ExceptionSpecType = EST_ComputedNoexcept;
+        EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
+                                                     tok::kw_false).take();
+      }
     }
     FunctionProtoType::ExtProtoInfo getEPI() const {
       FunctionProtoType::ExtProtoInfo EPI;

Modified: cfe/trunk/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DumpXML.cpp?rev=166404&r1=166403&r2=166404&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DumpXML.cpp (original)
+++ cfe/trunk/lib/AST/DumpXML.cpp Sun Oct 21 18:00:34 2012
@@ -977,6 +977,16 @@
     setFlag("const", T->isConst());
     setFlag("volatile", T->isVolatile());
     setFlag("restrict", T->isRestrict());
+    switch (T->getExceptionSpecType()) {
+    case EST_None: break;
+    case EST_DynamicNone: set("exception_spec", "throw()"); break;
+    case EST_Dynamic: set("exception_spec", "throw(T)"); break;
+    case EST_MSAny: set("exception_spec", "throw(...)"); break;
+    case EST_BasicNoexcept: set("exception_spec", "noexcept"); break;
+    case EST_ComputedNoexcept: set("exception_spec", "noexcept(expr)"); break;
+    case EST_Unevaluated: set("exception_spec", "unevaluated"); break;
+    case EST_Uninstantiated: set("exception_spec", "uninstantiated"); break;
+    }
   }
   void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
     push("parameters");

Modified: cfe/trunk/test/CXX/except/except.spec/p14.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/except/except.spec/p14.cpp?rev=166404&r1=166403&r2=166404&view=diff
==============================================================================
--- cfe/trunk/test/CXX/except/except.spec/p14.cpp (original)
+++ cfe/trunk/test/CXX/except/except.spec/p14.cpp Sun Oct 21 18:00:34 2012
@@ -63,3 +63,41 @@
   static_assert(!noexcept(X(X::val())), "");
   static_assert(!noexcept(X::ref() = X::val()), "");
 }
+
+namespace PR14141 {
+  // Part of DR1351: the implicit exception-specification is noexcept(false) if
+  // the set of potential exceptions of the special member function contains
+  // "any". Hence it is compatible with noexcept(false).
+  struct ThrowingBase {
+    ThrowingBase() noexcept(false);
+    ThrowingBase(const ThrowingBase&) noexcept(false);
+    ThrowingBase(ThrowingBase&&) noexcept(false);
+    ThrowingBase &operator=(const ThrowingBase&) noexcept(false);
+    ThrowingBase &operator=(ThrowingBase&&) noexcept(false);
+    ~ThrowingBase() noexcept(false);
+  };
+  struct Derived : ThrowingBase {
+    Derived() noexcept(false) = default;
+    Derived(const Derived&) noexcept(false) = default;
+    Derived(Derived&&) noexcept(false) = default;
+    Derived &operator=(const Derived&) noexcept(false) = default;
+    Derived &operator=(Derived&&) noexcept(false) = default;
+    ~Derived() noexcept(false) = default;
+  };
+  struct Derived2 : ThrowingBase {
+    Derived2() = default;
+    Derived2(const Derived2&) = default;
+    Derived2(Derived2&&) = default;
+    Derived2 &operator=(const Derived2&) = default;
+    Derived2 &operator=(Derived2&&) = default;
+    ~Derived2() = default;
+  };
+  struct Derived3 : ThrowingBase {
+    Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
+    Derived3(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
+    Derived3(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
+    Derived3 &operator=(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
+    Derived3 &operator=(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
+    ~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
+  };
+}





More information about the cfe-commits mailing list