Skip to content

Commit e95ff21

Browse files
ChuanqiXu9frederik-h
authored andcommitted
[C++20] [Modules] Don't add decls from other units to undefinedButUsed set
It is still better to elide the declaration if possible. To overcome the false positive undefinedButUsed diagnostic, it seems better to not add declaration from other units to the set actually.
1 parent 2047ce1 commit e95ff21

File tree

4 files changed

+12
-21
lines changed

4 files changed

+12
-21
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3829,11 +3829,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Scope *S,
38293829

38303830
// If this redeclaration makes the function inline, we may need to add it to
38313831
// UndefinedButUsed.
3832-
if (!Old->isInlined() && New->isInlined() &&
3833-
!New->hasAttr<GNUInlineAttr>() &&
3834-
!getLangOpts().GNUInline &&
3835-
Old->isUsed(false) &&
3836-
!Old->isDefined() && !New->isThisDeclarationADefinition())
3832+
if (!Old->isInlined() && New->isInlined() && !New->hasAttr<GNUInlineAttr>() &&
3833+
!getLangOpts().GNUInline && Old->isUsed(false) && !Old->isDefined() &&
3834+
!New->isThisDeclarationADefinition() && !Old->isInAnotherModuleUnit())
38373835
UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(),
38383836
SourceLocation()));
38393837

@@ -4700,7 +4698,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
47004698
// If this redeclaration makes the variable inline, we may need to add it to
47014699
// UndefinedButUsed.
47024700
if (!Old->isInline() && New->isInline() && Old->isUsed(false) &&
4703-
!Old->getDefinition() && !New->isThisDeclarationADefinition())
4701+
!Old->getDefinition() && !New->isThisDeclarationADefinition() &&
4702+
!Old->isInAnotherModuleUnit())
47044703
UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(),
47054704
SourceLocation()));
47064705

clang/lib/Sema/SemaExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18355,7 +18355,7 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func,
1835518355
// If this is the first "real" use, act on that.
1835618356
if (OdrUse == OdrUseContext::Used && !Func->isUsed(/*CheckUsedAttr=*/false)) {
1835718357
// Keep track of used but undefined functions.
18358-
if (!Func->isDefined()) {
18358+
if (!Func->isDefined() && !Func->isInAnotherModuleUnit()) {
1835918359
if (mightHaveNonExternalLinkage(Func))
1836018360
UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc));
1836118361
else if (Func->getMostRecentDecl()->isInlined() &&

clang/lib/Serialization/ASTWriterDecl.cpp

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

333333
bool clang::CanElideDeclDef(const Decl *D) {
334-
bool isExternalWithNoLinkageType = false;
335-
if (auto *VD = dyn_cast<ValueDecl>(D))
336-
if (VD->hasExternalFormalLinkage() &&
337-
!isExternalFormalLinkage(VD->getType()->getLinkage()))
338-
isExternalWithNoLinkageType = true;
339-
340334
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
341335
if (FD->isInlined() || FD->isConstexpr())
342336
return false;
@@ -346,9 +340,6 @@ bool clang::CanElideDeclDef(const Decl *D) {
346340

347341
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
348342
return false;
349-
350-
if (isExternalWithNoLinkageType && !FD->isExternC())
351-
return false;
352343
}
353344

354345
if (auto *VD = dyn_cast<VarDecl>(D)) {
@@ -362,9 +353,6 @@ bool clang::CanElideDeclDef(const Decl *D) {
362353

363354
if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
364355
return false;
365-
366-
if (isExternalWithNoLinkageType && !VD->isExternC())
367-
return false;
368356
}
369357

370358
return true;

clang/test/Modules/external-but-not-type-external.cppm

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
// RUN: split-file %s %t
33
// RUN: cd %t
44
//
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
5+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/a.cppm -emit-reduced-module-interface -o %t/a.pcm
6+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/use.cc -fmodule-file=a=%t/a.pcm -fsyntax-only -verify
7+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/use.cc -fmodule-file=a=%t/a.pcm -emit-llvm -o - | \
8+
// RUN: FileCheck %t/use.cc
79

810
//--- a.cppm
911
export module a;
@@ -25,3 +27,5 @@ void *use() {
2527
A a;
2628
return a.external_but_not_type_external(nullptr);
2729
}
30+
31+
// CHECK-NOT: define {{.*}}@_ZNW1a1A30external_but_not_type_externalEPN12_GLOBAL__N_15LocalE

0 commit comments

Comments
 (0)