Author: rsmith Date: Fri Feb 3 19:28:01 2017 New Revision: 294078 URL: http://llvm.org/viewvc/llvm-project?rev=294078&view=rev Log: PR31846: Don't replace 'auto' type with a template parameter type in a generic lambda until after we've checked whether 'auto' is valid in the current language mode.
Modified: cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/SemaCXX/auto-cxx0x.cpp Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=294078&r1=294077&r2=294078&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb 3 19:28:01 2017 @@ -6727,6 +6727,9 @@ public: /// \brief Substitute Replacement for auto in TypeWithAuto TypeSourceInfo* SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType Replacement); + /// \brief Completely replace the \c auto in \p TypeWithAuto by + /// \p Replacement. This does not retain any \c auto type sugar. + QualType ReplaceAutoType(QualType TypeWithAuto, QualType Replacement); /// \brief Result type of DeduceAutoType. enum DeduceAutoResult { Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=294078&r1=294077&r2=294078&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Fri Feb 3 19:28:01 2017 @@ -4250,6 +4250,13 @@ TypeSourceInfo* Sema::SubstAutoTypeSourc .TransformType(TypeWithAuto); } +QualType Sema::ReplaceAutoType(QualType TypeWithAuto, + QualType TypeToReplaceAuto) { + return SubstituteAutoTransform(*this, TypeToReplaceAuto, + /*UseAutoSugar*/ false) + .TransformType(TypeWithAuto); +} + void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) { if (isa<InitListExpr>(Init)) Diag(VDecl->getLocation(), Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=294078&r1=294077&r2=294078&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Fri Feb 3 19:28:01 2017 @@ -1502,40 +1502,7 @@ static QualType ConvertDeclSpecToType(Ty break; case DeclSpec::TST_auto: - // TypeQuals handled by caller. - // If auto is mentioned in a lambda parameter context, convert it to a - // template parameter type immediately, with the appropriate depth and - // index, and update sema's state (LambdaScopeInfo) for the current lambda - // being analyzed (which tracks the invented type template parameter). - if (declarator.getContext() == Declarator::LambdaExprParameterContext) { - sema::LambdaScopeInfo *LSI = S.getCurLambda(); - assert(LSI && "No LambdaScopeInfo on the stack!"); - const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth; - const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size(); - const bool IsParameterPack = declarator.hasEllipsis(); - - // Turns out we must create the TemplateTypeParmDecl here to - // retrieve the corresponding template parameter type. - TemplateTypeParmDecl *CorrespondingTemplateParam = - TemplateTypeParmDecl::Create(Context, - // Temporarily add to the TranslationUnit DeclContext. When the - // associated TemplateParameterList is attached to a template - // declaration (such as FunctionTemplateDecl), the DeclContext - // for each template parameter gets updated appropriately via - // a call to AdoptTemplateParameterList. - Context.getTranslationUnitDecl(), - /*KeyLoc*/ SourceLocation(), - /*NameLoc*/ declarator.getLocStart(), - TemplateParameterDepth, - AutoParameterPosition, // our template param index - /* Identifier*/ nullptr, false, IsParameterPack); - LSI->AutoTemplateParams.push_back(CorrespondingTemplateParam); - // Replace the 'auto' in the function parameter with this invented - // template type parameter. - Result = QualType(CorrespondingTemplateParam->getTypeForDecl(), 0); - } else { - Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false); - } + Result = Context.getAutoType(QualType(), AutoTypeKeyword::Auto, false); break; case DeclSpec::TST_auto_type: @@ -2802,6 +2769,32 @@ static QualType GetDeclSpecTypeForDeclar if (!SemaRef.getLangOpts().CPlusPlus14 || !Auto || Auto->getKeyword() != AutoTypeKeyword::Auto) Error = 16; + else { + // If auto is mentioned in a lambda parameter context, convert it to a + // template parameter type. + sema::LambdaScopeInfo *LSI = SemaRef.getCurLambda(); + assert(LSI && "No LambdaScopeInfo on the stack!"); + const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth; + const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size(); + const bool IsParameterPack = D.hasEllipsis(); + + // Create the TemplateTypeParmDecl here to retrieve the corresponding + // template parameter type. Template parameters are temporarily added + // to the TU until the associated TemplateDecl is created. + TemplateTypeParmDecl *CorrespondingTemplateParam = + TemplateTypeParmDecl::Create( + SemaRef.Context, SemaRef.Context.getTranslationUnitDecl(), + /*KeyLoc*/SourceLocation(), /*NameLoc*/D.getLocStart(), + TemplateParameterDepth, AutoParameterPosition, + /*Identifier*/nullptr, false, IsParameterPack); + LSI->AutoTemplateParams.push_back(CorrespondingTemplateParam); + // Replace the 'auto' in the function parameter with this invented + // template type parameter. + // FIXME: Retain some type sugar to indicate that this was written + // as 'auto'. + T = SemaRef.ReplaceAutoType( + T, QualType(CorrespondingTemplateParam->getTypeForDecl(), 0)); + } break; case Declarator::MemberContext: { if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || Modified: cfe/trunk/test/SemaCXX/auto-cxx0x.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/auto-cxx0x.cpp?rev=294078&r1=294077&r2=294078&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/auto-cxx0x.cpp (original) +++ cfe/trunk/test/SemaCXX/auto-cxx0x.cpp Fri Feb 3 19:28:01 2017 @@ -8,3 +8,10 @@ void f() { typedef auto PR25449(); // expected-error {{'auto' not allowed in typedef}} thread_local auto x; // expected-error {{requires an initializer}} + +void g() { + [](auto){}(0); +#if __cplusplus == 201103L + // expected-error@-2 {{'auto' not allowed in lambda parameter}} +#endif +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits