Skip to content

bogus error "redeclaration with a different type" for redefined auto-typed inline variable #214560

Description

@zygoloid

Testcase:

#pragma clang module build std
module std {
    module a {}
    module b {}
}
#pragma clang module contents
#pragma clang module begin std.a
inline constexpr auto x = [] {};
#pragma clang module end
#pragma clang module begin std.b
inline constexpr auto x = [] {};
#pragma clang module end
#pragma clang module endbuild

is rejected with this error:

std.map:10:23: error: redeclaration of 'x' with a different type: 'const (lambda at std.map:10:27)' vs 'const (lambda at std.map:7:27)'
   10 | inline constexpr auto x = [] {};
      |                       ^
std.map:7:23: note: previous definition is here
    7 | inline constexpr auto x = [] {};
      |                       ^

I believe this is incorrect: the ODR says the two lambdas introduce the same type, because they are within the definition of the same inline variable. Our definition merging logic is presumably not handling this case properly.

In practice, this can happen in some build configurations within libc++, here:

libcxx/include/__compare/synth_three_way.h:28:45: error: redeclaration of '__synth_three_way' with a different type: 'const std::__u::(lambda at libcxx/include/__compare/synth_three_way.h:28:65)' vs 'const std::__u::(lambda at libcxx/include/__compare/synth_three_way.h:28:65)'

Presumably the same thing would happen in a C++20 build:

export module A;
extern "C++" inline auto a = [] {};
module B;
import A;
extern "C++" inline auto a = [] {};

or indirectly via:

module;
#include <compare>
export module A;
import A;
#include <compare>

(if you don't have a modular libc++).

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:modulesC++20 modules and Clang Header Modules

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions