[clang] [Clang][Sema] Reject array prvalue operands (PR #140702)
via cfe-commits
cfe-commits at lists.llvm.org
Tue May 20 04:50:50 PDT 2025
https://github.com/languagelawyer updated https://github.com/llvm/llvm-project/pull/140702
>From f6067249c40ad8423048b718be53e69f74b8607d Mon Sep 17 00:00:00 2001
From: Andrey Erokhin <language.lawyer at 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..e72d62a9a5408 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6971,6 +6971,8 @@ def err_typecheck_arc_assign_self_class_method : Error<
def err_typecheck_arr_assign_enumeration : Error<
"fast enumeration variables cannot be modified in ARC by default; "
"declare the variable __strong to allow this">;
+def err_typecheck_array_prvalue_operand : Error<
+ "array prvalue is not permitted">;
def err_typecheck_arc_assign_externally_retained : Error<
"variable declared with 'objc_externally_retained' "
"cannot be modified in ARC">;
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}}
}
More information about the cfe-commits
mailing list