@@ -111,6 +111,28 @@ static inline Visibility getMinVisibility(Visibility lhs, Visibility rhs) {
111111 return Visibility::Default;
112112}
113113
114+ // ===----------------------------------------------------------------------===//
115+ // Unnamed_addr helpers
116+ // ===----------------------------------------------------------------------===//
117+
118+ using UnnamedAddr = LLVM::UnnamedAddr;
119+
120+ static bool isNoneUnnamedAddr (UnnamedAddr val) {
121+ return val == UnnamedAddr::None;
122+ }
123+
124+ static bool isLocalUnnamedAddr (UnnamedAddr val) {
125+ return val == UnnamedAddr::Local;
126+ }
127+
128+ static UnnamedAddr getMinUnnamedAddr (UnnamedAddr lhs, UnnamedAddr rhs) {
129+ if (isNoneUnnamedAddr (lhs) || isNoneUnnamedAddr (rhs))
130+ return UnnamedAddr::None;
131+ if (isLocalUnnamedAddr (lhs) || isLocalUnnamedAddr (rhs))
132+ return UnnamedAddr::Local;
133+ return UnnamedAddr::Global;
134+ }
135+
114136// ===----------------------------------------------------------------------===//
115137// LLVMLinkerMixin
116138// ===----------------------------------------------------------------------===//
@@ -176,6 +198,29 @@ class LLVMLinkerMixin {
176198 isAvailableExternallyLinkage (srcLinkage));
177199 }
178200
201+ LogicalResult verifyLinkageCompatibility (Conflict pair) {
202+ const DerivedLinkerInterface &derived = getDerived ();
203+ assert (derived.canBeLinked (pair.src ) && " expected linkable operation" );
204+ assert (derived.canBeLinked (pair.dst ) && " expected linkable operation" );
205+
206+ auto linkError = [&](const Twine &error) -> LogicalResult {
207+ return pair.src ->emitError (error) << " dst: " << pair.dst ->getLoc ();
208+ };
209+
210+ Linkage srcLinkage = derived.getLinkage (pair.src );
211+ Linkage dstLinkage = derived.getLinkage (pair.dst );
212+
213+ UnnamedAddr srcUnnamedAddr = derived.getUnnamedAddr (pair.src );
214+ UnnamedAddr dstUnnamedAddr = derived.getUnnamedAddr (pair.dst );
215+
216+ if (isAppendingLinkage (srcLinkage) && isAppendingLinkage (dstLinkage)) {
217+ if (srcUnnamedAddr != dstUnnamedAddr) {
218+ return linkError (" Appending variables with different unnamed_addr need to be linked" );
219+ }
220+ }
221+ return success ();
222+ }
223+
179224 ConflictResolution resolveConflict (Conflict pair) {
180225 const DerivedLinkerInterface &derived = getDerived ();
181226 assert (derived.canBeLinked (pair.src ) && " expected linkable operation" );
@@ -191,6 +236,13 @@ class LLVMLinkerMixin {
191236 derived.setVisibility (pair.src , visibility);
192237 derived.setVisibility (pair.dst , visibility);
193238
239+ UnnamedAddr srcUnnamedAddr = derived.getUnnamedAddr (pair.src );
240+ UnnamedAddr dstUnnamedAddr = derived.getUnnamedAddr (pair.dst );
241+
242+ UnnamedAddr unnamedAddr = getMinUnnamedAddr (srcUnnamedAddr, dstUnnamedAddr);
243+ derived.setUnnamedAddr (pair.src , unnamedAddr);
244+ derived.setUnnamedAddr (pair.dst , unnamedAddr);
245+
194246 const bool srcIsDeclaration = isDeclarationForLinker (pair.src );
195247 const bool dstIsDeclaration = isDeclarationForLinker (pair.dst );
196248
@@ -267,6 +319,8 @@ class SymbolAttrLLVMLinkerInterface
267319 }
268320
269321 LogicalResult resolveConflict (Conflict pair) override {
322+ if (failed (LinkerMixin::verifyLinkageCompatibility (pair)))
323+ return failure ();
270324 ConflictResolution resolution = LinkerMixin::resolveConflict (pair);
271325
272326 switch (resolution) {
0 commit comments