From f859a91264b0256d63e87733534476c7701a9fc2 Mon Sep 17 00:00:00 2001 From: wuhuiquan Date: Fri, 16 May 2025 16:01:53 +0800 Subject: [PATCH] [safezone] Fixed the unexpected error of adding short or char types in the safe zone --- clang/lib/Sema/SemaExpr.cpp | 45 +++++++++++----- .../safe_operation/safe_operation.cbs | 54 +++++++++++++++++++ 2 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 clang/test/BSC/Negative/SafeZone/safe_operation/safe_operation.cbs diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 246582275fef..34332f30632f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -837,7 +837,11 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) { // Try to perform integral promotions if the object has a theoretically // promotable type. - if (Ty->isIntegralOrUnscopedEnumerationType()) { + if (Ty->isIntegralOrUnscopedEnumerationType() +#if ENABLE_BSC + && !IsInSafeZone() +#endif + ) { // C99 6.3.1.1p2: // // The following may be used in an expression wherever an int or @@ -1578,19 +1582,32 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, return QualType(); // Apply unary and bitfield promotions to the LHS's type. - QualType LHSUnpromotedType = LHSType; - if (LHSType->isPromotableIntegerType()) - LHSType = Context.getPromotedIntegerType(LHSType); - QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(LHS.get()); - if (!LHSBitfieldPromoteTy.isNull()) - LHSType = LHSBitfieldPromoteTy; - if (LHSType != LHSUnpromotedType && ACK != ACK_CompAssign) - LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast); - - // If both types are identical, no conversion is needed. - if (LHSType == RHSType) - return LHSType; - +#if ENABLE_BSC + if (IsInSafeZone()) { + if (IsSafeConstantValueConversion(LHSType, RHS.get())) { + RHS = ImpCastExprToType(RHS.get(), LHSType, CK_IntegralCast); + return LHSType; + } + if (IsSafeConstantValueConversion(RHSType, LHS.get())) { + LHS = ImpCastExprToType(LHS.get(), RHSType, CK_IntegralCast); + return RHSType; + } + } else { +#endif + QualType LHSUnpromotedType = LHSType; + if (LHSType->isPromotableIntegerType()) + LHSType = Context.getPromotedIntegerType(LHSType); + QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(LHS.get()); + if (!LHSBitfieldPromoteTy.isNull()) + LHSType = LHSBitfieldPromoteTy; + if (LHSType != LHSUnpromotedType && ACK != ACK_CompAssign) + LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast); + // If both types are identical, no conversion is needed. + if (LHSType == RHSType) + return LHSType; +#if ENABLE_BSC + } +#endif // At this point, we have two different arithmetic types. // Diagnose attempts to convert between __ibm128, __float128 and long double diff --git a/clang/test/BSC/Negative/SafeZone/safe_operation/safe_operation.cbs b/clang/test/BSC/Negative/SafeZone/safe_operation/safe_operation.cbs new file mode 100644 index 000000000000..dcdf809cbf74 --- /dev/null +++ b/clang/test/BSC/Negative/SafeZone/safe_operation/safe_operation.cbs @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// short add short +// short add Integer +// Integer add short +safe void short_add_short(short a, short b) { + short c = a + b; + // short -32768 ~ 32767 + c = c + 32767; + c = 32768 + c; // expected-error {{conversion from type 'int' to 'short' is forbidden in the safe zone}} + c = c - 1; + c = c - (-1); // ok + c = c - (-32768); // ok + c = c - (-32769); // expected-error {{conversion from type 'int' to 'short' is forbidden in the safe zone}} + unsigned short g = 1; + unsigned short h = 2; + unsigned short i = g + h; + // unsigned short max 65535 + i = i + 65535; + i = 65536 + i; // expected-error {{conversion from type 'int' to 'unsigned short' is forbidden in the safe zone}} + i = i - 1; + i = i - (-1); // expected-error {{conversion from type 'int' to 'unsigned short' is forbidden in the safe zone}} + for (short j = 0; j < 100; j = j + 1) { + i = i + 1; + } +} + +// char add char +// char add Integer +safe void char_add_char(char a, char b) { + char c = a + b; // ok + c = c + 127; // ok + c = 128 + c; // expected-error {{conversion from type 'int' to 'char' is forbidden in the safe zone}} + c = c - 1; + c = c - (-1); + c = c - (-128); + c = c - (-129); // expected-error {{conversion from type 'int' to 'char' is forbidden in the safe zone}} + unsigned char g = 1; + unsigned char h = 2; + unsigned char i = g + h; + i = i + 255; + i = 256 + i; // expected-error {{conversion from type 'int' to 'unsigned char' is forbidden in the safe zone}} + i = i - 1; + i = i - (-1); // expected-error {{conversion from type 'int' to 'unsigned char' is forbidden in the safe zone}} + for (char j = 0; j < 100; j = j + 1) { + i = i + 1; + } +} + +int main() { + short_add_short(100, 200); + char_add_char(100, 101); + return 0; +} -- Gitee