Whenever we're creating an expression that is typically an rvalue
(e.g., a call, cast, etc.), immediately adjust the expression's type
to strip cv-qualifiers off of all non-class types (in C++) or all
types (in C). This effectively extends my previous fix for PR7463,
which was restricted to calls, to other kinds of expressions within
similar characteristics. I've audited every use of
getNonReferenceType() in the code base, switching to the newly-renamed
getNonLValueExprType() where necessary.
Big thanks to Eli for pointing out just how incomplete my original fix
for PR7463 actually was. We've been handling cv-qualifiers on rvalues
wrong for a very, very long time. Fixes PR7463.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108253 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index f00eb04..9e1d79d 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -223,7 +223,7 @@
} else if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
Expr *E = new (Context) DeclRefExpr(NTTP,
- NTTP->getType().getNonReferenceType(),
+ NTTP->getType().getNonLValueExprType(Context),
NTTP->getLocation());
TemplateArgs.push_back(TemplateArgument(E));
} else {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index ebcf828..d792930 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -992,7 +992,7 @@
void FunctionType::ANCHOR() {} // Key function for FunctionType.
-QualType QualType::getCallResultType(ASTContext &Context) const {
+QualType QualType::getNonLValueExprType(ASTContext &Context) const {
if (const ReferenceType *RefType = getTypePtr()->getAs<ReferenceType>())
return RefType->getPointeeType();
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 90b6446..995c9b5 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -572,8 +572,8 @@
TestAndClearIgnoreImag();
bool ignreal = TestAndClearIgnoreRealAssign();
bool ignimag = TestAndClearIgnoreImagAssign();
- assert(CGF.getContext().getCanonicalType(E->getLHS()->getType()) ==
- CGF.getContext().getCanonicalType(E->getRHS()->getType()) &&
+ assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
+ E->getRHS()->getType()) &&
"Invalid assignment");
// Emit the RHS.
ComplexPairTy Val = Visit(E->getRHS());
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index b7e855f..9115786 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -153,7 +153,8 @@
case tok::kw_const_cast:
if (!TypeDependent)
CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
- return Owned(new (Context) CXXConstCastExpr(DestType.getNonReferenceType(),
+ return Owned(new (Context) CXXConstCastExpr(
+ DestType.getNonLValueExprType(Context),
Ex, DestTInfo, OpLoc));
case tok::kw_dynamic_cast: {
@@ -161,7 +162,8 @@
CXXBaseSpecifierArray BasePath;
if (!TypeDependent)
CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath);
- return Owned(new (Context)CXXDynamicCastExpr(DestType.getNonReferenceType(),
+ return Owned(new (Context)CXXDynamicCastExpr(
+ DestType.getNonLValueExprType(Context),
Kind, Ex, BasePath, DestTInfo,
OpLoc));
}
@@ -170,7 +172,7 @@
if (!TypeDependent)
CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
return Owned(new (Context) CXXReinterpretCastExpr(
- DestType.getNonReferenceType(),
+ DestType.getNonLValueExprType(Context),
Kind, Ex, CXXBaseSpecifierArray(),
DestTInfo, OpLoc));
}
@@ -180,7 +182,8 @@
if (!TypeDependent)
CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath);
- return Owned(new (Context) CXXStaticCastExpr(DestType.getNonReferenceType(),
+ return Owned(new (Context) CXXStaticCastExpr(
+ DestType.getNonLValueExprType(Context),
Kind, Ex, BasePath,
DestTInfo, OpLoc));
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ce3bf11..5d53dde 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -475,6 +475,7 @@
if (isa<NonTypeTemplateParmDecl>(VD)) {
// Non-type template parameters can be referenced anywhere they are
// visible.
+ Ty = Ty.getNonLValueExprType(Context);
} else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) {
@@ -4008,7 +4009,8 @@
return ExprError();
Op.release();
- return Owned(new (Context) CStyleCastExpr(Ty->getType().getNonReferenceType(),
+ return Owned(new (Context) CStyleCastExpr(
+ Ty->getType().getNonLValueExprType(Context),
Kind, castExpr, BasePath, Ty,
LParenLoc, RParenLoc));
}
@@ -4904,7 +4906,7 @@
// The getNonReferenceType() call makes sure that the resulting expression
// does not have reference type.
if (result != Incompatible && rExpr->getType() != lhsType)
- ImpCastExprToType(rExpr, lhsType.getNonReferenceType(),
+ ImpCastExprToType(rExpr, lhsType.getNonLValueExprType(Context),
CastExpr::CK_Unknown);
return result;
}
@@ -7348,7 +7350,8 @@
// FIXME: Warn if a non-POD type is passed in.
expr.release();
- return Owned(new (Context) VAArgExpr(BuiltinLoc, E, T.getNonReferenceType(),
+ return Owned(new (Context) VAArgExpr(BuiltinLoc, E,
+ T.getNonLValueExprType(Context),
RPLoc));
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index a5abfe8..090400f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -540,7 +540,8 @@
exprs.release();
- return Owned(new (Context) CXXFunctionalCastExpr(Ty.getNonReferenceType(),
+ return Owned(new (Context) CXXFunctionalCastExpr(
+ Ty.getNonLValueExprType(Context),
TInfo, TyBeginLoc, Kind,
Exprs[0], BasePath,
RParenLoc));
@@ -1879,7 +1880,7 @@
case ICK_Qualification:
// FIXME: Not sure about lvalue vs rvalue here in the presence of rvalue
// references.
- ImpCastExprToType(From, ToType.getNonReferenceType(),
+ ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
CastExpr::CK_NoOp, ToType->isLValueReferenceType());
if (SCS.DeprecatedStringLiteralToCharPtr)
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 7536289..7ad1775 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -523,8 +523,9 @@
StructuredList->setSyntacticForm(IList);
CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true,
Index, StructuredList, StructuredIndex, TopLevelObject);
- IList->setType(T.getNonReferenceType());
- StructuredList->setType(T.getNonReferenceType());
+ QualType ExprTy = T.getNonLValueExprType(SemaRef.Context);
+ IList->setType(ExprTy);
+ StructuredList->setType(ExprTy);
if (hadError)
return;
@@ -1716,7 +1717,7 @@
InitRange.getBegin(), 0, 0,
InitRange.getEnd());
- Result->setType(CurrentObjectType.getNonReferenceType());
+ Result->setType(CurrentObjectType.getNonLValueExprType(SemaRef.Context));
// Pre-allocate storage for the structured initializer list.
unsigned NumElements = 0;
@@ -2370,13 +2371,14 @@
// Add the user-defined conversion step.
Sequence.AddUserConversionStep(Function, Best->FoundDecl,
- T2.getNonReferenceType());
+ T2.getNonLValueExprType(S.Context));
// Determine whether we need to perform derived-to-base or
// cv-qualification adjustments.
bool NewDerivedToBase = false;
Sema::ReferenceCompareResult NewRefRelationship
- = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonReferenceType(),
+ = S.CompareReferenceRelationship(DeclLoc, T1,
+ T2.getNonLValueExprType(S.Context),
NewDerivedToBase);
if (NewRefRelationship == Sema::Ref_Incompatible) {
// If the type we've converted to is not reference-related to the
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index ee4c479..975ad0b 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -3727,7 +3727,7 @@
// there are 0 arguments (i.e., nothing is allocated using ASTContext's
// allocator).
CallExpr Call(Context, &ConversionFn, 0, 0,
- Conversion->getConversionType().getNonReferenceType(),
+ Conversion->getConversionType().getNonLValueExprType(Context),
From->getLocStart());
ImplicitConversionSequence ICS =
TryCopyInitialization(*this, &Call, ToType,