diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-03-03 01:50:05 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-03-03 01:50:05 +0000 |
commit | d09a51c299ab277119b2e96b26ed9864c6404ebe (patch) | |
tree | ea05b065457d4b843e712b0964d957df7914a85c /clang/lib/Sema/SemaExprCXX.cpp | |
parent | 786ad180496d20cf224ba30b25a754cc2d934b2b (diff) | |
download | bcm5719-llvm-d09a51c299ab277119b2e96b26ed9864c6404ebe.tar.gz bcm5719-llvm-d09a51c299ab277119b2e96b26ed9864c6404ebe.zip |
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.
llvm-svn: 231049
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 27 |
1 files changed, 6 insertions, 21 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 695c3db1461..6ad0b24275a 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -660,24 +660,10 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, /// 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(SourceLocation ThrowLoc, Expr *E, 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(SourceLocation ThrowLoc, Expr *E, 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(); |