diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-12 21:11:25 +0000 | 
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-12 21:11:25 +0000 | 
| commit | b64764a30bcec0cc13fff3eb23aa3664b71ac377 (patch) | |
| tree | 74109c5c270367cf8050c620c9838f05b22d4a2d /clang | |
| parent | c480f30580ab0f23a4f7c2ac142fd89412e76a41 (diff) | |
| download | bcm5719-llvm-b64764a30bcec0cc13fff3eb23aa3664b71ac377.tar.gz bcm5719-llvm-b64764a30bcec0cc13fff3eb23aa3664b71ac377.zip  | |
PR38141: check whether noexcept-specifications are equivalent in redeclarations
llvm-svn: 336946
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaExceptionSpec.cpp | 14 | ||||
| -rw-r--r-- | clang/test/CXX/except/except.spec/p3.cpp | 10 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp | 2 | 
3 files changed, 21 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 8dce6d59c60..df5bc9b82b9 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -530,10 +530,16 @@ static bool CheckEquivalentExceptionSpecImpl(      }    } -  // FIXME: We treat dependent noexcept specifications as compatible even if -  // their expressions are not equivalent. -  if (OldEST == EST_DependentNoexcept && NewEST == EST_DependentNoexcept) -    return false; +  // C++14 [except.spec]p3: +  //   Two exception-specifications are compatible if [...] both have the form +  //   noexcept(constant-expression) and the constant-expressions are equivalent +  if (OldEST == EST_DependentNoexcept && NewEST == EST_DependentNoexcept) { +    llvm::FoldingSetNodeID OldFSN, NewFSN; +    Old->getNoexceptExpr()->Profile(OldFSN, S.Context, true); +    New->getNoexceptExpr()->Profile(NewFSN, S.Context, true); +    if (OldFSN == NewFSN) +      return false; +  }    // Dynamic exception specifications with the same set of adjusted types    // are compatible. diff --git a/clang/test/CXX/except/except.spec/p3.cpp b/clang/test/CXX/except/except.spec/p3.cpp index 03f1d7626c0..d5af4651047 100644 --- a/clang/test/CXX/except/except.spec/p3.cpp +++ b/clang/test/CXX/except/except.spec/p3.cpp @@ -104,3 +104,13 @@ void* operator new(mysize_t);  void* operator new[](mysize_t);  void* operator new[](mysize_t) throw(std::bad_alloc); +template<bool X> void equivalent() noexcept (X); +template<bool X> void equivalent() noexcept (X); + +template<bool X, bool Y> void not_equivalent() noexcept (X); // expected-note {{previous}} +template<bool X, bool Y> void not_equivalent() noexcept (Y); // expected-error {{does not match}} + +template<bool X> void missing() noexcept (X); // expected-note {{previous}} +// FIXME: The missing exception specification that we report here doesn't make +// sense in the context of this declaration. +template<bool P> void missing(); // expected-error {{missing exception specification 'noexcept(X)'}} diff --git a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp index 814b04c6e42..82ed724e1bd 100644 --- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp +++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp @@ -10,7 +10,7 @@ template<typename T> void redecl1() noexcept(noexcept(T())); // ok, same type  template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-error {{redefinition}}  template<bool A, bool B> void redecl2() noexcept(A); // expected-note {{previous}} -template<bool A, bool B> void redecl2() noexcept(B); // expected-error {{conflicting types}} +template<bool A, bool B> void redecl2() noexcept(B); // expected-error {{does not match previous}}  // These have the same canonical type, but are still different.  template<typename A, typename B> void redecl3() throw(A); // expected-note {{previous}}  | 

