diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-07-13 18:40:04 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-07-13 18:40:04 +0000 |
commit | 6398235d7890a81b785ea5af3b6e66d86bf184cc (patch) | |
tree | 51c5154e7ce66f26b051400f26e14f305868fe25 /lib | |
parent | 6dc1ef87044e6b177d4df0d2b593a94616180b3d (diff) |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 2 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGExprComplex.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 2 |
8 files changed, 28 insertions, 19 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index f00eb0478a..9e1d79d79d 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -223,7 +223,7 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { } 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 ebcf828ebf..d792930423 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -992,7 +992,7 @@ const char *BuiltinType::getName(const LangOptions &LO) const { 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 90b6446e0e..995c9b5c45 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -572,8 +572,8 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { 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 b7e855fb1c..911578622d 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -153,7 +153,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, 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 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, 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 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, 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 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, 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 ce3bf11caa..5d53ddeb98 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -475,6 +475,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc, 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 @@ Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, 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 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { // 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 @@ Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, // 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 a5abfe851b..090400fc4e 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -540,7 +540,8 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, 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 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, 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 7536289afc..7ad177557e 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -523,8 +523,9 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, 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 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, 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 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, // 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 ee4c479f72..975ad0bfd4 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3727,7 +3727,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, // 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, |