[clang] ODR violation with header modules and template conversion operator (original) (raw)

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 operator decltype(func()) () {} };

#endif

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

template 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 using UnrelatedAlias = decltype(func())();

#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>()) () {}
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~