diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-04-30 21:23:01 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-04-30 21:23:01 +0000 |
commit | 9b1317531d376738fd6631291b0a04109c76a63b (patch) | |
tree | 7ad9189e14f6588a784230d2278ea9399f91c8e3 /lib/Sema | |
parent | 3d2f000df9311bfccb6d2ac350be3d3efa5a412b (diff) |
When deducing an 'auto' type, don't modify the type-as-written.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180808 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 28 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 47 |
4 files changed, 45 insertions, 52 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 1e5e5bb259..1aab5c669f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7334,17 +7334,16 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, Init = Result.take(); DefaultedToAuto = true; } - - TypeSourceInfo *DeducedType = 0; + + QualType DeducedType; if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) == DAR_Failed) DiagnoseAutoDeductionFailure(VDecl, DeduceInit); - if (!DeducedType) { + if (DeducedType.isNull()) { RealDecl->setInvalidDecl(); return; } - VDecl->setTypeSourceInfo(DeducedType); - VDecl->setType(DeducedType->getType()); + VDecl->setType(DeducedType); assert(VDecl->isLinkageValid()); // In ARC, infer lifetime. @@ -7356,8 +7355,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // We only want to warn outside of template instantiations, though: // inside a template, the 'id' could have come from a parameter. if (ActiveTemplateInstantiations.empty() && !DefaultedToAuto && - DeducedType->getType()->isObjCIdType()) { - SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc(); + DeducedType->isObjCIdType()) { + SourceLocation Loc = + VDecl->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); Diag(Loc, diag::warn_auto_var_is_id) << VDecl->getDeclName() << DeduceInit->getSourceRange(); } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index df09b4bcae..56c418720a 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1133,16 +1133,14 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, << AllocType << TypeRange); } Expr *Deduce = Inits[0]; - TypeSourceInfo *DeducedType = 0; + QualType DeducedType; if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed) return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) << AllocType << Deduce->getType() << TypeRange << Deduce->getSourceRange()); - if (!DeducedType) + if (DeducedType.isNull()) return ExprError(); - - AllocTypeInfo = DeducedType; - AllocType = AllocTypeInfo->getType(); + AllocType = DeducedType; } // Per C++0x [expr.new]p5, the type being constructed may be a diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 63c2a7d8e6..673b84e815 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1590,25 +1590,22 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, // If the type contained 'auto', deduce the 'auto' to 'id'. if (FirstType->getContainedAutoType()) { - TypeSourceInfo *DeducedType = 0; OpaqueValueExpr OpaqueId(D->getLocation(), Context.getObjCIdType(), VK_RValue); Expr *DeducedInit = &OpaqueId; - if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, DeducedType) - == DAR_Failed) { + if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, FirstType) == + DAR_Failed) DiagnoseAutoDeductionFailure(D, DeducedInit); - } - if (!DeducedType) { + if (FirstType.isNull()) { D->setInvalidDecl(); return StmtError(); } - D->setTypeSourceInfo(DeducedType); - D->setType(DeducedType->getType()); - FirstType = DeducedType->getType(); + D->setType(FirstType); if (ActiveTemplateInstantiations.empty()) { - SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc(); + SourceLocation Loc = + D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(); Diag(Loc, diag::warn_auto_var_is_id) << D->getDeclName(); } @@ -1645,20 +1642,19 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, /// Finish building a variable declaration for a for-range statement. /// \return true if an error occurs. static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, - SourceLocation Loc, int diag) { + SourceLocation Loc, int DiagID) { // Deduce the type for the iterator variable now rather than leaving it to // AddInitializerToDecl, so we can produce a more suitable diagnostic. - TypeSourceInfo *InitTSI = 0; + QualType InitType; if ((!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) || - SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitTSI) == + SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitType) == Sema::DAR_Failed) - SemaRef.Diag(Loc, diag) << Init->getType(); - if (!InitTSI) { + SemaRef.Diag(Loc, DiagID) << Init->getType(); + if (InitType.isNull()) { Decl->setInvalidDecl(); return true; } - Decl->setTypeSourceInfo(InitTSI); - Decl->setType(InitTSI->getType()); + Decl->setType(InitType); // In ARC, infer lifetime. // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index ea5b145871..70da91e2e0 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3600,32 +3600,32 @@ namespace { // Lambdas never need to be transformed. return E; } + + QualType Apply(TypeSourceInfo *TSI) { + if (TypeSourceInfo *Result = TransformType(TSI)) + return Result->getType(); + return QualType(); + } }; } -/// \brief Deduce the type for an auto type-specifier (C++0x [dcl.spec.auto]p6) +/// \brief Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6) /// /// \param Type the type pattern using the auto type-specifier. -/// /// \param Init the initializer for the variable whose type is to be deduced. -/// /// \param Result if type deduction was successful, this will be set to the -/// deduced type. This may still contain undeduced autos if the type is -/// dependent. This will be set to null if deduction succeeded, but auto -/// substitution failed; the appropriate diagnostic will already have been -/// produced in that case. +/// deduced type. Sema::DeduceAutoResult -Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, - TypeSourceInfo *&Result) { +Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result) { if (Init->getType()->isNonOverloadPlaceholderType()) { - ExprResult result = CheckPlaceholderExpr(Init); - if (result.isInvalid()) return DAR_FailedAlreadyDiagnosed; - Init = result.take(); + ExprResult NonPlaceholder = CheckPlaceholderExpr(Init); + if (NonPlaceholder.isInvalid()) + return DAR_FailedAlreadyDiagnosed; + Init = NonPlaceholder.take(); } if (Init->isTypeDependent() || Type->getType()->isDependentType()) { - Result = - SubstituteAutoTransform(*this, Context.DependentTy).TransformType(Type); + Result = SubstituteAutoTransform(*this, Context.DependentTy).Apply(Type); return DAR_Succeeded; } @@ -3642,7 +3642,7 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType Deduced = BuildDecltypeType(Init, Init->getLocStart()); // FIXME: Support a non-canonical deduced type for 'auto'. Deduced = Context.getCanonicalType(Deduced); - Result = SubstituteAutoTransform(*this, Deduced).TransformType(Type); + Result = SubstituteAutoTransform(*this, Deduced).Apply(Type); return DAR_Succeeded; } } @@ -3660,10 +3660,9 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr, Loc); - TypeSourceInfo *FuncParamInfo = - SubstituteAutoTransform(*this, TemplArg).TransformType(Type); - assert(FuncParamInfo && "substituting template parameter for 'auto' failed"); - QualType FuncParam = FuncParamInfo->getType(); + QualType FuncParam = SubstituteAutoTransform(*this, TemplArg).Apply(Type); + assert(!FuncParam.isNull() && + "substituting template parameter for 'auto' failed"); // Deduce type of TemplParam in Func(Init) SmallVector<DeducedTemplateArgument, 1> Deduced; @@ -3704,15 +3703,15 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, return DAR_FailedAlreadyDiagnosed; } - Result = SubstituteAutoTransform(*this, DeducedType).TransformType(Type); + Result = SubstituteAutoTransform(*this, DeducedType).Apply(Type); // Check that the deduced argument type is compatible with the original // argument type per C++ [temp.deduct.call]p4. - if (!InitList && Result && - CheckOriginalCallArgDeduction(*this, + if (!InitList && !Result.isNull() && + CheckOriginalCallArgDeduction(*this, Sema::OriginalCallArg(FuncParam,0,InitType), - Result->getType())) { - Result = 0; + Result)) { + Result = QualType(); return DAR_Failed; } |