First version of a testcase, plus fixes.

llvm-svn: 113624
This commit is contained in:
Sebastian Redl 2010-09-10 20:55:47 +00:00
parent 4202c0f2a9
commit 5f0180d815
3 changed files with 139 additions and 2 deletions

View 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:

View 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
//===----------------------------------------------------------------------===//

View File

@ -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)));
}