[cfe-commits] r131177 - in /cfe/trunk: lib/AST/Expr.cpp test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp

Douglas Gregor dgregor at apple.com
Wed May 11 13:50:21 PDT 2011


On May 10, 2011, at 10:22 PM, Eli Friedman wrote:

> 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.

Looks good, thanks!

	- Doug
> 
> 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>();
> }
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list