This might have caused http://llvm.org/bugs/show_bug.cgi?id=22789
On 2 March 2015 at 17:50, David Majnemer <[email protected]> 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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
