if (isa<CXXConstructorDecl>(Function)) {
// Add the user-defined conversion step. Any cv-qualification conversion is
- // subsumed by the initialization.
- Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType,
+ // subsumed by the initialization. Per DR5, the created temporary is of the
+ // cv-unqualified type of the destination.
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl,
+ DestType.getUnqualifiedType(),
HadMultipleCandidates);
return;
}
// Add the user-defined conversion step that calls the conversion function.
QualType ConvType = Function->getCallResultType();
if (ConvType->getAs<RecordType>()) {
- // If we're converting to a class type, there may be an copy if
+ // If we're converting to a class type, there may be an copy of
// the resulting temporary object (possible to create an object of
// a base class type). That copy is not a separate conversion, so
// we just make a note of the actual destination type (possibly a
Loc, ConstructorArgs))
return ExprError();
- // Build the an expression that constructs a temporary.
+ // Build an expression that constructs a temporary.
CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
move_arg(ConstructorArgs),
HadMultipleCandidates,
f(foo);
}
}
+
+namespace DR5 {
+ // Core issue 5: if a temporary is created in copy-initialization, it is of
+ // the cv-unqualified version of the destination type.
+ namespace Ex1 {
+ struct C { };
+ C c;
+ struct A {
+ A(const A&);
+ A(const C&);
+ };
+ const volatile A a = c; // ok
+ }
+
+ namespace Ex2 {
+ struct S {
+ S(S&&); // expected-warning {{C++11}}
+ S(int);
+ };
+ const S a(0);
+ const S b = 0;
+ }
+}