https://github.com/mizvekov created https://github.com/llvm/llvm-project/pull/101447
Since 3bf72d7d64b8465acd4f4af1a469d68d9dc86058 we have made a simplification where we transform a string literal into a prvalue, where normally they would always be lvalues. This patch fixes expression classification to account for this case. Fixes #82167 >From 345d5d15f7d8992ce1ecd575f83ea85088bb27c1 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Thu, 1 Aug 2024 00:01:19 -0300 Subject: [PATCH] [clang] fix classification of a string literal expression used as initialzier Since 3bf72d7d64b8465acd4f4af1a469d68d9dc86058 we have made a simplification where we transform a string literal into a prvalue, where normally they would always be lvalues. This patch fixes expression classification to account for this case. Fixes #82167 --- clang/docs/ReleaseNotes.rst | 4 +++- clang/lib/AST/ExprClassification.cpp | 8 ++++++-- clang/test/SemaCXX/GH82167.cpp | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/GH82167.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 3c2e0282d1c72..c4dca7252e87a 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -130,7 +130,7 @@ Improvements to Clang's diagnostics - Some template related diagnostics have been improved. .. code-block:: c++ - + void foo() { template <typename> int i; } // error: templates can only be declared in namespace or class scope struct S { @@ -170,6 +170,8 @@ Bug Fixes to C++ Support - Fixed a failed assertion when checking invalid delete operator declaration. (#GH96191) - Fix a crash when checking destructor reference with an invalid initializer. (#GH97230) - Clang now correctly parses potentially declarative nested-name-specifiers in pointer-to-member declarators. +- Fix a crash when checking the initialzier of an object that was initialized + with a string literal. (#GH82167) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 6482cb6d39acc..3b3c0af826079 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -119,8 +119,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // First come the expressions that are always lvalues, unconditionally. case Expr::ObjCIsaExprClass: - // C++ [expr.prim.general]p1: A string literal is an lvalue. - case Expr::StringLiteralClass: // @encode is equivalent to its string case Expr::ObjCEncodeExprClass: // __func__ and friends are too. @@ -150,6 +148,12 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::OMPIteratorExprClass: return Cl::CL_LValue; + // C++ [expr.prim.general]p1: A string literal is an lvalue. + // Except we special case them as prvalues when they are used for + // initialization. + case Expr::StringLiteralClass: + return E->isLValue() ? Cl::CL_LValue : Cl::CL_PRValue; + // C99 6.5.2.5p5 says that compound literals are lvalues. // In C++, they're prvalue temporaries, except for file-scope arrays. case Expr::CompoundLiteralExprClass: diff --git a/clang/test/SemaCXX/GH82167.cpp b/clang/test/SemaCXX/GH82167.cpp new file mode 100644 index 0000000000000..0e13a5a3e1b6d --- /dev/null +++ b/clang/test/SemaCXX/GH82167.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++23 -fsyntax-only -verify %s +// expected-no-diagnostics + +namespace t1 { + struct array { + char elems[2]; + }; + + template <unsigned> struct Literal { + array arr; + constexpr Literal() : arr("") {} + }; + + template struct Literal<0>; +} // namespace t1 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits