https://github.com/languagelawyer updated 
https://github.com/llvm/llvm-project/pull/140702

>From df91056b5ccbb0f51945f21cd5b2e5bca31eee7f Mon Sep 17 00:00:00 2001
From: Andrey Erokhin <language.law...@gmail.com>
Date: Tue, 20 May 2025 14:58:23 +0500
Subject: [PATCH] [Clang][Sema] Reject array prvalue operands

of unary + and *, and binary + and - operators
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 ++
 clang/lib/Sema/SemaExpr.cpp                   | 24 +++++++++++++++++++
 clang/test/CXX/expr/p8.cpp                    | 12 ++++++++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d78a757c72e4a..2d7498a750d18 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7639,6 +7639,8 @@ def warn_param_mismatched_alignment : Warning<
 
 def err_objc_object_assignment : Error<
   "cannot assign to class object (%0 invalid)">;
+def err_typecheck_array_prvalue_operand : Error<
+  "array prvalue is not permitted">;
 def err_typecheck_invalid_operands : Error<
   "invalid operands to binary expression (%0 and %1)">, Deferrable;
 def note_typecheck_invalid_operands_converted : Note<
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d1889100c382e..3e0a80602df68 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11333,6 +11333,13 @@ QualType Sema::CheckAdditionOperands(ExprResult &LHS, 
ExprResult &RHS,
   if (!IExp->getType()->isIntegerType())
     return InvalidOperands(Loc, LHS, RHS);
 
+  if (OriginalOperand Orig(PExp);
+      Orig.getType()->isArrayType() && Orig.Orig->isPRValue()) {
+    Diag(Loc, diag::err_typecheck_array_prvalue_operand)
+        << PExp->getSourceRange();
+    return QualType();
+  }
+
   // Adding to a null pointer results in undefined behavior.
   if (PExp->IgnoreParenCasts()->isNullPointerConstant(
           Context, Expr::NPC_ValueDependentIsNotNull)) {
@@ -11429,6 +11436,18 @@ QualType Sema::CheckSubtractionOperands(ExprResult 
&LHS, ExprResult &RHS,
     return compType;
   }
 
+  OriginalOperand OrigLHS(LHS.get()), OrigRHS(RHS.get());
+  bool LHSArrP = OrigLHS.getType()->isArrayType() && OrigLHS.Orig->isPRValue();
+  bool RHSArrP = OrigRHS.getType()->isArrayType() && OrigRHS.Orig->isPRValue();
+  if (LHSArrP || RHSArrP) {
+    auto &&diag = Diag(Loc, diag::err_typecheck_array_prvalue_operand);
+    if (LHSArrP)
+      diag << LHS.get()->getSourceRange();
+    if (RHSArrP)
+      diag << RHS.get()->getSourceRange();
+    return QualType();
+  }
+
   // Either ptr - int   or   ptr - ptr.
   if (LHS.get()->getType()->isAnyPointerType()) {
     QualType lpointee = LHS.get()->getType()->getPointeeType();
@@ -15840,6 +15859,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation 
OpLoc,
       InputExpr->getType()->isSpecificBuiltinType(BuiltinType::Dependent)) {
     resultType = Context.DependentTy;
   } else {
+    if (Opc == UO_Deref || Opc == UO_Plus) {
+      if (InputExpr->getType()->isArrayType() && InputExpr->isPRValue())
+        return ExprError(Diag(OpLoc, diag::err_typecheck_array_prvalue_operand)
+                         << InputExpr->getSourceRange());
+    }
     switch (Opc) {
     case UO_PreInc:
     case UO_PreDec:
diff --git a/clang/test/CXX/expr/p8.cpp b/clang/test/CXX/expr/p8.cpp
index 471d1c5a30206..f736b88b3db09 100644
--- a/clang/test/CXX/expr/p8.cpp
+++ b/clang/test/CXX/expr/p8.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
 
 int a0;
 const volatile int a1 = 2;
@@ -16,4 +15,13 @@ int main()
   f0(a1);
   f1(a2);
   f2(a3);
+
+  using IA = int[];
+  void(+IA{ 1, 2, 3 }); // expected-error {{array prvalue}}
+  void(*IA{ 1, 2, 3 }); // expected-error {{array prvalue}}
+  void(IA{ 1, 2, 3 } + 0); // expected-error {{array prvalue}}
+  void(IA{ 1, 2, 3 } - 0); // expected-error {{array prvalue}}
+  void(0 + IA{ 1, 2, 3 }); // expected-error {{array prvalue}}
+  void(0 - IA{ 1, 2, 3 }); // expected-error {{array prvalue}}
+  void(IA{ 1, 2, 3 } - IA{ 1, 2, 3 }); // expected-error {{array prvalue}}
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to