Skip to content

Commit b6c7177

Browse files
committed
[C++20] [Modules] Don't generate unused variables in other module units
even if its initializer has side effects Close #61892 The variables whose initializer has side effects will be emitted even if it is not used. But it shouldn't be true after we introduced modules. The variables in other modules shouldn't be emitted if it is not used even if its initializer has size effects. Also this patch rename `Decl::isInCurrentModuleUnit` to `Decl::isInAnotherModuleUnit` to make it closer to the semantics.
1 parent 7591a7b commit b6c7177

File tree

7 files changed

+83
-12
lines changed

7 files changed

+83
-12
lines changed

clang/include/clang/AST/DeclBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ class alignas(8) Decl {
645645
}
646646

647647
/// Whether this declaration comes from another module unit.
648-
bool isInCurrentModuleUnit() const;
648+
bool isInAnotherModuleUnit() const;
649649

650650
/// FIXME: Implement discarding declarations actually in global module
651651
/// fragment. See [module.global.frag]p3,4 for details.

clang/lib/AST/ASTContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11926,6 +11926,10 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
1192611926
!isMSStaticDataMemberInlineDefinition(VD))
1192711927
return false;
1192811928

11929+
// Variables in other module units shouldn't be forced to be emitted.
11930+
if (VD->isInAnotherModuleUnit())
11931+
return false;
11932+
1192911933
// Variables that can be needed in other TUs are required.
1193011934
auto Linkage = GetGVALinkageForVariable(VD);
1193111935
if (!isDiscardableGVALinkage(Linkage))

clang/lib/AST/DeclBase.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,24 +1023,26 @@ bool Decl::isInExportDeclContext() const {
10231023
return DC && isa<ExportDecl>(DC);
10241024
}
10251025

