From 4fbaa62b60b872654a5e2dbfd68337dc34b5f8cc Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai Date: Thu, 21 Sep 2017 19:54:12 +0000 Subject: [Sema] Prevent InstantiateClass from checking unrelated exception specs. Sema::InstantiateClass should check only exception specs added during class instantiation and ignore already present delayed specs. This fixes a case where we instantiate a class before parsing member initializers, check exceptions for a different class and fail to find a member initializer. Which is required for comparing exception specs for explicitly-defaulted and implicit default constructor. With the fix we are still checking exception specs but only after member initializers are present. Removing errors in crash-unparsed-exception.cpp is acceptable according to discussion in PR24000 because other compilers accept code in crash-unparsed-exception.cpp as valid. rdar://problem/34167492 Reviewers: davide, rsmith Reviewed By: rsmith Subscribers: dim, cfe-commits Differential Revision: https://reviews.llvm.org/D37881 llvm-svn: 313906 --- .../test/SemaTemplate/default-arguments-cxx0x.cpp | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'clang/test/SemaTemplate/default-arguments-cxx0x.cpp') diff --git a/clang/test/SemaTemplate/default-arguments-cxx0x.cpp b/clang/test/SemaTemplate/default-arguments-cxx0x.cpp index d9fa2b4a825..c24ed12a024 100644 --- a/clang/test/SemaTemplate/default-arguments-cxx0x.cpp +++ b/clang/test/SemaTemplate/default-arguments-cxx0x.cpp @@ -87,3 +87,30 @@ namespace PR13986 { A<1> m_target; }; } + +// rdar://problem/34167492 +// Template B is instantiated during checking if defaulted A copy constructor +// is constexpr. For this we check if S copy constructor is constexpr. And +// for this we check S constructor template with default argument that mentions +// template B. In turn, template instantiation triggers checking defaulted +// members exception spec. The problem is that it checks defaulted members not +// for instantiated class only, but all defaulted members so far. In this case +// we try to check exception spec for A default constructor which requires +// initializer for the field _a. But initializers are added after constexpr +// check so we reject the code because cannot find _a initializer. +namespace rdar34167492 { + template struct B { using type = bool; }; + + template struct S { + S() noexcept; + + template ::type = true> + S(const S&) noexcept; + }; + + class A { + A() noexcept = default; + A(const A&) noexcept = default; + S _a{}; + }; +} -- cgit v1.2.3