Skip to content

Commit 76864e6

Browse files
committed
[C++20] [Modules] Don't find module for linkage for decls in global
module Possibly fix #96693 The direct reason is that we are calculating the linkage for the declaration too early so that the linkage got calculated incorrectly. And after I look into the problem, I found it is completely not necessary to calculate the linkage there. It is for ModulesTS. So I simply removes that legacy experimental code and fix the issue.
1 parent 7934fce commit 76864e6

File tree

4 files changed

+28
-24
lines changed

4 files changed

+28
-24
lines changed

clang/include/clang/AST/DeclBase.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -835,10 +835,7 @@ class alignas(8) Decl {
835835

836836
/// Get the module that owns this declaration for linkage purposes.
837837
/// There only ever is such a standard C++ module.
838-
///
839-
/// \param IgnoreLinkage Ignore the linkage of the entity; assume that
840-
/// all declarations in a global module fragment are unowned.
841-
Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
838+
Module *getOwningModuleForLinkage() const;
842839

843840
/// Determine whether this declaration is definitely visible to name lookup,
844841
/// independent of whether the owning module is visible.

clang/lib/AST/Decl.cpp

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) {
16141614
: CK);
16151615
}
16161616

1617-
Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
1617+
Module *Decl::getOwningModuleForLinkage() const {
16181618
if (isa<NamespaceDecl>(this))
16191619
// Namespaces never have module linkage. It is the entities within them
16201620
// that [may] do.
@@ -1637,24 +1637,9 @@ Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
16371637

16381638
case Module::ModuleHeaderUnit:
16391639
case Module::ExplicitGlobalModuleFragment:
1640-
case Module::ImplicitGlobalModuleFragment: {
1641-
// External linkage declarations in the global module have no owning module
1642-
// for linkage purposes. But internal linkage declarations in the global
1643-
// module fragment of a particular module are owned by that module for
1644-
// linkage purposes.
1645-
// FIXME: p1815 removes the need for this distinction -- there are no
1646-
// internal linkage declarations that need to be referred to from outside
1647-
// this TU.
1648-
if (IgnoreLinkage)
1649-
return nullptr;
1650-
bool InternalLinkage;
1651-
if (auto *ND = dyn_cast<NamedDecl>(this))
1652-
InternalLinkage = !ND->hasExternalFormalLinkage();
1653-
else
1654-
InternalLinkage = isInAnonymousNamespace();
1655-
return InternalLinkage ? M->Kind == Module::ModuleHeaderUnit ? M : M->Parent
1656-
: nullptr;
1657-
}
1640+
case Module::ImplicitGlobalModuleFragment:
1641+
// The global module shouldn't change the linkage.
1642+
return nullptr;
16581643

16591644
case Module::PrivateModuleFragment:
16601645
// The private module fragment is part of its containing module for linkage

clang/lib/Sema/SemaLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5965,7 +5965,7 @@ RedeclarationKind Sema::forRedeclarationInCurContext() const {
59655965
// anything that is not visible. We don't need to check linkage here; if
59665966
// the context has internal linkage, redeclaration lookup won't find things
59675967
// from other TUs, and we can't safely compute linkage yet in general.
5968-
if (cast<Decl>(CurContext)->getOwningModuleForLinkage(/*IgnoreLinkage*/ true))
5968+
if (cast<Decl>(CurContext)->getOwningModuleForLinkage())
59695969
return RedeclarationKind::ForVisibleRedeclaration;
59705970
return RedeclarationKind::ForExternalRedeclaration;
59715971
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: cd %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 %t/m.cppm -fsyntax-only -verify
6+
7+
//--- foo.h
8+
9+
template <typename... U>
10+
static void foo(U...) noexcept;
11+
12+
class A {
13+
template <typename... U>
14+
friend void foo(U...) noexcept;
15+
};
16+
17+
//--- m.cppm
18+
// expected-no-diagnostics
19+
module;
20+
#include "foo.h"
21+
export module m;
22+
export using ::A;

0 commit comments

Comments
 (0)