Author: ahatanak Date: Thu Dec 15 21:19:41 2016 New Revision: 289914 URL: http://llvm.org/viewvc/llvm-project?rev=289914&view=rev Log: [Sema] Fix handling of enumerators used as default arguments of lambda expressions in a function or class template.
This patch makes the following changes: - Create a DependentScopeDeclRefExpr for the default argument instead of a CXXDependentScopeMemberExpr. - Pass CombineWithOuterScope=true so that the outer scope in which the enum is declared is searched for the instantiation of the enum. This is the first part of https://reviews.llvm.org/D23096. Fixes PR28795 rdar://problem/27535319 Added: cfe/trunk/test/SemaTemplate/default-expr-arguments-3.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=289914&r1=289913&r2=289914&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Dec 15 21:19:41 2016 @@ -429,7 +429,12 @@ Sema::ActOnDependentIdExpression(const C bool MightBeCxx11UnevalField = getLangOpts().CPlusPlus11 && isUnevaluatedContext(); - if (!MightBeCxx11UnevalField && !isAddressOfOperand && + // Check if the nested name specifier is an enum type. + bool IsEnum = false; + if (NestedNameSpecifier *NNS = SS.getScopeRep()) + IsEnum = dyn_cast_or_null<EnumType>(NNS->getAsType()); + + if (!MightBeCxx11UnevalField && !isAddressOfOperand && !IsEnum && isa<CXXMethodDecl>(DC) && cast<CXXMethodDecl>(DC)->isInstance()) { QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context); Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=289914&r1=289913&r2=289914&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Dec 15 21:19:41 2016 @@ -1687,7 +1687,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(Parm // Instantiate default arguments for methods of local classes (DR1484) // and non-defining declarations. Sema::ContextRAII SavedContext(*this, OwningFunc); - LocalInstantiationScope Local(*this); + LocalInstantiationScope Local(*this, true); ExprResult NewArg = SubstExpr(Arg, TemplateArgs); if (NewArg.isUsable()) { // It would be nice if we still had this. Added: cfe/trunk/test/SemaTemplate/default-expr-arguments-3.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-expr-arguments-3.cpp?rev=289914&view=auto ============================================================================== --- cfe/trunk/test/SemaTemplate/default-expr-arguments-3.cpp (added) +++ cfe/trunk/test/SemaTemplate/default-expr-arguments-3.cpp Thu Dec 15 21:19:41 2016 @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -std=c++14 -emit-llvm -disable-llvm-optzns -verify %s +// expected-no-diagnostics + +namespace PR28795 { + template<typename T> + void func() { + enum class foo { a, b }; + auto bar = [](foo f = foo::a) { return f; }; + bar(); + } + + void foo() { + func<int>(); + } +} + +// Template struct case: +template <class T> struct class2 { + void bar() { + enum class foo { a, b }; + [](foo f = foo::a) { return f; }(); + } +}; + +template struct class2<int>; + +template<typename T> +void f1() { + enum class foo { a, b }; + struct S { + int g1(foo n = foo::a); + }; +} + +template void f1<int>(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits