https://github.com/MitalAshok updated https://github.com/llvm/llvm-project/pull/95846
>From 89da8b3bcc678430fe4225c723e87914f2c378cd Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Mon, 17 Jun 2024 21:48:57 +0100 Subject: [PATCH 1/2] [Clang] [Sema] Ensure noexcept(typeid(E)) checks if E throws when needed --- clang/lib/Sema/SemaExceptionSpec.cpp | 9 +++++++-- .../test/SemaCXX/cxx0x-noexcept-expression.cpp | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 67e0c7c63909e..ef1128cedf994 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1111,13 +1111,18 @@ static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { } static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { - if (DC->isTypeOperand()) + // Operand is not evaluated, cannot possibly throw + if (!DC->isPotentiallyEvaluated()) return CT_Cannot; if (DC->isValueDependent()) return CT_Dependent; - return DC->hasNullCheck() ? CT_Can : CT_Cannot; + // Can throw std::bad_typeid if a nullptr is dereferenced + if (DC->hasNullCheck()) + return CT_Can; + + return S.canThrow(DC->getExprOperand()); } CanThrowResult Sema::canThrow(const Stmt *S) { diff --git a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp index c2b2244c117a0..1e86a31fffcbf 100644 --- a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp +++ b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp @@ -1,6 +1,10 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s -fexceptions -fcxx-exceptions -Wno-unevaluated-expression // RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s -fexceptions -fcxx-exceptions -Wno-unevaluated-expression -fexperimental-new-constant-interpreter +namespace std { +struct type_info; +} + void f(); // expected-note {{possible target for call}} void f(int); // expected-note {{possible target for call}} @@ -97,3 +101,17 @@ void j() noexcept(0); void k() noexcept(1); void l() noexcept(2); // expected-error {{noexcept specifier argument evaluates to 2, which cannot be narrowed to type 'bool'}} } // namespace P1401 + +template<bool NoexceptConstructor, bool NoexceptDestructor> +struct Polymorphic { + Polymorphic() noexcept(NoexceptConstructor) {} + virtual ~Polymorphic() noexcept(NoexceptDestructor) {} +}; + +static_assert(noexcept(typeid(Polymorphic<false, false>{}))); // Not evaluated (not glvalue) +static_assert(noexcept(typeid((Polymorphic<true, true>&&) Polymorphic<true, true>{}))); +static_assert(!noexcept(typeid((Polymorphic<false, true>&&) Polymorphic<false, true>{}))); +static_assert(!noexcept(typeid((Polymorphic<true, false>&&) Polymorphic<true, false>{}))); +static_assert(!noexcept(typeid(*&(const Polymorphic<true, true>&) Polymorphic<true, true>{}))); +static_assert(!noexcept(typeid(*&(const Polymorphic<false, true>&) Polymorphic<false, true>{}))); +static_assert(!noexcept(typeid(*&(const Polymorphic<true, false>&) Polymorphic<true, false>{}))); >From 1c6c9bf7f30d60a3a69747cd993d49908447d106 Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Tue, 18 Jun 2024 06:05:43 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Timm Baeder <tbae...@redhat.com> --- clang/lib/Sema/SemaExceptionSpec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index ef1128cedf994..2222fcdc39532 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1111,14 +1111,14 @@ static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { } static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { - // Operand is not evaluated, cannot possibly throw + // Operand is not evaluated, cannot possibly throw. if (!DC->isPotentiallyEvaluated()) return CT_Cannot; if (DC->isValueDependent()) return CT_Dependent; - // Can throw std::bad_typeid if a nullptr is dereferenced + // Can throw std::bad_typeid if a nullptr is dereferenced. if (DC->hasNullCheck()) return CT_Can; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits