Hi rsmith,

This is an attempt to fix PR15481.

noexcept operator currently ignores whether given call is a constant 
expression. The patch adds a check whether given call expression is a constant 
expression. If so, canCalleeThrow returns CT_Cannot.

http://llvm-reviews.chandlerc.com/D538

Files:
  lib/Sema/SemaExceptionSpec.cpp
  test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp

Index: lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- lib/Sema/SemaExceptionSpec.cpp
+++ lib/Sema/SemaExceptionSpec.cpp
@@ -854,6 +854,16 @@
   if (!FT)
     return CT_Can;
 
+  // C++11: [expr.unary.noexcept]p3:
+  // The result of the noexcept operator is false if in a potentially-evaluated
+  // context the expression would contain:
+  // — a potentially evaluated call to a function, member function, function
+  //   pointer, or member function pointer that does not have a non-throwing
+  //   exception-specification (15.4), unless the call is a constant
+  //   expression (5.19),
+  if (isa<CallExpr>(E) && E->isCXX11ConstantExpr(S.getASTContext()))
+    return CT_Cannot;
+
   return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can;
 }
 
Index: test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
===================================================================
--- test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
+++ test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
@@ -23,6 +23,8 @@
 void nothrowattr() __attribute__((nothrow));
 void noexcept_true() noexcept;
 void noexcept_false() noexcept(false);
+constexpr int constant_expression(bool f) throw(int)
+{ return f ? 0 : throw 42; }
 
 void call() {
   N(nospec());
@@ -32,6 +34,8 @@
   P(nothrowattr());
   P(noexcept_true());
   N(noexcept_false());
+  P(constant_expression(true));
+  N(constant_expression(false));
 }
 
 void (*pnospec)();
Index: lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- lib/Sema/SemaExceptionSpec.cpp
+++ lib/Sema/SemaExceptionSpec.cpp
@@ -854,6 +854,16 @@
   if (!FT)
     return CT_Can;
 
+  // C++11: [expr.unary.noexcept]p3:
+  // The result of the noexcept operator is false if in a potentially-evaluated
+  // context the expression would contain:
+  // — a potentially evaluated call to a function, member function, function
+  //   pointer, or member function pointer that does not have a non-throwing
+  //   exception-specification (15.4), unless the call is a constant
+  //   expression (5.19),
+  if (isa<CallExpr>(E) && E->isCXX11ConstantExpr(S.getASTContext()))
+    return CT_Cannot;
+
   return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can;
 }
 
Index: test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
===================================================================
--- test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
+++ test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
@@ -23,6 +23,8 @@
 void nothrowattr() __attribute__((nothrow));
 void noexcept_true() noexcept;
 void noexcept_false() noexcept(false);
+constexpr int constant_expression(bool f) throw(int)
+{ return f ? 0 : throw 42; }
 
 void call() {
   N(nospec());
@@ -32,6 +34,8 @@
   P(nothrowattr());
   P(noexcept_true());
   N(noexcept_false());
+  P(constant_expression(true));
+  N(constant_expression(false));
 }
 
 void (*pnospec)();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to