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