forked from OSchip/llvm-project
[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 llvm-svn: 289914
This commit is contained in:
parent
3826727453
commit
d644e021b5
|
@ -429,7 +429,12 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
|
|||
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);
|
||||
|
||||
|
|
|
@ -1687,7 +1687,7 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
|
|||
// 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.
|
||||
|
|
|
@ -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>();
|
Loading…
Reference in New Issue