diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 43 |
3 files changed, 48 insertions, 9 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 99814911e0..f9a487270b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6335,7 +6335,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init); // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. - if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) { + AutoType *Auto = 0; + if (TypeMayContainAuto && + (Auto = VDecl->getType()->getContainedAutoType()) && + !Auto->isDeduced()) { Expr *DeduceInit = Init; // Initializer could be a C++ direct-initializer. Deduction only works if it // contains exactly one expression. diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 8efd465580..9657661a03 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1093,8 +1093,10 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, } } - // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. - if (TypeMayContainAuto && AllocType->getContainedAutoType()) { + // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. + AutoType *AT = 0; + if (TypeMayContainAuto && + (AT = AllocType->getContainedAutoType()) && !AT->isDeduced()) { if (initStyle == CXXNewExpr::NoInit || NumInits == 0) return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) << AllocType << TypeRange); @@ -1110,8 +1112,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, } Expr *Deduce = Inits[0]; TypeSourceInfo *DeducedType = 0; - if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == - DAR_Failed) + if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed) return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) << AllocType << Deduce->getType() << TypeRange << Deduce->getSourceRange()); diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index f4618e2e7e..310d9b36cb 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3464,6 +3464,41 @@ namespace { return E; } }; + + /// Determine whether the specified type (which contains an 'auto' type + /// specifier) is dependent. This is not trivial, because the 'auto' specifier + /// itself claims to be type-dependent. + bool isDependentAutoType(QualType Ty) { + while (1) { + QualType Pointee = Ty->getPointeeType(); + if (!Pointee.isNull()) { + Ty = Pointee; + } else if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()){ + if (MPT->getClass()->isDependentType()) + return true; + Ty = MPT->getPointeeType(); + } else if (const FunctionProtoType *FPT = Ty->getAs<FunctionProtoType>()){ + for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), + E = FPT->arg_type_end(); + I != E; ++I) + if ((*I)->isDependentType()) + return true; + Ty = FPT->getResultType(); + } else if (Ty->isDependentSizedArrayType()) { + return true; + } else if (const ArrayType *AT = Ty->getAsArrayTypeUnsafe()) { + Ty = AT->getElementType(); + } else if (Ty->getAs<DependentSizedExtVectorType>()) { + return true; + } else if (const VectorType *VT = Ty->getAs<VectorType>()) { + Ty = VT->getElementType(); + } else { + break; + } + } + assert(Ty->getAs<AutoType>() && "didn't find 'auto' in auto type"); + return false; + } } /// \brief Deduce the type for an auto type-specifier (C++0x [dcl.spec.auto]p6) @@ -3486,7 +3521,7 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, Init = result.take(); } - if (Init->isTypeDependent()) { + if (Init->isTypeDependent() || isDependentAutoType(Type->getType())) { Result = Type; return DAR_Succeeded; } @@ -3517,10 +3552,10 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, TemplateDeductionInfo Info(Context, Loc); - InitListExpr * InitList = dyn_cast<InitListExpr>(Init); + InitListExpr *InitList = dyn_cast<InitListExpr>(Init); if (InitList) { for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) { - if (DeduceTemplateArgumentByListElement(*this, &TemplateParams, + if (DeduceTemplateArgumentByListElement(*this, &TemplateParams, TemplArg, InitList->getInit(i), Info, Deduced, TDF)) @@ -3531,7 +3566,7 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, FuncParam, InitType, Init, TDF)) return DAR_Failed; - + if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam, InitType, Info, Deduced, TDF)) return DAR_Failed; |