[AST] lookup in parent DeclContext for transparent DeclContext

The compiler would crash if we lookup for name in transparent decl
context. See the tests attached for example.

I think this should make sense since the member declared in transparent
DeclContext are semantically defined in the enclosing (non-transparent)
DeclContext, this is the definition for transparent DeclContext.

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D116792
This commit is contained in:
Chuanqi Xu 2022-01-11 10:15:46 +08:00
parent 9ef2175f81
commit d9d63fc108
4 changed files with 29 additions and 3 deletions

View File

@ -1644,9 +1644,9 @@ void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) {
DeclContext::lookup_result
DeclContext::lookup(DeclarationName Name) const {
assert(getDeclKind() != Decl::LinkageSpec &&
getDeclKind() != Decl::Export &&
"should not perform lookups into transparent contexts");
// For transparent DeclContext, we should lookup in their enclosing context.
if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
return getParent()->lookup(Name);
const DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this)

View File

@ -0,0 +1,3 @@
export module foo;
export template <typename T>
class X {};

View File

@ -0,0 +1,11 @@
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: %clang_cc1 -std=c++20 %S/Inputs/template_name_lookup/foo.cppm -emit-module-interface -o %t/foo.pcm
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %s -fsyntax-only -verify
import foo;
void use() {
X x; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'X'}}
// expected-note@Inputs/template_name_lookup/foo.cppm:3 {{candidate template ignored: couldn't infer template argument 'T'}}
// expected-note@Inputs/template_name_lookup/foo.cppm:3 {{candidate function template not viable: requires 1 argument, but 0 were provided}}
}

View File

@ -0,0 +1,12 @@
// Tests that the lookup in transparent declaration context
// (linkage specifiaction context) wouldn't cause compiler crash.
// RUN: %clang_cc1 -std=c++20 %s -fsyntax-only -verify
extern "C++" {
template <class T>
class X {}; // expected-note {{candidate template ignored: couldn't infer template argument 'T'}}
// expected-note@-1 {{candidate function template not viable: requires 1 argument, but 0 were provided}}
}
void foo() {
X x; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'X'}}
}