Refactor CompareReferenceRelationship and its callers in preparation for
implementing the resolution of CWG2352.
No functionality change, except that we now convert the referent of a
reference binding to the underlying type of the reference in more cases;
we used to happen to preserve the type sugar from the referent if the
only type change was in the cv-qualifiers.
This exposed a bug in how we generate code for trivial assignment
operators: if the type sugar (particularly the may_alias attribute)
got lost during reference binding, we'd use the "wrong" TBAA information
for the load during the assignment.
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 47b58df..cfb3a05 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5862,29 +5862,29 @@
// FIXME:
// Resolving a defect in P0012R1: we extend this to cover all cases where
// one of the operands is reference-compatible with the other, in order
- // to support conditionals between functions differing in noexcept.
+ // to support conditionals between functions differing in noexcept. This
+ // will similarly cover difference in array bounds after P0388R4.
ExprValueKind LVK = LHS.get()->getValueKind();
ExprValueKind RVK = RHS.get()->getValueKind();
if (!Context.hasSameType(LTy, RTy) &&
LVK == RVK && LVK != VK_RValue) {
// DerivedToBase was already handled by the class-specific case above.
// FIXME: Should we allow ObjC conversions here?
- bool DerivedToBase, ObjCConversion, ObjCLifetimeConversion,
- FunctionConversion;
- if (CompareReferenceRelationship(QuestionLoc, LTy, RTy, DerivedToBase,
- ObjCConversion, ObjCLifetimeConversion,
- FunctionConversion) == Ref_Compatible &&
- !DerivedToBase && !ObjCConversion && !ObjCLifetimeConversion &&
+ const ReferenceConversions AllowedConversions =
+ ReferenceConversions::Qualification | ReferenceConversions::Function;
+
+ ReferenceConversions RefConv;
+ if (CompareReferenceRelationship(QuestionLoc, LTy, RTy, &RefConv) ==
+ Ref_Compatible &&
+ !(RefConv & ~AllowedConversions) &&
// [...] subject to the constraint that the reference must bind
// directly [...]
!RHS.get()->refersToBitField() && !RHS.get()->refersToVectorElement()) {
RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK);
RTy = RHS.get()->getType();
- } else if (CompareReferenceRelationship(
- QuestionLoc, RTy, LTy, DerivedToBase, ObjCConversion,
- ObjCLifetimeConversion,
- FunctionConversion) == Ref_Compatible &&
- !DerivedToBase && !ObjCConversion && !ObjCLifetimeConversion &&
+ } else if (CompareReferenceRelationship(QuestionLoc, RTy, LTy, &RefConv) ==
+ Ref_Compatible &&
+ !(RefConv & ~AllowedConversions) &&
!LHS.get()->refersToBitField() &&
!LHS.get()->refersToVectorElement()) {
LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK);