diff options
| author | Douglas Gregor <dgregor@apple.com> | 2011-06-14 16:42:44 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2011-06-14 16:42:44 +0000 |
| commit | d1cff77200a984c631565e47c280e7639d828bce (patch) | |
| tree | 2c930f0562e86c7423a20e39db2cce5fe946ee64 /clang | |
| parent | c1338e8d384c2a26a4b6c9503d297d22b9ab9a60 (diff) | |
| download | bcm5719-llvm-d1cff77200a984c631565e47c280e7639d828bce.tar.gz bcm5719-llvm-d1cff77200a984c631565e47c280e7639d828bce.zip | |
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.
llvm-svn: 132998
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/Type.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CXX/except/except.spec/canonical.cpp | 53 |
2 files changed, 54 insertions, 1 deletions
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index d2875528447..938a686c2b5 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/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/clang/test/CXX/except/except.spec/canonical.cpp b/clang/test/CXX/except/except.spec/canonical.cpp new file mode 100644 index 00000000000..9bc26de1444 --- /dev/null +++ b/clang/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 <class _Tp> _Tp&& declval() noexcept; + +template <class _Tp, class... _Args> +struct __is_nothrow_constructible +{ + static const bool value = noexcept(_Tp(declval<_Args>()...)); +}; + +template<class, class _Traits, class _Allocator> +class basic_string +{ +public: + typedef typename _Traits::char_type value_type; + typedef _Allocator allocator_type; + + basic_string() + noexcept(__is_nothrow_constructible<allocator_type>::value); +}; + +template <class, class, class _Compare> +struct __map_value_compare +{ +public: + __map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value); +}; + +struct less +{ +}; + +struct map +{ + typedef __map_value_compare<int, short, less> __vc; + __vc vc_; +}; + + +template<class T, class _Traits, class _Allocator> +basic_string<T, _Traits, _Allocator>::basic_string() noexcept(__is_nothrow_constructible<allocator_type>::value) {} + +template <class T, class Value, class _Compare> +__map_value_compare<T, Value, _Compare>::__map_value_compare() + noexcept(__is_nothrow_constructible<_Compare>::value) {} + +} // std |

