diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-26 01:05:54 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-26 01:05:54 +0000 |
| commit | fda59e5851215850f9b9b534bfd8bda579089029 (patch) | |
| tree | 5275243be051d4b8a2e4728a161cbea4e948ec66 /clang/lib/Sema/SemaDecl.cpp | |
| parent | 7ae21772627a6ce81ad0527640db55daf59bc999 (diff) | |
| download | bcm5719-llvm-fda59e5851215850f9b9b534bfd8bda579089029.tar.gz bcm5719-llvm-fda59e5851215850f9b9b534bfd8bda579089029.zip | |
Implement name mangling proposal for exception specifications from cxx-abi-dev 2016-10-11.
This has the following ABI impact:
1) Functions whose parameter or return types are non-throwing function pointer
types have different manglings in c++1z mode from prior modes. This is
necessary because c++1z permits overloading on the noexceptness of function
pointer parameter types. A warning is issued for cases that will change
manglings in c++1z mode.
2) Functions whose parameter or return types contain instantiation-dependent
exception specifications change manglings in all modes. This is necessary
to support overloading on / SFINAE in these exception specifications, which
a careful reading of the standard indicates has essentially always been
permitted.
Note that, in order to be affected by these changes, the code in question must
specify an exception specification on a function pointer/reference type that is
written syntactically within the declaration of another function. Such
declarations are very rare, and I have so far been unable to find any code
that would be affected by this. (Note that such things will probably become
more common in C++17, since it's a lot easier to get a noexcept function type
as a function parameter / return type there.)
This change does not affect the set of symbols produced by a build of clang,
libc++, or libc++abi.
llvm-svn: 285150
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index aba171b9688..e9e0f5e214d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8996,6 +8996,42 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, !R->isObjCObjectPointerType()) Diag(NewFD->getLocation(), diag::warn_return_value_udt) << NewFD << R; } + + // C++1z [dcl.fct]p6: + // [...] whether the function has a non-throwing exception-specification + // [is] part of the function type + // + // This results in an ABI break between C++14 and C++17 for functions whose + // declared type includes an exception-specification in a parameter or + // return type. (Exception specifications on the function itself are OK in + // most cases, and exception specifications are not permitted in most other + // contexts where they could make it into a mangling.) + if (!getLangOpts().CPlusPlus1z && !NewFD->getPrimaryTemplate()) { + auto HasNoexcept = [&](QualType T) -> bool { + // Strip off declarator chunks that could be between us and a function + // type. We don't need to look far, exception specifications are very + // restricted prior to C++17. + if (auto *RT = T->getAs<ReferenceType>()) + T = RT->getPointeeType(); + else if (T->isAnyPointerType()) + T = T->getPointeeType(); + else if (auto *MPT = T->getAs<MemberPointerType>()) + T = MPT->getPointeeType(); + if (auto *FPT = T->getAs<FunctionProtoType>()) + if (FPT->isNothrow(Context)) + return true; + return false; + }; + + auto *FPT = NewFD->getType()->castAs<FunctionProtoType>(); + bool AnyNoexcept = HasNoexcept(FPT->getReturnType()); + for (QualType T : FPT->param_types()) + AnyNoexcept |= HasNoexcept(T); + if (AnyNoexcept) + Diag(NewFD->getLocation(), + diag::warn_cxx1z_compat_exception_spec_in_signature) + << NewFD; + } } return Redeclaration; } |

