[cfe-commits] r131177 - in /cfe/trunk: lib/AST/Expr.cpp test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
Eli Friedman
eli.friedman at gmail.com
Tue May 10 22:22:44 PDT 2011
Author: efriedma
Date: Wed May 11 00:22:44 2011
New Revision: 131177
URL: http://llvm.org/viewvc/llvm-project?rev=131177&view=rev
Log:
PR9882: Fix noexcept to deal with dependent new, delete, calls, and
dynamic_cast correctly.
Modified:
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=131177&r1=131176&r2=131177&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Wed May 11 00:22:44 2011
@@ -1693,6 +1693,9 @@
if (!DC->getTypeAsWritten()->isReferenceType())
return Expr::CT_Cannot;
+ if (DC->getSubExpr()->isTypeDependent())
+ return Expr::CT_Dependent;
+
return DC->getCastKind() == clang::CK_Dynamic? Expr::CT_Can : Expr::CT_Cannot;
}
@@ -1747,7 +1750,11 @@
case CallExprClass:
case CXXOperatorCallExprClass:
case CXXMemberCallExprClass: {
- CanThrowResult CT = CanCalleeThrow(C,cast<CallExpr>(this)->getCalleeDecl());
+ CanThrowResult CT;
+ if (isTypeDependent())
+ CT = CT_Dependent;
+ else
+ CT = CanCalleeThrow(C, cast<CallExpr>(this)->getCalleeDecl());
if (CT == CT_Can)
return CT;
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
@@ -1763,7 +1770,11 @@
}
case CXXNewExprClass: {
- CanThrowResult CT = MergeCanThrow(
+ CanThrowResult CT;
+ if (isTypeDependent())
+ CT = CT_Dependent;
+ else
+ CT = MergeCanThrow(
CanCalleeThrow(C, cast<CXXNewExpr>(this)->getOperatorNew()),
CanCalleeThrow(C, cast<CXXNewExpr>(this)->getConstructor(),
/*NullThrows*/false));
@@ -1773,22 +1784,18 @@
}
case CXXDeleteExprClass: {
- CanThrowResult CT = CanCalleeThrow(C,
- cast<CXXDeleteExpr>(this)->getOperatorDelete());
- if (CT == CT_Can)
- return CT;
- const Expr *Arg = cast<CXXDeleteExpr>(this)->getArgument();
- // Unwrap exactly one implicit cast, which converts all pointers to void*.
- if (const ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
- Arg = Cast->getSubExpr();
- if (const PointerType *PT = Arg->getType()->getAs<PointerType>()) {
- if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>()) {
- CanThrowResult CT2 = CanCalleeThrow(C,
- cast<CXXRecordDecl>(RT->getDecl())->getDestructor());
- if (CT2 == CT_Can)
- return CT2;
- CT = MergeCanThrow(CT, CT2);
+ CanThrowResult CT;
+ QualType DTy = cast<CXXDeleteExpr>(this)->getDestroyedType();
+ if (DTy.isNull() || DTy->isDependentType()) {
+ CT = CT_Dependent;
+ } else {
+ CT = CanCalleeThrow(C, cast<CXXDeleteExpr>(this)->getOperatorDelete());
+ if (const RecordType *RT = DTy->getAs<RecordType>()) {
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ CT = MergeCanThrow(CT, CanCalleeThrow(C, RD->getDestructor()));
}
+ if (CT == CT_Can)
+ return CT;
}
return MergeCanThrow(CT, CanSubExprsThrow(C, this));
}
Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp?rev=131177&r1=131176&r2=131177&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp Wed May 11 00:22:44 2011
@@ -155,12 +155,16 @@
N(G3());
}
+template <class T> void f(T&&) noexcept;
template <typename T, bool b>
void late() {
B(b, typeid(*(T*)0));
B(b, T(1));
B(b, static_cast<T>(S2(0, 0)));
B(b, S1() + T());
+ P(f(T()));
+ P(new (0) T);
+ P(delete (T*)0);
}
struct S3 {
virtual ~S3() throw();
@@ -168,9 +172,15 @@
explicit S3(int);
S3(const S2&);
};
+template <class T> T&& f2() noexcept;
+template <typename T>
+void late2() {
+ P(dynamic_cast<S3&>(f2<T&>()));
+}
void operator +(const S1&, float) throw();
void operator +(const S1&, const S3&);
void tlate() {
late<float, true>();
late<S3, false>();
+ late2<S3>();
}
More information about the cfe-commits
mailing list