r231049 - Sema: Properly initialize the thrown exception object
David Majnemer
david.majnemer at gmail.com
Mon Mar 2 17:50:05 PST 2015
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}}
+}
+}
More information about the cfe-commits
mailing list