[clang] 02fccc2 - Revert "DR458: Search template parameter scopes in the right order."
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 16 23:55:03 PDT 2020
Author: Richard Smith
Date: 2020-06-16T23:53:44-07:00
New Revision: 02fccc26cf6af22c07fb81ff3aa69abd77850028
URL: https://github.com/llvm/llvm-project/commit/02fccc26cf6af22c07fb81ff3aa69abd77850028
DIFF: https://github.com/llvm/llvm-project/commit/02fccc26cf6af22c07fb81ff3aa69abd77850028.diff
LOG: Revert "DR458: Search template parameter scopes in the right order."
We weren't re-entering template scopes in the right order, causing this
to break self-host with -fdelayed-template-parsing.
This reverts commit 237c2a23b6d4fa953f5ae910dccf492db61bb959.
Added:
Modified:
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/Scope.h
clang/lib/AST/DeclBase.cpp
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Parse/ParseTemplate.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaLookup.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/test/CXX/drs/dr4xx.cpp
clang/test/CXX/temp/temp.res/temp.local/p8.cpp
clang/test/SemaCXX/lambda-expressions.cpp
clang/www/cxx_dr_status.html
Removed:
################################################################################
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 31840694da27..1ae219781c69 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1088,31 +1088,6 @@ class Parser : public CodeCompletionHandler {
}
};
- /// Introduces zero or more scopes for parsing. The scopes will all be exited
- /// when the object is destroyed.
- class MultiParseScope {
- Parser &Self;
- unsigned NumScopes = 0;
-
- MultiParseScope(const MultiParseScope&) = delete;
-
- public:
- MultiParseScope(Parser &Self) : Self(Self) {}
- void Enter(unsigned ScopeFlags) {
- Self.EnterScope(ScopeFlags);
- ++NumScopes;
- }
- void Exit() {
- while (NumScopes) {
- Self.ExitScope();
- --NumScopes;
- }
- }
- ~MultiParseScope() {
- Exit();
- }
- };
-
/// EnterScope - Start a new scope.
void EnterScope(unsigned ScopeFlags);
@@ -3265,7 +3240,7 @@ class Parser : public CodeCompletionHandler {
DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd,
ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none);
- bool ParseTemplateParameters(MultiParseScope &TemplateScopes, unsigned Depth,
+ bool ParseTemplateParameters(unsigned Depth,
SmallVectorImpl<NamedDecl *> &TemplateParams,
SourceLocation &LAngleLoc,
SourceLocation &RAngleLoc);
diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index b7260f15fe1b..9b8f1415a1e3 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -322,21 +322,8 @@ class Scope {
/// declared in.
bool isDeclScope(const Decl *D) const { return DeclsInScope.count(D) != 0; }
- /// Get the entity corresponding to this scope.
- DeclContext *getEntity() const {
- return isTemplateParamScope() ? nullptr : Entity;
- }
-
- /// Get the DeclContext in which to continue unqualified lookup after a
- /// lookup in this scope.
- DeclContext *getLookupEntity() const { return Entity; }
-
- void setEntity(DeclContext *E) {
- assert(!isTemplateParamScope() &&
- "entity associated with template param scope");
- Entity = E;
- }
- void setLookupEntity(DeclContext *E) { Entity = E; }
+ DeclContext *getEntity() const { return Entity; }
+ void setEntity(DeclContext *E) { Entity = E; }
/// Determine whether any unrecoverable errors have occurred within this
/// scope. Note that this may return false even if the scope contains invalid
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 50ad0255f838..2aab53f4fa90 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -241,7 +241,7 @@ TemplateDecl *Decl::getDescribedTemplate() const {
}
bool Decl::isTemplated() const {
- // A declaration is templated if it is a template or a template pattern, or
+ // A declaration is dependent if it is a template or a template pattern, or
// is within (lexcially for a friend, semantically otherwise) a dependent
// context.
// FIXME: Should local extern declarations be treated like friends?
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index aa35200c33b6..48277dc85466 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1258,16 +1258,17 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
};
// FIXME: Consider allowing this as an extension for GCC compatibiblity.
- MultiParseScope TemplateParamScope(*this);
- if (Tok.is(tok::less)) {
+ const bool HasExplicitTemplateParams = Tok.is(tok::less);
+ ParseScope TemplateParamScope(this, Scope::TemplateParamScope,
+ /*EnteredScope=*/HasExplicitTemplateParams);
+ if (HasExplicitTemplateParams) {
Diag(Tok, getLangOpts().CPlusPlus20
? diag::warn_cxx17_compat_lambda_template_parameter_list
: diag::ext_lambda_template_parameter_list);
SmallVector<NamedDecl*, 4> TemplateParams;
SourceLocation LAngleLoc, RAngleLoc;
- if (ParseTemplateParameters(TemplateParamScope,
- CurTemplateDepthTracker.getDepth(),
+ if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(),
TemplateParams, LAngleLoc, RAngleLoc)) {
Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
return ExprError();
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 847c513b5baa..16aecffa494a 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -67,7 +67,8 @@ Decl *Parser::ParseTemplateDeclarationOrSpecialization(
assert(Tok.isOneOf(tok::kw_export, tok::kw_template) &&
"Token does not start a template declaration.");
- MultiParseScope TemplateParamScopes(*this);
+ // Enter template-parameter scope.
+ ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
// Tell the action that names should be checked in the context of
// the declaration to come.
@@ -115,8 +116,7 @@ Decl *Parser::ParseTemplateDeclarationOrSpecialization(
// Parse the '<' template-parameter-list '>'
SourceLocation LAngleLoc, RAngleLoc;
SmallVector<NamedDecl*, 4> TemplateParams;
- if (ParseTemplateParameters(TemplateParamScopes,
- CurTemplateDepthTracker.getDepth(),
+ if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(),
TemplateParams, LAngleLoc, RAngleLoc)) {
// Skip until the semi-colon or a '}'.
SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
@@ -150,6 +150,9 @@ Decl *Parser::ParseTemplateDeclarationOrSpecialization(
TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get()));
} while (Tok.isOneOf(tok::kw_export, tok::kw_template));
+ unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope;
+ ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization);
+
// Parse the actual template declaration.
if (Tok.is(tok::kw_concept))
return ParseConceptDefinition(
@@ -427,9 +430,8 @@ Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,
///
/// \returns true if an error occurred, false otherwise.
bool Parser::ParseTemplateParameters(
- MultiParseScope &TemplateScopes, unsigned Depth,
- SmallVectorImpl<NamedDecl *> &TemplateParams, SourceLocation &LAngleLoc,
- SourceLocation &RAngleLoc) {
+ unsigned Depth, SmallVectorImpl<NamedDecl *> &TemplateParams,
+ SourceLocation &LAngleLoc, SourceLocation &RAngleLoc) {
// Get the template parameter list.
if (!TryConsumeToken(tok::less, LAngleLoc)) {
Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
@@ -438,11 +440,8 @@ bool Parser::ParseTemplateParameters(
// Try to parse the template parameter list.
bool Failed = false;
- // FIXME: Missing greatergreatergreater support.
- if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) {
- TemplateScopes.Enter(Scope::TemplateParamScope);
+ if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater))
Failed = ParseTemplateParameterList(Depth, TemplateParams);
- }
if (Tok.is(tok::greatergreater)) {
// No diagnostic required here: a template-parameter-list can only be
@@ -851,9 +850,9 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
SmallVector<NamedDecl*,8> TemplateParams;
SourceLocation LAngleLoc, RAngleLoc;
{
- MultiParseScope TemplateParmScope(*this);
- if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,
- LAngleLoc, RAngleLoc)) {
+ ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
+ if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
+ RAngleLoc)) {
return nullptr;
}
}
@@ -1631,7 +1630,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
Sema::ContextRAII GlobalSavedContext(
Actions, Actions.Context.getTranslationUnitDecl());
- MultiParseScope Scopes(*this);
+ SmallVector<ParseScope*, 4> TemplateParamScopeStack;
// Get the list of DeclContexts to reenter. For inline methods, we only want
// to push the DeclContext of the outermost class. This matches the way the
@@ -1656,12 +1655,13 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
// Reenter template scopes from outermost to innermost.
for (ContainingDC CDC : reverse(DeclContextsToReenter)) {
- Scopes.Enter(Scope::TemplateParamScope);
+ TemplateParamScopeStack.push_back(
+ new ParseScope(this, Scope::TemplateParamScope));
unsigned NumParamLists = Actions.ActOnReenterTemplateScope(
getCurScope(), cast<Decl>(CDC.getDC()));
CurTemplateDepthTracker.addDepth(NumParamLists);
if (CDC.shouldPushDC()) {
- Scopes.Enter(Scope::DeclScope);
+ TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
Actions.PushDeclContext(Actions.getCurScope(), CDC.getDC());
}
}
@@ -1709,6 +1709,13 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
} else
Actions.ActOnFinishFunctionBody(LPT.D, nullptr);
}
+
+ // Exit scopes.
+ FnScope.Exit();
+ SmallVectorImpl<ParseScope *>::reverse_iterator I =
+ TemplateParamScopeStack.rbegin();
+ for (; I != TemplateParamScopeStack.rend(); ++I)
+ delete *I;
}
/// Lex a delayed template function for late parsing.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1d046c776709..2bf16d138d5a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1358,50 +1358,6 @@ void Sema::EnterDeclaratorContext(Scope *S, DeclContext *DC) {
CurContext = DC;
S->setEntity(DC);
-
- if (!S->getParent()->isTemplateParamScope())
- return;
-
- // Also set the corresponding entities for all immediately-enclosing template
- // parameter scopes.
- //
- // C++20 [temp.local]p7:
- // In the definition of a member of a class template that appears outside
- // of the class template definition, the name of a member of the class
- // template hides the name of a template-parameter of any enclosing class
- // templates (but not a template-parameter of the member if the member is a
- // class or function template).
- // C++20 [temp.local]p9:
- // In the definition of a class template or in the definition of a member
- // of such a template that appears outside of the template definition, for
- // each non-dependent base class (13.8.2.1), if the name of the base class
- // or the name of a member of the base class is the same as the name of a
- // template-parameter, the base class name or member name hides the
- // template-parameter name (6.4.10).
- //
- // This means that a template parameter scope should be searched immediately
- // after searching the DeclContext for which it is a template parameter
- // scope. For example, for
- // template<typename T> template<typename U> template<typename V>
- // void N::A<T>::B<U>::f(...)
- // we search V then B<U> (and base classes) then U then A<T> (and base
- // classes) then T then N then ::.
- unsigned ScopeDepth = getTemplateDepth(S);
- for (Scope *OuterS = S->getParent(); OuterS && OuterS->isTemplateParamScope();
- OuterS = OuterS->getParent(), --ScopeDepth) {
- auto *SearchDCAfterScope = DC;
- for (; DC; DC = DC->getLookupParent()) {
- if (auto *TD = cast<Decl>(DC)->getDescribedTemplate()) {
- unsigned DCDepth = TD->getTemplateParameters()->getDepth() + 1;
- if (DCDepth > ScopeDepth)
- continue;
- if (ScopeDepth == DCDepth)
- SearchDCAfterScope = DC = DC->getLookupParent();
- break;
- }
- }
- OuterS->setLookupEntity(SearchDCAfterScope);
- }
}
void Sema::ExitDeclaratorContext(Scope *S) {
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 5757eaf3fac0..06a4dfa0a636 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1153,14 +1153,73 @@ static bool isNamespaceOrTranslationUnitScope(Scope *S) {
return false;
}
-/// Find the outer declaration context from this scope. This indicates the
-/// context that we should search up to (exclusive) before considering the
-/// parent of the specified scope.
-static DeclContext *findOuterContext(Scope *S) {
- for (Scope *OuterS = S->getParent(); OuterS; OuterS = OuterS->getParent())
- if (DeclContext *DC = OuterS->getLookupEntity())
- return DC;
- return nullptr;
+// Find the next outer declaration context from this scope. This
+// routine actually returns the semantic outer context, which may
+//
diff er from the lexical context (encoded directly in the Scope
+// stack) when we are parsing a member of a class template. In this
+// case, the second element of the pair will be true, to indicate that
+// name lookup should continue searching in this semantic context when
+// it leaves the current template parameter scope.
+static std::pair<DeclContext *, bool> findOuterContext(Scope *S) {
+ DeclContext *DC = S->getEntity();
+ DeclContext *Lexical = nullptr;
+ for (Scope *OuterS = S->getParent(); OuterS;
+ OuterS = OuterS->getParent()) {
+ if (OuterS->getEntity()) {
+ Lexical = OuterS->getEntity();
+ break;
+ }
+ }
+
+ // C++ [temp.local]p8:
+ // In the definition of a member of a class template that appears
+ // outside of the namespace containing the class template
+ // definition, the name of a template-parameter hides the name of
+ // a member of this namespace.
+ //
+ // Example:
+ //
+ // namespace N {
+ // class C { };
+ //
+ // template<class T> class B {
+ // void f(T);
+ // };
+ // }
+ //
+ // template<class C> void N::B<C>::f(C) {
+ // C b; // C is the template parameter, not N::C
+ // }
+ //
+ // In this example, the lexical context we return is the
+ // TranslationUnit, while the semantic context is the namespace N.
+ if (!Lexical || !DC || !S->getParent() ||
+ !S->getParent()->isTemplateParamScope())
+ return std::make_pair(Lexical, false);
+
+ // Find the outermost template parameter scope.
+ // For the example, this is the scope for the template parameters of
+ // template<class C>.
+ Scope *OutermostTemplateScope = S->getParent();
+ while (OutermostTemplateScope->getParent() &&
+ OutermostTemplateScope->getParent()->isTemplateParamScope())
+ OutermostTemplateScope = OutermostTemplateScope->getParent();
+
+ // Find the namespace context in which the original scope occurs. In
+ // the example, this is namespace N.
+ DeclContext *Semantic = DC;
+ while (!Semantic->isFileContext())
+ Semantic = Semantic->getParent();
+
+ // Find the declaration context just outside of the template
+ // parameter scope. This is the context in which the template is
+ // being lexically declaration (a namespace context). In the
+ // example, this is the global scope.
+ if (Lexical->isFileContext() && !Lexical->Equals(Semantic) &&
+ Lexical->Encloses(Semantic))
+ return std::make_pair(Semantic, true);
+
+ return std::make_pair(Lexical, false);
}
namespace {
@@ -1227,11 +1286,13 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
UnqualUsingDirectiveSet UDirs(*this);
bool VisitedUsingDirectives = false;
bool LeftStartingScope = false;
+ DeclContext *OutsideOfTemplateParamDC = nullptr;
// When performing a scope lookup, we want to find local extern decls.
FindLocalExternScope FindLocals(R);
for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {
+ DeclContext *Ctx = S->getEntity();
bool SearchNamespaceScope = true;
// Check whether the IdResolver has anything in this scope.
for (; I != IEnd && S->isDeclScope(*I); ++I) {
@@ -1263,8 +1324,7 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
if (!SearchNamespaceScope) {
R.resolveKind();
if (S->isClassScope())
- if (CXXRecordDecl *Record =
- dyn_cast_or_null<CXXRecordDecl>(S->getEntity()))
+ if (CXXRecordDecl *Record = dyn_cast_or_null<CXXRecordDecl>(Ctx))
R.setNamingClass(Record);
return true;
}
@@ -1278,8 +1338,24 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
return false;
}
- if (DeclContext *Ctx = S->getLookupEntity()) {
- DeclContext *OuterCtx = findOuterContext(S);
+ if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC &&
+ S->getParent() && !S->getParent()->isTemplateParamScope()) {
+ // We've just searched the last template parameter scope and
+ // found nothing, so look into the contexts between the
+ // lexical and semantic declaration contexts returned by
+ // findOuterContext(). This implements the name lookup behavior
+ // of C++ [temp.local]p8.
+ Ctx = OutsideOfTemplateParamDC;
+ OutsideOfTemplateParamDC = nullptr;
+ }
+
+ if (Ctx) {
+ DeclContext *OuterCtx;
+ bool SearchAfterTemplateScope;
+ std::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S);
+ if (SearchAfterTemplateScope)
+ OutsideOfTemplateParamDC = OuterCtx;
+
for (; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) {
// We do not directly look into transparent contexts, since
// those entities will be found in the nearest enclosing
@@ -1404,9 +1480,25 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
return true;
}
- DeclContext *Ctx = S->getLookupEntity();
+ DeclContext *Ctx = S->getEntity();
+ if (!Ctx && S->isTemplateParamScope() && OutsideOfTemplateParamDC &&
+ S->getParent() && !S->getParent()->isTemplateParamScope()) {
+ // We've just searched the last template parameter scope and
+ // found nothing, so look into the contexts between the
+ // lexical and semantic declaration contexts returned by
+ // findOuterContext(). This implements the name lookup behavior
+ // of C++ [temp.local]p8.
+ Ctx = OutsideOfTemplateParamDC;
+ OutsideOfTemplateParamDC = nullptr;
+ }
+
if (Ctx) {
- DeclContext *OuterCtx = findOuterContext(S);
+ DeclContext *OuterCtx;
+ bool SearchAfterTemplateScope;
+ std::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S);
+ if (SearchAfterTemplateScope)
+ OutsideOfTemplateParamDC = OuterCtx;
+
for (; Ctx && !Ctx->Equals(OuterCtx); Ctx = Ctx->getLookupParent()) {
// We do not directly look into transparent contexts, since
// those entities will be found in the nearest enclosing
@@ -3903,12 +3995,14 @@ class LookupVisibleHelper {
}
}
- DeclContext *Entity = S->getLookupEntity();
- if (Entity) {
+ // FIXME: C++ [temp.local]p8
+ DeclContext *Entity = nullptr;
+ if (S->getEntity()) {
// Look into this scope's declaration context, along with any of its
// parent lookup contexts (e.g., enclosing classes), up to the point
// where we hit the context stored in the next outer scope.
- DeclContext *OuterCtx = findOuterContext(S);
+ Entity = S->getEntity();
+ DeclContext *OuterCtx = findOuterContext(S).first; // FIXME
for (DeclContext *Ctx = Entity; Ctx && !Ctx->Equals(OuterCtx);
Ctx = Ctx->getLookupParent()) {
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6bf46f273a02..073b4e818a24 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -51,7 +51,8 @@ unsigned Sema::getTemplateDepth(Scope *S) const {
// Each template parameter scope represents one level of template parameter
// depth.
- for (Scope *TempParamScope = S->getTemplateParamParent(); TempParamScope;
+ for (Scope *TempParamScope = S->getTemplateParamParent();
+ TempParamScope && !Depth;
TempParamScope = TempParamScope->getParent()->getTemplateParamParent()) {
++Depth;
}
diff --git a/clang/test/CXX/drs/dr4xx.cpp b/clang/test/CXX/drs/dr4xx.cpp
index ff90ee82d4d4..2c762237037d 100644
--- a/clang/test/CXX/drs/dr4xx.cpp
+++ b/clang/test/CXX/drs/dr4xx.cpp
@@ -690,7 +690,7 @@ namespace dr457 { // dr457: yes
};
}
-namespace dr458 { // dr458: 11
+namespace dr458 { // dr458: no
struct A {
int T;
int f();
@@ -706,9 +706,9 @@ namespace dr458 { // dr458: 11
int A::f() {
return T;
}
- template<typename T> // expected-note {{declared here}}
+ template<typename T>
int A::g() {
- return T; // expected-error {{'T' does not refer to a value}}
+ return T; // FIXME: this is invalid, it finds the template parameter
}
template<typename T>
@@ -719,9 +719,9 @@ namespace dr458 { // dr458: 11
int B<T>::g() {
return T;
}
- template<typename U> template<typename T> // expected-note {{declared here}}
+ template<typename U> template<typename T>
int B<U>::h() {
- return T; // expected-error {{'T' does not refer to a value}}
+ return T; // FIXME: this is invalid, it finds the template parameter
}
}
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p8.cpp b/clang/test/CXX/temp/temp.res/temp.local/p8.cpp
index c2b4c1950ea5..fecfed06f109 100644
--- a/clang/test/CXX/temp/temp.res/temp.local/p8.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.local/p8.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
namespace N {
enum { C };
@@ -51,63 +52,3 @@ void N::Y::f(D) {
D d;
}
-// Ensure we properly interleave the searches within classes and template parameter lists.
-namespace SearchClassBetweenTemplateParameterLists {
- int AA, BB; // none of the below lookups should ever consider these
-
- template<typename T> struct A {
- using AA = void;
- template<typename U> struct B {
- using BB = void;
- void f(U);
- void g(U);
- void h(T);
- void i(T);
- template<typename V> void j(V);
- template<typename V> void k(U);
- };
- };
-
- // Search order for the below is:
- // 1) template parameter scope of the function itself (if any)
- // 2) class of which function is a member
- // 3) template parameter scope of inner class
- // 4) class of which class is a member
- // 5) template parameter scope of outer class
-
- // OK, 'AA' found in (3)
- template<typename T> template<typename AA>
- void A<T>::B<AA>::f(AA) {
- AA aa;
- }
-
- // error, 'BB' found in (2)
- template<typename T> template<typename BB>
- void A<T>::B<BB>::g(BB) { // expected-error {{does not match}}
- BB bb; // expected-error {{incomplete type}}
- }
-
- // error, 'AA' found in (4)
- template<typename AA> template<typename U>
- void A<AA>::B<U>::h(AA) { // expected-error {{does not match}}
- AA aa; // expected-error {{incomplete type}}
- }
-
- // error, 'BB' found in (2)
- template<typename BB> template<typename U>
- void A<BB>::B<U>::i(BB) { // expected-error {{does not match}}
- BB bb; // expected-error {{incomplete type}}
- }
-
- // OK, 'BB' found in (1)
- template<typename T> template<typename U> template<typename BB>
- void A<T>::B<U>::j(BB) {
- BB bb;
- }
-
- // error, 'BB' found in (2)
- template<typename T> template<typename BB> template<typename V>
- void A<T>::B<BB>::k(V) { // expected-error {{does not match}}
- BB bb; // expected-error {{incomplete type}}
- }
-}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 3240d5351fc5..0f4edc4d1f34 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -601,24 +601,16 @@ namespace ConversionOperatorDoesNotHaveDeducedReturnType {
#if __cplusplus > 201402L
friend constexpr auto T::operator()(int) const;
friend constexpr T::operator ExpectedTypeT() const noexcept;
-
- template<typename T>
- friend constexpr void U::operator()(T&) const;
- // FIXME: This should not match; the return type is specified as behaving
- // "as if it were a decltype-specifier denoting the return type of
- // [operator()]", which is not equivalent to this alias template.
- template<typename T>
- friend constexpr U::operator ExpectedTypeU<T>() const noexcept;
#else
friend auto T::operator()(int) const;
friend T::operator ExpectedTypeT() const;
+#endif
+ // FIXME: The first of these should match. The second should not.
template<typename T>
- friend void U::operator()(T&) const;
- // FIXME: This should not match, as above.
+ friend void U::operator()(T&) const; // expected-error {{does not match}}
template<typename T>
- friend U::operator ExpectedTypeU<T>() const;
-#endif
+ friend U::operator ExpectedTypeU<T>() const; // expected-error {{does not match}}
private:
int n;
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 22755e4b20ea..4abdc0fa2639 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -2789,7 +2789,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://wg21.link/cwg458">458</a></td>
<td>C++11</td>
<td>Hiding of member template parameters by other members</td>
- <td class="unreleased" align="center">Clang 11</td>
+ <td class="none" align="center">No</td>
</tr>
<tr class="open" id="459">
<td><a href="https://wg21.link/cwg459">459</a></td>
@@ -12307,7 +12307,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://wg21.link/cwg2082">2082</a></td>
<td>CD4</td>
<td>Referring to parameters in unevaluated operands of default arguments</td>
- <td class="unreleased" align="center">Clang 11</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2083">
<td><a href="https://wg21.link/cwg2083">2083</a></td>
@@ -13891,7 +13891,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://wg21.link/cwg2346">2346</a></td>
<td>DRWP</td>
<td>Local variables in default arguments</td>
- <td class="unreleased" align="center">Clang 11</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="2347">
<td><a href="https://wg21.link/cwg2347">2347</a></td>
More information about the cfe-commits
mailing list