[clang] [clang] fix classification of a string literal expression used as initializer (PR #101447)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 31 20:06:55 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Matheus Izvekov (mizvekov)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/101447.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+3-1)
- (modified) clang/lib/AST/ExprClassification.cpp (+6-2)
- (added) clang/test/SemaCXX/GH82167.cpp (+15)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/101447
More information about the cfe-commits
mailing list