[cfe-commits] r113621 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/Expr.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Fri Sep 10 15:27:01 PDT 2010


On Sep 10, 2010, at 2:58 PM, Douglas Gregor wrote:

> On Sep 10, 2010, at 1:55 PM, Sebastian Redl wrote:
> 
>> Author: cornedbee
>> Date: Fri Sep 10 15:55:33 2010
>> New Revision: 113621
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=113621&view=rev
>> Log:
>> Implement Expr::CanThrow, a function that applies the noexcept operator rules to expressions.
>> 
>> Modified:
>>   cfe/trunk/include/clang/AST/Expr.h
>>   cfe/trunk/lib/AST/Expr.cpp
>> 
>> +static Expr::CanThrowResult CanCalleeThrow(const Decl *D,
>> +                                           bool NullThrows = true) {
>> +  if (!D)
>> +    return NullThrows ? Expr::CT_Can : Expr::CT_Cannot;
>> +
>> +  // See if we can get a function type from the decl somehow.
>> +  const ValueDecl *VD = dyn_cast<ValueDecl>(D);
>> +  if (!VD) // If we have no clue what we're calling, assume the worst.
>> +    return Expr::CT_Can;
>> +
>> +  QualType T = VD->getType();
>> +  const FunctionProtoType *FT;
>> +  if ((FT = T->getAs<FunctionProtoType>())) {
>> +  } else if (const PointerType *PT = T->getAs<PointerType>())
>> +    FT = PT->getPointeeType()->getAs<FunctionProtoType>();
>> +  else if (const ReferenceType *RT = T->getAs<ReferenceType>())
>> +    FT = RT->getPointeeType()->getAs<FunctionProtoType>();
>> +  else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
>> +    FT = MT->getPointeeType()->getAs<FunctionProtoType>();
>> +  else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
>> +    FT = BT->getPointeeType()->getAs<FunctionProtoType>();
>> +
>> +  if (!FT)
>> +    return Expr::CT_Can;
>> +
>> +  return FT->hasEmptyExceptionSpec() ? Expr::CT_Cannot : Expr::CT_Can;
>> +}
> 
> We should also be checking whether D is a FunctionDecl with the nothrow attribute. At least, I think GCC does this.

Fixed.

>> +  case CXXConstructExprClass: {
>> +    CanThrowResult CT = CanCalleeThrow(
>> +        cast<CXXConstructExpr>(this)->getConstructor());
>> +    if (CT == CT_Can)
>> +      return CT;
>> +    return MergeCanThrow(CT, CanSubExprsThrow(C, this));
>> +  }
> 
> CXXTemporaryObjectExprClass?
> 

That's part of the testcase commit, I failed to rewrite history in a way that makes sense here.

>> 
>> +  case CXXExprWithTemporariesClass:
> 
> CXXExprWithTemporaries is where we'll end up calling the destructors for temporary objects.

Yep, I still have to implement this part.



More information about the cfe-commits mailing list