1026-
bool Decl::isInCurrentModuleUnit() const {
1026+
bool Decl::isInAnotherModuleUnit() const {
10271027
auto *M = getOwningModule();
10281028

10291029
if (!M)
1030-
return true;
1030+
return false;
10311031

10321032
M = M->getTopLevelModule();
10331033
// FIXME: It is problematic if the header module lives in another module
10341034
// unit. Consider to fix this by techniques like
10351035
// ExternalASTSource::hasExternalDefinitions.
10361036
if (M->isHeaderLikeModule())
1037-
return true;
1037+
return false;
10381038

1039+
// A global module without parent implies that we're parsing the global
1040+
// module. So it can't be in another module unit.
10391041
if (M->isGlobalModule())
1040-
return true;
1042+
return false;
10411043

10421044
assert(M->isModulePurview() && "New module kind?");
1043-
return M == getASTContext().getCurrentNamedModule();
1045+
return M != getASTContext().getCurrentNamedModule();
10441046
}
10451047

10461048
static Decl::Kind getKind(const Decl *D) { return D->getKind(); }

clang/lib/Sema/SemaLookup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,7 @@ bool LookupResult::isReachableSlow(Sema &SemaRef, NamedDecl *D) {
19091909
if (DeclModule->isHeaderLikeModule())
19101910
return false;
19111911

1912-
if (D->isInCurrentModuleUnit())
1912+
if (!D->isInAnotherModuleUnit())
19131913
return true;
19141914

19151915
// [module.reach]/p3:
@@ -3889,7 +3889,7 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
38893889
"bad export context");
38903890
// .. are attached to a named module M, do not appear in the
38913891
// translation unit containing the point of the lookup..
3892-
if (!D->isInCurrentModuleUnit() &&
3892+
if (D->isInAnotherModuleUnit() &&
38933893
llvm::any_of(AssociatedClasses, [&](auto *E) {
38943894
// ... and have the same innermost enclosing non-inline
38953895
// namespace scope as a declaration of an associated entity

clang/lib/Sema/SemaOverload.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6543,7 +6543,7 @@ void Sema::AddOverloadCandidate(
65436543
}
65446544

65456545
// Functions with internal linkage are only viable in the same module unit.
6546-
if (getLangOpts().CPlusPlusModules && !Function->isInCurrentModuleUnit()) {
6546+
if (getLangOpts().CPlusPlusModules && Function->isInAnotherModuleUnit()) {
65476547
/// FIXME: Currently, the semantics of linkage in clang is slightly
65486548
/// different from the semantics in C++ spec. In C++ spec, only names
65496549
/// have linkage. So that all entities of the same should share one

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2851,7 +2851,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
28512851
NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();
28522852
SawDefaultArgument = true;
28532853

2854-
if (OldTypeParm->isInCurrentModuleUnit())
2854+
if (!OldTypeParm->isInAnotherModuleUnit())
28552855
RedundantDefaultArg = true;
28562856
else if (!getASTContext().isSameDefaultTemplateArgument(OldTypeParm,
28572857
NewTypeParm)) {
@@ -2903,7 +2903,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
29032903
OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc();
29042904
NewDefaultLoc = NewNonTypeParm->getDefaultArgumentLoc();
29052905
SawDefaultArgument = true;
2906-
if (OldNonTypeParm->isInCurrentModuleUnit())
2906+
if (!OldNonTypeParm->isInAnotherModuleUnit())
29072907
RedundantDefaultArg = true;
29082908
else if (!getASTContext().isSameDefaultTemplateArgument(
29092909
OldNonTypeParm, NewNonTypeParm)) {
@@ -2954,7 +2954,7 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
29542954
OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation();
29552955
NewDefaultLoc = NewTemplateParm->getDefaultArgument().getLocation();
29562956
SawDefaultArgument = true;
2957-
if (OldTemplateParm->isInCurrentModuleUnit())
2957+
if (!OldTemplateParm->isInAnotherModuleUnit())
29582958
RedundantDefaultArg = true;
29592959
else if (!getASTContext().isSameDefaultTemplateArgument(
29602960
OldTemplateParm, NewTemplateParm)) {

clang/test/Modules/pr61892.cppm

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple \
6+
// RUN: -emit-module-interface %t/a.cppm -o %t/a.pcm
7+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple \
8+
// RUN: %t/b.cpp -fmodule-file=a=%t/a.pcm -disable-llvm-passes \
9+
// RUN: -emit-llvm -o - | FileCheck %t/b.cpp
10+
// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple \
11+
// RUN: %t/c.cpp -fmodule-file=a=%t/a.pcm -disable-llvm-passes \
12+
// RUN: -emit-llvm -o - | FileCheck %t/c.cpp
13+
14+
//--- a.cppm
15+
export module a;
16+
17+
struct integer {
18+
explicit operator int() const {
19+
return 0;
20+
}
21+
};
22+
23+
export template<typename>
24+
int a = static_cast<int>(integer());
25+
26+
struct s {
27+
~s();
28+
operator int() const;
29+
};
30+
31+
export template<typename>
32+
auto d = s();
33+
34+
int aa() {
35+
return a<void> + d<void>;
36+
}
37+
38+
int dynamic_func();
39+
export inline int dynamic_var = dynamic_func();
40+
41+
//--- b.cpp
42+
import a;
43+
44+
void b() {}
45+
46+
// CHECK-NOT: @_ZW1a1dIvE =
47+
// CHECK-NOT: @_ZGVW1a1dIvE =
48+
// CHECK-NOT: @_ZW1a11dynamic_var =
49+
// CHECK-NOT: @_ZGVW1a11dynamic_var =
50+
// CHECK-NOT: @_ZW1a1aIvE =
51+
// CHECK-NOT: @_ZGVW1a1aIvE =
52+
53+
//--- c.cpp
54+
import a;
55+
int c() {
56+
return a<void> + d<void> + dynamic_var;
57+
}
58+
59+
// The used variables are generated normally
60+
// CHECK-DAG: @_ZW1a1aIvE =
61+
// CHECK-DAG: @_ZW1a1dIvE =
62+
// CHECK-DAG: @_ZW1a11dynamic_var = linkonce_odr
63+
// CHECK-DAG: @_ZGVW1a1aIvE =
64+
// CHECk-DAG: @_ZGVW1a1dIvE =
65+
// CHECK-DAG: @_ZGVW1a11dynamic_var = linkonce_odr

0 commit comments

Comments
 (0)