r231049 - Sema: Properly initialize the thrown exception object

Rafael EspĂ­ndola rafael.espindola at gmail.com
Wed Mar 4 08:34:17 PST 2015


This might have caused http://llvm.org/bugs/show_bug.cgi?id=22789


On 2 March 2015 at 17:50, David Majnemer <david.majnemer at gmail.com> wrote:
> Author: majnemer
> Date: Mon Mar  2 19:50:05 2015
> New Revision: 231049
>
> URL: http://llvm.org/viewvc/llvm-project?rev=231049&view=rev
> Log:
> Sema: Properly initialize the thrown exception object
>
> We would create the exception object with the wrong qualifiers, ensuring
> that the wrong copy constructor would get called.
>
> Modified:
>     cfe/trunk/include/clang/AST/ASTContext.h
>     cfe/trunk/lib/AST/ASTContext.cpp
>     cfe/trunk/lib/Sema/SemaExprCXX.cpp
>     cfe/trunk/test/SemaCXX/exceptions.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=231049&r1=231048&r2=231049&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Mon Mar  2 19:50:05 2015
> @@ -1936,6 +1936,8 @@ public:
>    /// cv-qualifiers.
>    QualType getSignatureParameterType(QualType T) const;
>
> +  QualType getExceptionObjectType(QualType T) const;
> +
>    /// \brief Return the properly qualified result of decaying the specified
>    /// array type to a pointer.
>    ///
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=231049&r1=231048&r2=231049&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Mar  2 19:50:05 2015
> @@ -4338,6 +4338,19 @@ QualType ASTContext::getSignatureParamet
>    return T.getUnqualifiedType();
>  }
>
> +QualType ASTContext::getExceptionObjectType(QualType T) const {
> +  // C++ [except.throw]p3:
> +  //   A throw-expression initializes a temporary object, called the exception
> +  //   object, the type of which is determined by removing any top-level
> +  //   cv-qualifiers from the static type of the operand of throw and adjusting
> +  //   the type from "array of T" or "function returning T" to "pointer to T"
> +  //   or "pointer to function returning T", [...]
> +  T = getVariableArrayDecayedType(T);
> +  if (T->isArrayType() || T->isFunctionType())
> +    T = getDecayedType(T);
> +  return T.getUnqualifiedType();
> +}
> +
>  /// getArrayDecayedType - Return the properly qualified result of decaying the
>  /// specified array type to a pointer.  This operation is non-trivial when
>  /// handling typedefs etc.  The canonical type of "T" must be an array type,
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=231049&r1=231048&r2=231049&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Mar  2 19:50:05 2015
> @@ -660,24 +660,10 @@ ExprResult Sema::BuildCXXThrow(SourceLoc
>  /// CheckCXXThrowOperand - Validate the operand of a throw.
>  ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E,
>                                        bool IsThrownVarInScope) {
> -  // C++ [except.throw]p3:
> -  //   A throw-expression initializes a temporary object, called the exception
> -  //   object, the type of which is determined by removing any top-level
> -  //   cv-qualifiers from the static type of the operand of throw and adjusting
> -  //   the type from "array of T" or "function returning T" to "pointer to T"
> -  //   or "pointer to function returning T", [...]
> -  if (E->getType().hasQualifiers())
> -    E = ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
> -                          E->getValueKind()).get();
> -
> -  ExprResult Res = DefaultFunctionArrayConversion(E);
> -  if (Res.isInvalid())
> -    return ExprError();
> -  E = Res.get();
> -
> +  QualType ExceptionObjectTy = Context.getExceptionObjectType(E->getType());
>    //   If the type of the exception would be an incomplete type or a pointer
>    //   to an incomplete type other than (cv) void the program is ill-formed.
> -  QualType Ty = E->getType();
> +  QualType Ty = ExceptionObjectTy;
>    bool isPointer = false;
>    if (const PointerType* Ptr = Ty->getAs<PointerType>()) {
>      Ty = Ptr->getPointeeType();
> @@ -690,7 +676,7 @@ ExprResult Sema::CheckCXXThrowOperand(So
>                              E->getSourceRange()))
>        return ExprError();
>
> -    if (RequireNonAbstractType(ThrowLoc, E->getType(),
> +    if (RequireNonAbstractType(ThrowLoc, ExceptionObjectTy,
>                                 diag::err_throw_abstract_type, E))
>        return ExprError();
>    }
> @@ -714,11 +700,10 @@ ExprResult Sema::CheckCXXThrowOperand(So
>      NRVOVariable = getCopyElisionCandidate(QualType(), E, false);
>
>    InitializedEntity Entity =
> -      InitializedEntity::InitializeException(ThrowLoc, E->getType(),
> +      InitializedEntity::InitializeException(ThrowLoc, ExceptionObjectTy,
>                                               /*NRVO=*/NRVOVariable != nullptr);
> -  Res = PerformMoveOrCopyInitialization(Entity, NRVOVariable,
> -                                        QualType(), E,
> -                                        IsThrownVarInScope);
> +  ExprResult Res = PerformMoveOrCopyInitialization(
> +      Entity, NRVOVariable, QualType(), E, IsThrownVarInScope);
>    if (Res.isInvalid())
>      return ExprError();
>    E = Res.get();
>
> Modified: cfe/trunk/test/SemaCXX/exceptions.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/exceptions.cpp?rev=231049&r1=231048&r2=231049&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/exceptions.cpp (original)
> +++ cfe/trunk/test/SemaCXX/exceptions.cpp Mon Mar  2 19:50:05 2015
> @@ -145,3 +145,16 @@ namespace Decay {
>  }
>
>  void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} expected-warning {{C++11}}
> +
> +namespace ConstVolatile {
> +struct S {
> +  S() {}         // expected-note{{candidate constructor not viable}}
> +  S(const S &s); // expected-note{{candidate constructor not viable}}
> +};
> +
> +typedef const volatile S CVS;
> +
> +void f() {
> +  throw CVS(); // expected-error{{no matching constructor for initialization}}
> +}
> +}
>
>
> _______________________________________________
> 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