Skip to content

Commit 144c93b

Browse files
committed
[C++20] [Modules] Don't diagnose redeclaration of implicit instantiations in different modules
See the attached example for motivation. Although it is not sure how should we treat the modules ownership of the implicit instantiations, it makes no sense to diagnose redeclaration of implicit instantiations in different modules.
1 parent d367c7d commit 144c93b

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,17 @@ void Sema::FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
16531653
F.done();
16541654
}
16551655

1656+
static bool isImplicitInstantiation(NamedDecl *D) {
1657+
if (auto *VD = dyn_cast<VarDecl>(D))
1658+
return VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation;
1659+
if (auto *FD = dyn_cast<FunctionDecl>(D))
1660+
return FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation;
1661+
if (auto *RD = dyn_cast<CXXRecordDecl>(D))
1662+
return RD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation;
1663+
1664+
return false;
1665+
}
1666+
16561667
bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) {
16571668
// [module.interface]p7:
16581669
// A declaration is attached to a module as follows:
@@ -1668,6 +1679,14 @@ bool Sema::CheckRedeclarationModuleOwnership(NamedDecl *New, NamedDecl *Old) {
16681679
return false;
16691680
}
16701681

1682+
// Although we have questions for the module ownership of implicit
1683+
// instantiations, it should be sure that we shouldn't diagnose the
1684+
// redeclaration of incorrect module ownership for different implicit
1685+
// instantiations in different modules. We will diagnose the redeclaration of
1686+
// incorrect module ownership for the template itself.
1687+
if (isImplicitInstantiation(New) || isImplicitInstantiation(Old))
1688+
return false;
1689+
16711690
Module *NewM = New->getOwningModule();
16721691
Module *OldM = Old->getOwningModule();
16731692

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
//
4+
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-reduced-module-interface -o %t/a.pcm
5+
// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-reduced-module-interface -o %t/b.pcm -fprebuilt-module-path=%t
6+
// RUN: %clang_cc1 -std=c++20 %t/c.cppm -emit-reduced-module-interface -o %t/c.pcm -fprebuilt-module-path=%t
7+
// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
8+
9+
//--- a.h
10+
template <typename T>
11+
struct A {
12+
static const T value0;
13+
static const T value1;
14+
15+
constexpr T get0() {
16+
return value0;
17+
}
18+
19+
constexpr T get1() {
20+
return value1;
21+
}
22+
};
23+
24+
template <typename T>
25+
const T A<T>::value0 = T(43);
26+
template <typename T>
27+
const T A<T>::value1 = T(44);
28+
29+
//--- a.cppm
30+
module;
31+
#include "a.h"
32+
export module a;
33+
export using ::A;
34+
35+
//--- b.cppm
36+
export module b;
37+
export import a;
38+
39+
export constexpr int bar() {
40+
return A<int>().get0();
41+
}
42+
43+
//--- c.cppm
44+
export module c;
45+
export import b;
46+
47+
export constexpr int foo() {
48+
return A<int>().get1() + A<int>().get0();
49+
}
50+
51+
//--- d.cpp
52+
// expected-no-diagnostics
53+
54+
import c;
55+
56+
static_assert(bar() + foo() == 130);
57+

0 commit comments

Comments
 (0)