Author: Jordan Rupprecht Date: 2026-01-16T13:19:07-06:00 New Revision: 42065cfd74dfd95916cc50cf4d324083585a9210
URL: https://github.com/llvm/llvm-project/commit/42065cfd74dfd95916cc50cf4d324083585a9210 DIFF: https://github.com/llvm/llvm-project/commit/42065cfd74dfd95916cc50cf4d324083585a9210.diff LOG: Revert "[Serialization] Stop demote var definition as declaration" (#176441) Reverts #172430 (c560f1cf03aa06c0bdd00c5a9b558c16d882af6f). Causes some failures like `error: static assertion expression is not an integral constant expression` and `error: substitution into constraint expression resulted in a non-constant expression` in modules builds. Repro TBD. Added: Modified: clang/lib/Serialization/ASTReaderDecl.cpp Removed: clang/test/Modules/pr149404-02.cppm clang/test/Modules/pr172241.cppm ################################################################################ diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index f0fb247f1afb9..f8e9caa3f5d1d 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3642,9 +3642,23 @@ template<> void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, Redeclarable<VarDecl> *D, Decl *Previous, Decl *Canon) { + auto *VD = static_cast<VarDecl *>(D); auto *PrevVD = cast<VarDecl>(Previous); D->RedeclLink.setPrevious(PrevVD); D->First = PrevVD->First; + + // We should keep at most one definition on the chain. + // FIXME: Cache the definition once we've found it. Building a chain with + // N definitions currently takes O(N^2) time here. + if (VD->isThisDeclarationADefinition() == VarDecl::Definition) { + for (VarDecl *CurD = PrevVD; CurD; CurD = CurD->getPreviousDecl()) { + if (CurD->isThisDeclarationADefinition() == VarDecl::Definition) { + Reader.mergeDefinitionVisibility(CurD, VD); + VD->demoteThisDefinitionToDeclaration(); + break; + } + } + } } static bool isUndeducedReturnType(QualType T) { diff --git a/clang/test/Modules/pr149404-02.cppm b/clang/test/Modules/pr149404-02.cppm deleted file mode 100644 index 291619ea05b8a..0000000000000 --- a/clang/test/Modules/pr149404-02.cppm +++ /dev/null @@ -1,104 +0,0 @@ -// RUN: rm -rf %t -// RUN: mkdir -p %t -// RUN: split-file %s %t - -// RUN: %clang_cc1 -std=c++20 -emit-module-interface -o %t/format.pcm %t/format.cppm -// RUN: %clang_cc1 -std=c++20 -emit-module-interface -o %t/includes_in_gmf.pcm %t/includes_in_gmf.cppm -// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/test.cpp -verify -fsyntax-only - -// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface -o %t/format.pcm %t/format.cppm -// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface -o %t/includes_in_gmf.pcm %t/includes_in_gmf.cppm -// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t %t/test.cpp -verify -fsyntax-only - -//--- format.h -#pragma once - -namespace test { - -template <class _Tp> -struct type_identity { - typedef _Tp type; -}; - -template <class _Tp> -using type_identity_t = typename type_identity<_Tp>::type; - - -template <class _Tp, class _CharT> -struct formatter -{ - formatter() = delete; -}; - -template <> -struct formatter<char, char> -{}; - -template <class _CharT, class... _Args> -struct basic_format_string { - static inline const int __handles_{ [] { - formatter<char, _CharT> f; - (void)f; - return 0; - }() }; - - consteval basic_format_string(const _CharT*) { - (void)__handles_; - } -}; - -template <class... _Args> -using wformat_string = basic_format_string<wchar_t, type_identity_t<_Args>...>; - -template <class... _Args> -using format_string = basic_format_string<char, type_identity_t<_Args>...>; - -template <class... _Args> -void format(format_string<_Args...> __fmt, _Args&&... __args) {} - -template <class... _Args> -void format(wformat_string<_Args...> __fmt, _Args&&... __args) {} - -} - -//--- format.cppm -module; -#include "format.h" -export module format; - -export namespace test { - using test::format; - using test::formatter; - using test::format_string; -} - -auto something() -> void -{ - auto a = 'a'; - test::format("{}", a); -} - -//--- includes_in_gmf.cppm -module; -#include "format.h" -export module includes_in_gmf; - -namespace test { - using test::format; - using test::formatter; - using test::format_string; -} - -//--- test.cpp -// expected-no-diagnostics -import format; -import includes_in_gmf; - -auto what() -> void -{ - auto a = 'a'; - test::format("{}", a); - - constexpr auto fs = "{}"; // test::format_string<char>{ "{}" }; // <- same result even passing exact param type - test::format(fs, 'r'); -} diff --git a/clang/test/Modules/pr172241.cppm b/clang/test/Modules/pr172241.cppm deleted file mode 100644 index 3eb885e8b2d9f..0000000000000 --- a/clang/test/Modules/pr172241.cppm +++ /dev/null @@ -1,47 +0,0 @@ -// RUN: rm -rf %t -// RUN: mkdir -p %t -// RUN: split-file %s %t -// -// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/m.cppm -emit-module-interface -o %t/m.pcm -// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/use.cpp -fmodule-file=m=%t/m.pcm -emit-llvm -o - | FileCheck %t/use.cpp -// -// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/m.cppm -emit-reduced-module-interface -o %t/m.pcm -// RUN: %clang_cc1 -std=c++20 -triple %itanium_abi_triple %t/use.cpp -fmodule-file=m=%t/m.pcm -emit-llvm -o - | FileCheck %t/use.cpp - -//--- header.h -#pragma once - -template <unsigned T> -class Templ { -public: - void lock() { __set_locked_bit(); } - -private: - static constexpr auto __set_locked_bit = [](){}; -}; - -class JT { -public: - ~JT() { - Templ<4> state; - state.lock(); - } -}; - -//--- m.cppm -module; -#include "header.h" -export module m; -export struct M { - JT jt; -}; -//--- use.cpp -#include "header.h" -import m; - -int main() { - M m; - return 0; -} - -// CHECK: @_ZN5TemplILj4EE16__set_locked_bitE = {{.*}}linkonce_odr _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
