Skip to content

Commit ea15e8b

Browse files
committed
[C++20] [Modules] Avoid use-but-not-defined error
See the attached test for example.
1 parent a98707e commit ea15e8b

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ namespace clang {
330330
}
331331

332332
bool clang::CanElideDeclDef(const Decl *D) {
333+
bool isExternalWithNoLinkageType = false;
334+
if (auto *VD = dyn_cast<ValueDecl>(D))
335+
if (VD->hasExternalFormalLinkage() &&
336+
!isExternalFormalLinkage(VD->getType()->getLinkage()))
337+
isExternalWithNoLinkageType = true;
338+
333339
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
334340
if (FD->isInlined() || FD->isConstexpr())
335341
return false;
@@ -339,6 +345,9 @@ bool clang::CanElideDeclDef(const Decl *D) {
339345

340346
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
341347
return false;
348+
349+
if (isExternalWithNoLinkageType && !FD->isExternC())
350+
return false;
342351
}
343352

344353
if (auto *VD = dyn_cast<VarDecl>(D)) {
@@ -352,6 +361,9 @@ bool clang::CanElideDeclDef(const Decl *D) {
352361

353362
if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
354363
return false;
364+
365+
if (isExternalWithNoLinkageType && !VD->isExternC())
366+
return false;
355367
}
356368

357369
return true;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: cd %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-reduced-module-interface -o %t/a.pcm
6+
// RUN: %clang_cc1 -std=c++20 %t/use.cc -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
7+
8+
//--- a.cppm
9+
export module a;
10+
namespace {
11+
struct Local {};
12+
}
13+
14+
export class A {
15+
public:
16+
void *external_but_not_type_external(Local *) {
17+
return nullptr;
18+
}
19+
};
20+
21+
//--- use.cc
22+
// expected-no-diagnostics
23+
import a;
24+
void *use() {
25+
A a;
26+
return a.external_but_not_type_external(nullptr);
27+
}

0 commit comments

Comments
 (0)