Skip to content

[clang] ODR violation with header modules and template conversion operator #143152

Open
@emaxx-google

Description

@emaxx-google

Reproducer:

// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: split-file %s %t
//
// RUN: cd %t
//
// RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=//small \
// RUN:     -fmodule-map-file=module-small.cppmap -xc++ module-small.cppmap -emit-module -o module-small.pcm
// RUN: %clang_cc1 -fmodules -fno-implicit-modules -fmodule-name=//large \
// RUN:     -fmodule-map-file=module-large.cppmap -xc++ module-large.cppmap -emit-module -o module-large.pcm
// RUN: %clang_cc1 -fmodules -fno-implicit-modules \
// RUN:     -fmodule-map-file=module-small.cppmap -fmodule-map-file=module-large.cppmap \
// RUN:     -fmodule-file=module-small.pcm -fmodule-file=module-large.pcm -xc++ \
// RUN:     main.cc

//--- class-with-operator.h
#ifndef CLASS_WITH_OPERATOR_H
#define CLASS_WITH_OPERATOR_H

#include "func.h"

class Foo {
  template <class T>
  operator decltype(func<T>()) () {}
};

#endif

//--- func.h
#ifndef FUNC_H
#define FUNC_H

template <class T>
T func();

#endif

//--- main.cc
#include "class-with-operator.h"

//--- module-large.cppmap
module "//large" {
header "module-large.h"
}

//--- module-large.h
#include "unrelated-alias.h"
#include "class-with-operator.h"

//--- module-small.cppmap
module "//small" {
header "module-small.h"
}

//--- module-small.h
#include "class-with-operator.h"

//--- unrelated-alias.h
#ifndef UNRELATED_ALIAS_H
#define UNRELATED_ALIAS_H

#include "func.h"

template <class UnrelatedT>
using UnrelatedAlias = decltype(func<UnrelatedT>())();

#endif

This currently causes a compilation error:

In module '//small':
./class-with-operator.h:8:3: error: 'Foo' with definition in module '//small' has different definitions in different modules; first difference is this function template
    7 |   template <class T>
      |   ~~~~~~~~~~~~~~~~~~
    8 |   operator decltype(func<T>()) () {}
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./class-with-operator.h:8:3: note: but in '//large' found different function template
    7 |   template <class T>
      |   ~~~~~~~~~~~~~~~~~~
    8 |   operator decltype(func<T>()) () {}
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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