Skip to content

[clang][modules] Inline function incorrectly marked as hidden leads to undefined reference #120108

@ldionne

Description

@ldionne

In some circumstances, functions are incorrectly given hidden visibility when Clang modules are enabled, which leads to undefined references. Here's a reproducer where we basically have two small header files, each of which is a module:

// construct_at:
template <class T>
constexpr void __construct_at(T* location, T arg) {
  void* loc = __voidify(*location);
  (void)loc;
}
// voidify
template <class T>
__attribute__((__always_inline__)) void* __voidify(T& from) {
  return const_cast<void*>(static_cast<const volatile void*>(&from));
}

We then have a small test program that uses construct_at:

#include <construct_at.h>

void foo(int* ptr) {
    __construct_at(ptr, 3);
}

and the following modulemap:

module voidify      { header "voidify.h" }
module construct_at { header "construct_at.h" }

Finally, we compile with modules enabled:

clang++ -std=c++17 -fmodules -fcxx-modules -fmodules-cache-path=ModuleCache.noindex -fbuiltin-module-map -c test.cpp -o test.o

And we can see that an undefined reference to __voidify is being generated in test.o, which should never happen for a few reasons:

  1. It's a template, so we need to have a linkonce_odr definition in test.o
  2. Even worse, it's marked as always_inline so it's absolutely evident that this can't end happily. Indeed, we know at the declaration that a definition will never be emitted anywhere else, so this is bound to fail.

In other words, this shouldn't create an undefined reference to __voidify regardless of whether that function is marked as __always_inline__, but it's just a bit more vexing that it does.

Full reproducer attached.

Also tracked as rdar://121551667.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:modulesC++20 modules and Clang Header Modules

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions