Author: Chuanqi Xu Date: 2024-01-18T17:09:35+08:00 New Revision: 085eae6b863881fb9fda323e5b672b04a00ed19e
URL: https://github.com/llvm/llvm-project/commit/085eae6b863881fb9fda323e5b672b04a00ed19e DIFF: https://github.com/llvm/llvm-project/commit/085eae6b863881fb9fda323e5b672b04a00ed19e.diff LOG: [C++20] [Modules] Allow to merge enums with the same underlying interger types Close https://github.com/llvm/llvm-project/issues/76638. See the issue for the context of the change. Added: clang/test/Modules/pr76638.cppm Modified: clang/lib/AST/ODRHash.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index aea1a93ae1fa828..07677d655c5afd6 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -741,8 +741,55 @@ void ODRHash::AddEnumDecl(const EnumDecl *Enum) { if (Enum->isScoped()) AddBoolean(Enum->isScopedUsingClassTag()); - if (Enum->getIntegerTypeSourceInfo()) - AddQualType(Enum->getIntegerType()); + if (Enum->getIntegerTypeSourceInfo()) { + // FIMXE: This allows two enums with diff erent spellings to have the same + // hash. + // + // // mod1.cppm + // module; + // extern "C" { + // typedef unsigned __int64 size_t; + // } + // namespace std { + // using :: size_t; + // } + // + // extern "C++" { + // namespace std { + // enum class align_val_t : std::size_t {}; + // } + // } + // + // export module mod1; + // export using std::align_val_t; + // + // // mod2.cppm + // module; + // extern "C" { + // typedef unsigned __int64 size_t; + // } + // + // extern "C++" { + // namespace std { + // enum class align_val_t : size_t {}; + // } + // } + // + // export module mod2; + // import mod1; + // export using std::align_val_t; + // + // The above example should be disallowed since it violates + // [basic.def.odr]p14: + // + // Each such definition shall consist of the same sequence of tokens + // + // The definitions of `std::align_val_t` in two module units have diff erent + // spellings but we failed to give an error here. + // + // See https://github.com/llvm/llvm-project/issues/76638 for details. + AddQualType(Enum->getIntegerType().getCanonicalType()); + } // Filter out sub-Decls which will not be processed in order to get an // accurate count of Decl's. diff --git a/clang/test/Modules/pr76638.cppm b/clang/test/Modules/pr76638.cppm new file mode 100644 index 000000000000000..8cc807961421b7c --- /dev/null +++ b/clang/test/Modules/pr76638.cppm @@ -0,0 +1,69 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/mod1.cppm -emit-module-interface -o %t/mod1.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod2.cppm -fmodule-file=mod1=%t/mod1.pcm \ +// RUN: -fsyntax-only -verify +// +// RUN: %clang_cc1 -std=c++20 %t/mod3.cppm -emit-module-interface -o %t/mod3.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod4.cppm -fmodule-file=mod3=%t/mod3.pcm \ +// RUN: -fsyntax-only -verify + +//--- size_t.h + +extern "C" { + typedef unsigned int size_t; +} + +//--- csize_t +namespace std { + using :: size_t; +} + +//--- align.h +namespace std { + enum class align_val_t : size_t {}; +} + +//--- mod1.cppm +module; +#include "size_t.h" +#include "align.h" +export module mod1; +export using std::align_val_t; + +//--- mod2.cppm +// expected-no-diagnostics +module; +#include "size_t.h" +#include "csize_t" +#include "align.h" +export module mod2; +import mod1; +export using std::align_val_t; + +//--- signed_size_t.h +// Test that we can still find the case if the underlying type is diff erent +extern "C" { + typedef signed int size_t; +} + +//--- mod3.cppm +module; +#include "size_t.h" +#include "align.h" +export module mod3; +export using std::align_val_t; + +//--- mod4.cppm +module; +#include "signed_size_t.h" +#include "csize_t" +#include "align.h" +export module mod4; +import mod3; +export using std::align_val_t; + +// expected-error@align.h:* {{'std::align_val_t' has diff erent definitions in diff erent modules; defined here first diff erence is enum with specified type 'size_t' (aka 'int')}} +// expected-note@align.h:* {{but in 'mod3.<global>' found enum with specified type 'size_t' (aka 'unsigned int')}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits