1e166755aSChuanqi Xu// RUN: rm -rf %t 2e166755aSChuanqi Xu// RUN: mkdir %t 3f4dd9775SChuanqi Xu// RUN: split-file %s %t 4f4dd9775SChuanqi Xu// 5f4dd9775SChuanqi Xu// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm 6f6b0ae14SChuanqi Xu// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t -DDIFFERENT %t/B.cppm -verify 7f4dd9775SChuanqi Xu// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -I%t %t/B.cppm -verify 8*8eea582dSChuanqi Xu// 9*8eea582dSChuanqi Xu// Testing the behavior of `-fskip-odr-check-in-gmf` 10*8eea582dSChuanqi Xu// RUN: %clang_cc1 -std=c++20 -fskip-odr-check-in-gmf %t/A.cppm -emit-module-interface -o %t/A.pcm 11*8eea582dSChuanqi Xu// RUN: %clang_cc1 -std=c++20 -fskip-odr-check-in-gmf -fprebuilt-module-path=%t -I%t \ 12*8eea582dSChuanqi Xu// RUN: -DDIFFERENT -DSKIP_ODR_CHECK_IN_GMF %t/B.cppm -verify 13*8eea582dSChuanqi Xu 14f4dd9775SChuanqi Xu//--- foo.h 15f4dd9775SChuanqi Xu#ifndef FOO_H 16f4dd9775SChuanqi Xu#define FOO_H 17f4dd9775SChuanqi Xu 18f4dd9775SChuanqi Xutemplate <class T> 19f4dd9775SChuanqi Xuconcept Range = requires(T &t) { t.begin(); }; 20f4dd9775SChuanqi Xu 21f4dd9775SChuanqi Xutemplate<class _Tp> 22f4dd9775SChuanqi Xuconcept __integer_like = true; 23f4dd9775SChuanqi Xu 24f4dd9775SChuanqi Xutemplate <class _Tp> 25f4dd9775SChuanqi Xuconcept __member_size = requires(_Tp &&t) { t.size(); }; 26f4dd9775SChuanqi Xu 27f6b0ae14SChuanqi Xutemplate <class First, class Second> 28f6b0ae14SChuanqi Xuconcept C = requires(First x, Second y) { x + y; }; 29f6b0ae14SChuanqi Xu 30f4dd9775SChuanqi Xustruct A { 31f4dd9775SChuanqi Xupublic: 32f4dd9775SChuanqi Xu template <Range T> 33f4dd9775SChuanqi Xu using range_type = T; 34f4dd9775SChuanqi Xu}; 35f4dd9775SChuanqi Xu 36f4dd9775SChuanqi Xustruct __fn { 37f4dd9775SChuanqi Xu template <__member_size _Tp> 38f4dd9775SChuanqi Xu constexpr __integer_like auto operator()(_Tp&& __t) const { 39f4dd9775SChuanqi Xu return __t.size(); 40f4dd9775SChuanqi Xu } 41f6b0ae14SChuanqi Xu 42f6b0ae14SChuanqi Xu template <__integer_like _Tp, C<_Tp> Sentinel> 43f6b0ae14SChuanqi Xu constexpr _Tp operator()(_Tp &&__t, Sentinel &&last) const { 44f6b0ae14SChuanqi Xu return __t; 45f6b0ae14SChuanqi Xu } 46f6b0ae14SChuanqi Xu 47f6b0ae14SChuanqi Xu template <template <class> class H, class S, C<H<S>> Sentinel> 48f6b0ae14SChuanqi Xu constexpr H<S> operator()(H<S> &&__s, Sentinel &&last) const { 49f6b0ae14SChuanqi Xu return __s; 50f6b0ae14SChuanqi Xu } 51f6b0ae14SChuanqi Xu 52f6b0ae14SChuanqi Xu// Tests that we could find different concept definition indeed. 53f6b0ae14SChuanqi Xu#ifndef DIFFERENT 54f6b0ae14SChuanqi Xu template <__integer_like _Tp, __integer_like _Up, C<_Tp> Sentinel> 55f6b0ae14SChuanqi Xu constexpr _Tp operator()(_Tp &&__t, _Up _u, Sentinel &&last) const { 56f6b0ae14SChuanqi Xu return __t; 57f6b0ae14SChuanqi Xu } 58f6b0ae14SChuanqi Xu#else 59f6b0ae14SChuanqi Xu template <__integer_like _Tp, __integer_like _Up, C<_Up> Sentinel> 60f6b0ae14SChuanqi Xu constexpr _Tp operator()(_Tp &&__t, _Up _u, Sentinel &&last) const { 61f6b0ae14SChuanqi Xu return __t; 62f6b0ae14SChuanqi Xu } 63f6b0ae14SChuanqi Xu#endif 64f4dd9775SChuanqi Xu}; 65f4dd9775SChuanqi Xu#endif 66f4dd9775SChuanqi Xu 67f4dd9775SChuanqi Xu//--- A.cppm 68f4dd9775SChuanqi Xumodule; 69f4dd9775SChuanqi Xu#include "foo.h" 70f4dd9775SChuanqi Xuexport module A; 71f4dd9775SChuanqi Xu 72f4dd9775SChuanqi Xu//--- B.cppm 73e166755aSChuanqi Xumodule; 74e166755aSChuanqi Xu#include "foo.h" 75e166755aSChuanqi Xuexport module B; 76e166755aSChuanqi Xuimport A; 77f4dd9775SChuanqi Xu 78*8eea582dSChuanqi Xu#ifdef SKIP_ODR_CHECK_IN_GMF 79*8eea582dSChuanqi Xu// expected-error@B.cppm:* {{call to object of type '__fn' is ambiguous}} 80*8eea582dSChuanqi Xu// expected-note@* 1+{{candidate function}} 81*8eea582dSChuanqi Xu#elif defined(DIFFERENT) 82*8eea582dSChuanqi Xu// expected-error@foo.h:41 {{'__fn::operator()' from module 'A.<global>' is not present in definition of '__fn' provided earlier}} 83*8eea582dSChuanqi Xu// expected-note@* 1+{{declaration of 'operator()' does not match}} 84*8eea582dSChuanqi Xu#else 85*8eea582dSChuanqi Xu// expected-no-diagnostics 86*8eea582dSChuanqi Xu#endif 87*8eea582dSChuanqi Xu 88f6b0ae14SChuanqi Xutemplate <class T> 89f6b0ae14SChuanqi Xustruct U { 90f6b0ae14SChuanqi Xu auto operator+(U) { return 0; } 91f6b0ae14SChuanqi Xu}; 92f6b0ae14SChuanqi Xu 93f4dd9775SChuanqi Xuvoid foo() { 94f4dd9775SChuanqi Xu A a; 95f4dd9775SChuanqi Xu struct S { 96f4dd9775SChuanqi Xu int size() { return 0; } 97f4dd9775SChuanqi Xu auto operator+(S s) { return 0; } 98f4dd9775SChuanqi Xu }; 99f4dd9775SChuanqi Xu __fn{}(S()); 100f6b0ae14SChuanqi Xu __fn{}(S(), S()); 101f6b0ae14SChuanqi Xu __fn{}(S(), S(), S()); 102f6b0ae14SChuanqi Xu 103f6b0ae14SChuanqi Xu __fn{}(U<int>(), U<int>()); 104f4dd9775SChuanqi Xu} 105