Initial step toward supporting qualification conversions (C++ 4.4).
Changes:
- Sema::IsQualificationConversion determines whether we have a qualification
conversion.
- Sema::CheckSingleAssignment constraints now follows the C++ rules in C++,
performing an implicit conversion from the right-hand side to the type of
the left-hand side rather than checking based on the C notion of
"compatibility". We now rely on the implicit-conversion code to
determine whether the conversion can happen or
not. Sema::TryCopyInitialization has an ugly reference-related
hack to cope with the initialization of references, for now.
- When building DeclRefExprs, strip away the reference type, since
there are no expressions whose type is a reference. We'll need to
do this throughout Sema.
- Expr::isLvalue now permits functions to be lvalues in C++ (but not
in C).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57935 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 7a3c6bd..3ead430 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -450,7 +450,7 @@
}
// If this reference is not in a block or if the referenced variable is
// within the block, create a normal DeclRefExpr.
- return new DeclRefExpr(VD, VD->getType(), Loc);
+ return new DeclRefExpr(VD, GetNonReferenceType(VD->getType()), Loc);
}
Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
@@ -1565,8 +1565,7 @@
// 3 & 4 (below). ...and the type *pointed to* by the left has all the
// qualifiers of the type *pointed to* by the right;
// FIXME: Handle ASQualType
- if ((lhptee.getCVRQualifiers() & rhptee.getCVRQualifiers()) !=
- rhptee.getCVRQualifiers())
+ if (!lhptee.isAtLeastAsQualifiedAs(rhptee))
ConvTy = CompatiblePointerDiscardsQualifiers;
// C99 6.5.16.1p1 (constraint 4): If one operand is a pointer to an object or
@@ -1766,6 +1765,28 @@
Sema::AssignConvertType
Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
+ if (getLangOptions().CPlusPlus) {
+ if (!lhsType->isRecordType()) {
+ // C++ 5.17p3: If the left operand is not of class type, the
+ // expression is implicitly converted (C++ 4) to the
+ // cv-unqualified type of the left operand.
+ ImplicitConversionSequence ICS
+ = TryCopyInitialization(rExpr, lhsType.getUnqualifiedType());
+ if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) {
+ // No implicit conversion available; we cannot perform this
+ // assignment.
+ return Incompatible;
+ } else {
+ // Perform the appropriate cast to the right-handle side.
+ ImpCastExprToType(rExpr, lhsType.getUnqualifiedType());
+ return Compatible;
+ }
+ }
+
+ // FIXME: Currently, we fall through and treat C++ classes like C
+ // structures.
+ }
+
// C99 6.5.16.1p1: the left operand is a pointer and the right is
// a null pointer constant.
if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() ||