From 1abd35950bcb0761887dca0995c68b8a9dc8916f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 14 Jun 2011 16:42:44 +0000 Subject: [PATCH] When profiling FunctionProtoTypes, don't canonicalize the expression in a noexcept exception specification because it isn't part of the canonical type. This ensures that we keep the exact expression written in the noexcept exception specification, rather than accidentally "adopting" a previously-written and canonically "equivalent" function prototype. Fixes PR10087. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132998 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/Type.cpp | 2 +- test/CXX/except/except.spec/canonical.cpp | 53 +++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 test/CXX/except/except.spec/canonical.cpp diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index d287552844..938a686c2b 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1472,7 +1472,7 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, for (unsigned i = 0; i != epi.NumExceptions; ++i) ID.AddPointer(epi.Exceptions[i].getAsOpaquePtr()); } else if (epi.ExceptionSpecType == EST_ComputedNoexcept && epi.NoexceptExpr){ - epi.NoexceptExpr->Profile(ID, Context, true); + epi.NoexceptExpr->Profile(ID, Context, false); } epi.ExtInfo.Profile(ID); } diff --git a/test/CXX/except/except.spec/canonical.cpp b/test/CXX/except/except.spec/canonical.cpp new file mode 100644 index 0000000000..9bc26de144 --- /dev/null +++ b/test/CXX/except/except.spec/canonical.cpp @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +// PR10087: Make sure that we don't conflate exception specifications +// from different functions in the canonical type system. +namespace std +{ + +template _Tp&& declval() noexcept; + +template +struct __is_nothrow_constructible +{ + static const bool value = noexcept(_Tp(declval<_Args>()...)); +}; + +template +class basic_string +{ +public: + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + + basic_string() + noexcept(__is_nothrow_constructible::value); +}; + +template +struct __map_value_compare +{ +public: + __map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value); +}; + +struct less +{ +}; + +struct map +{ + typedef __map_value_compare __vc; + __vc vc_; +}; + + +template +basic_string::basic_string() noexcept(__is_nothrow_constructible::value) {} + +template +__map_value_compare::__map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value) {} + +} // std -- 2.50.1