diff options
author | Krystian Stasiowski <sdkrystian@gmail.com> | 2024-04-30 14:23:02 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-30 14:23:02 -0400 |
commit | f061a395ffb78215a23e0f503e8ea121ee3b13ad (patch) | |
tree | 1e5b74ca40a77eecb4f3eb63de79243bbbc0add0 /clang/lib/Sema/SemaExceptionSpec.cpp | |
parent | 7662f95f2c767ae3c9b22eb4bdedb07ffcf258b7 (diff) | |
download | llvm-f061a395ffb78215a23e0f503e8ea121ee3b13ad.zip llvm-f061a395ffb78215a23e0f503e8ea121ee3b13ad.tar.gz llvm-f061a395ffb78215a23e0f503e8ea121ee3b13ad.tar.bz2 |
[Clang][Sema][Parse] Delay parsing of noexcept-specifiers in friend function declarations (#90517)
According to [class.mem.general] p8:
> A complete-class context of a class (template) is a
> - function body,
> - default argument,
> - default template argument,
> - _noexcept-specifier_, or
> - default member initializer
>
> within the member-specification of the class or class template.
When testing #90152, it came to my attention that we do _not_ consider
the _noexcept-specifier_ of a friend function declaration to be a
complete-class context (something which the Microsoft standard library
depends on). Although a comment states that this is "consistent with
what other implementations do", the only other implementation that
exhibits this behavior is GCC (MSVC and EDG both late-parse the
_noexcept-specifier_).
This patch changes _noexcept-specifiers_ of friend function declarations
to be late parsed, which is in agreement with the standard & majority of
implementations. Pre-#90152, our existing implementation falls "in
between" the implementation consensus: within non-template classes, we
would not find latter declared members (qualified and unqualified),
while within class templates we would not find latter declared member
when named with a unqualified name, we would find members named with a
qualified name (even when lookup context is the current instantiation).
Therefore, this _shouldn't_ be a breaking change -- any code that didn't
compile will continue to not compile (since a _noexcept-specifier_ is
not part of the deduction substitution
loci (see [temp.deduct.general] p7), and any code which
did compile should continue to do so.
Diffstat (limited to 'clang/lib/Sema/SemaExceptionSpec.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExceptionSpec.cpp | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index c9dd6bb..41bf273 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -258,13 +258,14 @@ Sema::UpdateExceptionSpec(FunctionDecl *FD, } static bool exceptionSpecNotKnownYet(const FunctionDecl *FD) { - auto *MD = dyn_cast<CXXMethodDecl>(FD); - if (!MD) + ExceptionSpecificationType EST = + FD->getType()->castAs<FunctionProtoType>()->getExceptionSpecType(); + if (EST == EST_Unparsed) + return true; + else if (EST != EST_Unevaluated) return false; - - auto EST = MD->getType()->castAs<FunctionProtoType>()->getExceptionSpecType(); - return EST == EST_Unparsed || - (EST == EST_Unevaluated && MD->getParent()->isBeingDefined()); + const DeclContext *DC = FD->getLexicalDeclContext(); + return DC->isRecord() && cast<RecordDecl>(DC)->isBeingDefined(); } static bool CheckEquivalentExceptionSpecImpl( |