Skip to content

Commit 5ee6cff

Browse files
authored
[clang] Propagate definition data to all redecls (#170090)
Fix the propagation added in commit 0d490ae to include all redecls, not only previous ones. This fixes another instance of the assertion "Cannot get layout of forward declarations" in getASTRecordLayout(). Kudos to Alexander Kornienko for providing an initial version of the reproducer that I further simplified. Fixes #170084
1 parent 98182f4 commit 5ee6cff

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,8 +2107,8 @@ void ASTDeclMerger::MergeDefinitionData(
21072107
auto *Def = DD.Definition;
21082108
DD = std::move(MergeDD);
21092109
DD.Definition = Def;
2110-
while ((Def = Def->getPreviousDecl()))
2111-
cast<CXXRecordDecl>(Def)->DefinitionData = &DD;
2110+
for (auto *D : Def->redecls())
2111+
cast<CXXRecordDecl>(D)->DefinitionData = &DD;
21122112
return;
21132113
}
21142114

clang/test/Modules/GH170084.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
// RUN: cd %t
5+
6+
// RUN: %clang_cc1 -fmodule-name=stl -fno-cxx-modules -emit-module -fmodules -xc++ stl.cppmap -o stl.pcm
7+
// RUN: %clang_cc1 -fmodule-name=d -fno-cxx-modules -emit-module -fmodules -fmodule-file=stl.pcm -xc++ d.cppmap -o d.pcm
8+
// RUN: %clang_cc1 -fmodule-name=b -fno-cxx-modules -emit-module -fmodules -fmodule-file=stl.pcm -xc++ b.cppmap -o b.pcm
9+
// RUN: %clang_cc1 -fmodule-name=a -fno-cxx-modules -emit-module -fmodules -fmodule-file=stl.pcm -fmodule-file=d.pcm -fmodule-file=b.pcm -xc++ a.cppmap -o a.pcm
10+
// RUN: %clang_cc1 -fno-cxx-modules -fmodules -fmodule-file=a.pcm -emit-llvm -o /dev/null main.cpp
11+
12+
//--- a.cppmap
13+
module "a" {
14+
header "a.h"
15+
}
16+
17+
//--- a.h
18+
#include "b.h"
19+
namespace {
20+
void a(absl::set<char> c) {
21+
absl::set<int> b;
22+
c.end();
23+
c.contains();
24+
}
25+
} // namespace
26+
27+
//--- b.cppmap
28+
module "b" {
29+
header "b.h"
30+
}
31+
32+
//--- b.h
33+
#include "c.h"
34+
void b() { absl::set<char> x; }
35+
36+
//--- c.h
37+
#include "stl.h"
38+
namespace absl {
39+
template <typename>
40+
class set {
41+
public:
42+
struct iterator {
43+
void u() const;
44+
};
45+
iterator end() const { return {}; }
46+
void contains() const { end().u(); }
47+
pair<iterator> e();
48+
};
49+
} // namespace absl
50+
51+
//--- d.cppmap
52+
module "d" {
53+
header "d.h"
54+
}
55+
56+
//--- d.h
57+
#include "c.h"
58+
void d() { absl::set<char> x; }
59+
60+
//--- stl.cppmap
61+
module "stl" {
62+
header "stl.h"
63+
}
64+
65+
//--- stl.h
66+
#ifndef _STL_H_
67+
#define _STL_H_
68+
template <class>
69+
struct pair;
70+
#endif
71+
72+
//--- main.cpp
73+
// expected-no-diagnostics
74+
#include "c.h"
75+
void f(absl::set<char> o) { o.contains(); }

0 commit comments

Comments
 (0)