First version of a testcase, plus fixes.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Fri, 10 Sep 2010 20:55:47 +0000 (20:55 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Fri, 10 Sep 2010 20:55:47 +0000 (20:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113624 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Expr.cpp
lib/AST/ExprConstant.cpp
test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp [new file with mode: 0644]

index 35456b38efcfe1086c9359ca4f2f0d548527df4d..435f7548ea5a5f0ebb55e49cfe252ded18c0af41 100644 (file)
@@ -1369,6 +1369,9 @@ static Expr::CanThrowResult CanDynamicCastThrow(const CXXDynamicCastExpr *DC) {
   if (DC->isTypeDependent())
     return Expr::CT_Dependent;
 
+  if (!DC->getTypeAsWritten()->isReferenceType())
+    return Expr::CT_Cannot;
+
   return DC->getCastKind() == clang::CK_Dynamic? Expr::CT_Can : Expr::CT_Cannot;
 }
 
@@ -1429,7 +1432,8 @@ Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const {
     return MergeCanThrow(CT, CanSubExprsThrow(C, this));
   }
 
-  case CXXConstructExprClass: {
+  case CXXConstructExprClass:
+  case CXXTemporaryObjectExprClass: {
     CanThrowResult CT = CanCalleeThrow(
         cast<CXXConstructExpr>(this)->getConstructor());
     if (CT == CT_Can)
@@ -1479,7 +1483,6 @@ Expr::CanThrowResult Expr::CanThrow(ASTContext &C) const {
   case CXXDefaultArgExprClass:
   case CXXBindTemporaryExprClass:
   case CXXExprWithTemporariesClass:
-  case CXXTemporaryObjectExprClass:
   case ObjCIvarRefExprClass:
   case ObjCIsaExprClass:
   case ShuffleVectorExprClass:
index 165dd4d0c017894e192090fc5e44be1adddf6247..c2b981cdbc260d2a9701f9054a1991dffc3aa3df 100644 (file)
@@ -958,6 +958,8 @@ public:
   bool VisitUnaryReal(const UnaryOperator *E);
   bool VisitUnaryImag(const UnaryOperator *E);
 
+  bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
+
 private:
   CharUnits GetAlignOfExpr(const Expr *E);
   CharUnits GetAlignOfType(QualType T);
@@ -1740,6 +1742,10 @@ bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
   return Success(0, E);
 }
 
+bool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
+  return Success(E->getValue(), E);
+}
+
 //===----------------------------------------------------------------------===//
 // Float Evaluation
 //===----------------------------------------------------------------------===//
diff --git a/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp b/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
new file mode 100644 (file)
index 0000000..c1865fc
--- /dev/null
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fms-extensions %s
+
+#define P(e) static_assert(noexcept(e), "expected nothrow")
+#define N(e) static_assert(!noexcept(e), "expected throw")
+
+void simple() {
+  P(0);
+  P(0 + 0);
+  int i;
+  P(i);
+  P(sizeof(0));
+  P(static_cast<int>(0));
+  N(throw 0);
+}
+
+void nospec();
+void allspec() throw(...);
+void intspec() throw(int);
+void emptyspec() throw();
+
+void call() {
+  N(nospec());
+  N(allspec());
+  N(intspec());
+  P(emptyspec());
+}
+
+void (*pnospec)();
+void (*pallspec)() throw(...);
+void (*pintspec)() throw(int);
+void (*pemptyspec)() throw();
+
+void callptr() {
+  N(pnospec());
+  N((*pnospec)());
+  N(pallspec());
+  N((*pallspec)());
+  N(pintspec());
+  N((*pintspec)());
+  P(pemptyspec());
+  P((*pemptyspec)());
+}
+
+struct S1 {
+  void nospec();
+  void allspec() throw(...);
+  void intspec() throw(int);
+  void emptyspec() throw();
+};
+
+void callmem() {
+  S1 s;
+  N(s.nospec());
+  N(s.allspec());
+  N(s.intspec());
+  P(s.emptyspec());
+}
+
+void (S1::*mpnospec)();
+void (S1::*mpallspec)() throw(...);
+void (S1::*mpintspec)() throw(int);
+void (S1::*mpemptyspec)() throw();
+
+void callmemptr() {
+  S1 s;
+  N((s.*mpnospec)());
+  N((s.*mpallspec)());
+  N((s.*mpintspec)());
+  P((s.*mpemptyspec)());
+}
+
+struct S2 {
+  S2();
+  S2(int, int) throw();
+  void operator +();
+  void operator -() throw();
+  void operator +(int);
+  void operator -(int) throw();
+  operator int();
+  operator float() throw();
+};
+
+void *operator new(__typeof__(sizeof(int)) sz, int) throw();
+
+void implicits() {
+  N(new int);
+  P(new (0) int);
+  N(S2());
+  P(S2(0, 0));
+  S2 s;
+  N(+s);
+  P(-s);
+  N(s + 0);
+  P(s - 0);
+  N(static_cast<int>(s));
+  P(static_cast<float>(s));
+  // FIXME: test destructors of temporaries
+}
+
+struct V {
+  virtual ~V() throw();
+};
+struct D : V {};
+
+void dyncast() {
+  V *pv = 0;
+  D *pd = 0;
+  P(dynamic_cast<V&>(*pd));
+  P(dynamic_cast<V*>(pd));
+  N(dynamic_cast<D&>(*pv));
+  P(dynamic_cast<D*>(pv));
+}
+
+namespace std {
+  struct type_info {};
+}
+
+void idtype() {
+  P(typeid(V));
+  P(typeid((V*)0));
+  P(typeid(*(S1*)0));
+  N(typeid(*(V*)0));
+}
+
+void uneval() {
+  P(sizeof(typeid(*(V*)0)));
+  P(typeid(typeid(*(V*)0)));
+}