Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "[Clang][Sema] Earlier type checking for builtin unary operators (#90500)" #92149

Merged
merged 1 commit into from
May 14, 2024

Conversation

sdkrystian
Copy link
Member

This reverts commit 8019cbb.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 14, 2024
@llvmbot
Copy link
Member

llvmbot commented May 14, 2024

@llvm/pr-subscribers-clang

Author: Krystian Stasiowski (sdkrystian)

Changes

This reverts commit 8019cbb.


Patch is 41.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92149.diff

15 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (-3)
  • (modified) clang/include/clang/AST/Type.h (+1-4)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+179-175)
  • (modified) clang/test/AST/ast-dump-expr-json.cpp (+2-2)
  • (modified) clang/test/AST/ast-dump-expr.cpp (+1-1)
  • (modified) clang/test/AST/ast-dump-lambda.cpp (+1-1)
  • (removed) clang/test/CXX/expr/expr.unary/expr.unary.general/p1.cpp (-65)
  • (modified) clang/test/CXX/over/over.built/ast.cpp (+30-128)
  • (modified) clang/test/CXX/over/over.built/p10.cpp (+1-1)
  • (modified) clang/test/CXX/over/over.built/p11.cpp (+1-1)
  • (modified) clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp (+15-10)
  • (modified) clang/test/Frontend/noderef_templates.cpp (+2-2)
  • (modified) clang/test/SemaCXX/cxx2b-deducing-this.cpp (+4-2)
  • (modified) clang/test/SemaTemplate/class-template-spec.cpp (+6-6)
  • (modified) clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (+3-3)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a2e44efe41347..49ab222bec405 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -55,9 +55,6 @@ C++ Specific Potentially Breaking Changes
 
 - Clang now rejects pointer to member from parenthesized expression in unevaluated context such as ``decltype(&(foo::bar))``. (#GH40906).
 
-- Clang now performs semantic analysis for unary operators with dependent operands
-  that are known to be of non-class non-enumeration type prior to instantiation.
-
 ABI Changes in This Version
 ---------------------------
 - Fixed Microsoft name mangling of implicitly defined variables used for thread
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index da3834f19ca04..e6643469e0b33 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -8044,10 +8044,7 @@ inline bool Type::isUndeducedType() const {
 /// Determines whether this is a type for which one can define
 /// an overloaded operator.
 inline bool Type::isOverloadableType() const {
-  if (!CanonicalType->isDependentType())
-    return isRecordType() || isEnumeralType();
-  return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
-         !isMemberPointerType();
+  return isDependentType() || isRecordType() || isEnumeralType();
 }
 
 /// Determines whether this type is written as a typedef-name.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 18fd5ba700ad3..e6c3fa51d54da 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -672,12 +672,12 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
 
   // We don't want to throw lvalue-to-rvalue casts on top of
   // expressions of certain types in C++.
-  if (getLangOpts().CPlusPlus) {
-    if (T == Context.OverloadTy || T->isRecordType() ||
-        (T->isDependentType() && !T->isAnyPointerType() &&
-         !T->isMemberPointerType()))
-      return E;
-  }
+  if (getLangOpts().CPlusPlus &&
+      (E->getType() == Context.OverloadTy ||
+       // FIXME: This is a hack! We want the lvalue-to-rvalue conversion applied
+       // to pointer types even if the pointee type is dependent.
+       (T->isDependentType() && !T->isPointerType()) || T->isRecordType()))
+    return E;
 
   // The C standard is actually really unclear on this point, and
   // DR106 tells us what the result should be but not why.  It's
@@ -10827,7 +10827,7 @@ static bool checkArithmeticIncompletePointerType(Sema &S, SourceLocation Loc,
   if (const AtomicType *ResAtomicType = ResType->getAs<AtomicType>())
     ResType = ResAtomicType->getValueType();
 
-  assert(ResType->isAnyPointerType());
+  assert(ResType->isAnyPointerType() && !ResType->isDependentType());
   QualType PointeeTy = ResType->getPointeeType();
   return S.RequireCompleteSizedType(
       Loc, PointeeTy,
@@ -13955,8 +13955,11 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
 static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
                                                ExprValueKind &VK,
                                                ExprObjectKind &OK,
-                                               SourceLocation OpLoc, bool IsInc,
-                                               bool IsPrefix) {
+                                               SourceLocation OpLoc,
+                                               bool IsInc, bool IsPrefix) {
+  if (Op->isTypeDependent())
+    return S.Context.DependentTy;
+
   QualType ResType = Op->getType();
   // Atomic types can be used for increment / decrement where the non-atomic
   // versions can, so ignore the _Atomic() specifier for the purpose of
@@ -14038,6 +14041,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
   }
 }
 
+
 /// getPrimaryDecl - Helper function for CheckAddressOfOperand().
 /// This routine allows us to typecheck complex/recursive expressions
 /// where the declaration is needed for type checking. We only need to
@@ -14407,6 +14411,9 @@ static void RecordModifiableNonNullParam(Sema &S, const Expr *Exp) {
 static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK,
                                         SourceLocation OpLoc,
                                         bool IsAfterAmp = false) {
+  if (Op->isTypeDependent())
+    return S.Context.DependentTy;
+
   ExprResult ConvResult = S.UsualUnaryConversions(Op);
   if (ConvResult.isInvalid())
     return QualType();
@@ -15460,191 +15467,188 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
       return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 1);
   }
 
-  if (InputExpr->isTypeDependent() &&
-      InputExpr->getType()->isSpecificBuiltinType(BuiltinType::Dependent)) {
-    resultType = Context.DependentTy;
-  } else {
-    switch (Opc) {
-    case UO_PreInc:
-    case UO_PreDec:
-    case UO_PostInc:
-    case UO_PostDec:
-      resultType =
-          CheckIncrementDecrementOperand(*this, Input.get(), VK, OK, OpLoc,
-                                         Opc == UO_PreInc || Opc == UO_PostInc,
-                                         Opc == UO_PreInc || Opc == UO_PreDec);
-      CanOverflow = isOverflowingIntegerType(Context, resultType);
+  switch (Opc) {
+  case UO_PreInc:
+  case UO_PreDec:
+  case UO_PostInc:
+  case UO_PostDec:
+    resultType = CheckIncrementDecrementOperand(*this, Input.get(), VK, OK,
+                                                OpLoc,
+                                                Opc == UO_PreInc ||
+                                                Opc == UO_PostInc,
+                                                Opc == UO_PreInc ||
+                                                Opc == UO_PreDec);
+    CanOverflow = isOverflowingIntegerType(Context, resultType);
+    break;
+  case UO_AddrOf:
+    resultType = CheckAddressOfOperand(Input, OpLoc);
+    CheckAddressOfNoDeref(InputExpr);
+    RecordModifiableNonNullParam(*this, InputExpr);
+    break;
+  case UO_Deref: {
+    Input = DefaultFunctionArrayLvalueConversion(Input.get());
+    if (Input.isInvalid()) return ExprError();
+    resultType =
+        CheckIndirectionOperand(*this, Input.get(), VK, OpLoc, IsAfterAmp);
+    break;
+  }
+  case UO_Plus:
+  case UO_Minus:
+    CanOverflow = Opc == UO_Minus &&
+                  isOverflowingIntegerType(Context, Input.get()->getType());
+    Input = UsualUnaryConversions(Input.get());
+    if (Input.isInvalid()) return ExprError();
+    // Unary plus and minus require promoting an operand of half vector to a
+    // float vector and truncating the result back to a half vector. For now, we
+    // do this only when HalfArgsAndReturns is set (that is, when the target is
+    // arm or arm64).
+    ConvertHalfVec = needsConversionOfHalfVec(true, Context, Input.get());
+
+    // If the operand is a half vector, promote it to a float vector.
+    if (ConvertHalfVec)
+      Input = convertVector(Input.get(), Context.FloatTy, *this);
+    resultType = Input.get()->getType();
+    if (resultType->isDependentType())
       break;
-    case UO_AddrOf:
-      resultType = CheckAddressOfOperand(Input, OpLoc);
-      CheckAddressOfNoDeref(InputExpr);
-      RecordModifiableNonNullParam(*this, InputExpr);
+    if (resultType->isArithmeticType()) // C99 6.5.3.3p1
       break;
-    case UO_Deref: {
-      Input = DefaultFunctionArrayLvalueConversion(Input.get());
-      if (Input.isInvalid())
-        return ExprError();
-      resultType =
-          CheckIndirectionOperand(*this, Input.get(), VK, OpLoc, IsAfterAmp);
+    else if (resultType->isVectorType() &&
+             // The z vector extensions don't allow + or - with bool vectors.
+             (!Context.getLangOpts().ZVector ||
+              resultType->castAs<VectorType>()->getVectorKind() !=
+                  VectorKind::AltiVecBool))
+      break;
+    else if (resultType->isSveVLSBuiltinType()) // SVE vectors allow + and -
+      break;
+    else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6
+             Opc == UO_Plus &&
+             resultType->isPointerType())
       break;
+
+    return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+      << resultType << Input.get()->getSourceRange());
+
+  case UO_Not: // bitwise complement
+    Input = UsualUnaryConversions(Input.get());
+    if (Input.isInvalid())
+      return ExprError();
+    resultType = Input.get()->getType();
+    if (resultType->isDependentType())
+      break;
+    // C99 6.5.3.3p1. We allow complex int and float as a GCC extension.
+    if (resultType->isComplexType() || resultType->isComplexIntegerType())
+      // C99 does not support '~' for complex conjugation.
+      Diag(OpLoc, diag::ext_integer_complement_complex)
+          << resultType << Input.get()->getSourceRange();
+    else if (resultType->hasIntegerRepresentation())
+      break;
+    else if (resultType->isExtVectorType() && Context.getLangOpts().OpenCL) {
+      // OpenCL v1.1 s6.3.f: The bitwise operator not (~) does not operate
+      // on vector float types.
+      QualType T = resultType->castAs<ExtVectorType>()->getElementType();
+      if (!T->isIntegerType())
+        return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+                          << resultType << Input.get()->getSourceRange());
+    } else {
+      return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+                       << resultType << Input.get()->getSourceRange());
     }
-    case UO_Plus:
-    case UO_Minus:
-      CanOverflow = Opc == UO_Minus &&
-                    isOverflowingIntegerType(Context, Input.get()->getType());
-      Input = UsualUnaryConversions(Input.get());
-      if (Input.isInvalid())
-        return ExprError();
-      // Unary plus and minus require promoting an operand of half vector to a
-      // float vector and truncating the result back to a half vector. For now,
-      // we do this only when HalfArgsAndReturns is set (that is, when the
-      // target is arm or arm64).
-      ConvertHalfVec = needsConversionOfHalfVec(true, Context, Input.get());
-
-      // If the operand is a half vector, promote it to a float vector.
-      if (ConvertHalfVec)
-        Input = convertVector(Input.get(), Context.FloatTy, *this);
-      resultType = Input.get()->getType();
-      if (resultType->isArithmeticType()) // C99 6.5.3.3p1
-        break;
-      else if (resultType->isVectorType() &&
-               // The z vector extensions don't allow + or - with bool vectors.
-               (!Context.getLangOpts().ZVector ||
-                resultType->castAs<VectorType>()->getVectorKind() !=
-                    VectorKind::AltiVecBool))
-        break;
-      else if (resultType->isSveVLSBuiltinType()) // SVE vectors allow + and -
-        break;
-      else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6
-               Opc == UO_Plus && resultType->isPointerType())
-        break;
+    break;
 
+  case UO_LNot: // logical negation
+    // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
+    Input = DefaultFunctionArrayLvalueConversion(Input.get());
+    if (Input.isInvalid()) return ExprError();
+    resultType = Input.get()->getType();
+
+    // Though we still have to promote half FP to float...
+    if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) {
+      Input = ImpCastExprToType(Input.get(), Context.FloatTy, CK_FloatingCast).get();
+      resultType = Context.FloatTy;
+    }
+
+    // WebAsembly tables can't be used in unary expressions.
+    if (resultType->isPointerType() &&
+        resultType->getPointeeType().isWebAssemblyReferenceType()) {
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
                        << resultType << Input.get()->getSourceRange());
+    }
 
-    case UO_Not: // bitwise complement
-      Input = UsualUnaryConversions(Input.get());
-      if (Input.isInvalid())
-        return ExprError();
-      resultType = Input.get()->getType();
-      // C99 6.5.3.3p1. We allow complex int and float as a GCC extension.
-      if (resultType->isComplexType() || resultType->isComplexIntegerType())
-        // C99 does not support '~' for complex conjugation.
-        Diag(OpLoc, diag::ext_integer_complement_complex)
-            << resultType << Input.get()->getSourceRange();
-      else if (resultType->hasIntegerRepresentation())
-        break;
-      else if (resultType->isExtVectorType() && Context.getLangOpts().OpenCL) {
-        // OpenCL v1.1 s6.3.f: The bitwise operator not (~) does not operate
-        // on vector float types.
+    if (resultType->isDependentType())
+      break;
+    if (resultType->isScalarType() && !isScopedEnumerationType(resultType)) {
+      // C99 6.5.3.3p1: ok, fallthrough;
+      if (Context.getLangOpts().CPlusPlus) {
+        // C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9:
+        // operand contextually converted to bool.
+        Input = ImpCastExprToType(Input.get(), Context.BoolTy,
+                                  ScalarTypeToBooleanCastKind(resultType));
+      } else if (Context.getLangOpts().OpenCL &&
+                 Context.getLangOpts().OpenCLVersion < 120) {
+        // OpenCL v1.1 6.3.h: The logical operator not (!) does not
+        // operate on scalar float types.
+        if (!resultType->isIntegerType() && !resultType->isPointerType())
+          return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+                           << resultType << Input.get()->getSourceRange());
+      }
+    } else if (resultType->isExtVectorType()) {
+      if (Context.getLangOpts().OpenCL &&
+          Context.getLangOpts().getOpenCLCompatibleVersion() < 120) {
+        // OpenCL v1.1 6.3.h: The logical operator not (!) does not
+        // operate on vector float types.
         QualType T = resultType->castAs<ExtVectorType>()->getElementType();
         if (!T->isIntegerType())
           return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
                            << resultType << Input.get()->getSourceRange());
-      } else {
-        return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-                         << resultType << Input.get()->getSourceRange());
       }
+      // Vector logical not returns the signed variant of the operand type.
+      resultType = GetSignedVectorType(resultType);
       break;
-
-    case UO_LNot: // logical negation
-      // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
-      Input = DefaultFunctionArrayLvalueConversion(Input.get());
-      if (Input.isInvalid())
-        return ExprError();
-      resultType = Input.get()->getType();
-
-      // Though we still have to promote half FP to float...
-      if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) {
-        Input = ImpCastExprToType(Input.get(), Context.FloatTy, CK_FloatingCast)
-                    .get();
-        resultType = Context.FloatTy;
-      }
-
-      // WebAsembly tables can't be used in unary expressions.
-      if (resultType->isPointerType() &&
-          resultType->getPointeeType().isWebAssemblyReferenceType()) {
-        return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-                         << resultType << Input.get()->getSourceRange());
-      }
-
-      if (resultType->isScalarType() && !isScopedEnumerationType(resultType)) {
-        // C99 6.5.3.3p1: ok, fallthrough;
-        if (Context.getLangOpts().CPlusPlus) {
-          // C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9:
-          // operand contextually converted to bool.
-          Input = ImpCastExprToType(Input.get(), Context.BoolTy,
-                                    ScalarTypeToBooleanCastKind(resultType));
-        } else if (Context.getLangOpts().OpenCL &&
-                   Context.getLangOpts().OpenCLVersion < 120) {
-          // OpenCL v1.1 6.3.h: The logical operator not (!) does not
-          // operate on scalar float types.
-          if (!resultType->isIntegerType() && !resultType->isPointerType())
-            return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-                             << resultType << Input.get()->getSourceRange());
-        }
-      } else if (resultType->isExtVectorType()) {
-        if (Context.getLangOpts().OpenCL &&
-            Context.getLangOpts().getOpenCLCompatibleVersion() < 120) {
-          // OpenCL v1.1 6.3.h: The logical operator not (!) does not
-          // operate on vector float types.
-          QualType T = resultType->castAs<ExtVectorType>()->getElementType();
-          if (!T->isIntegerType())
-            return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-                             << resultType << Input.get()->getSourceRange());
-        }
-        // Vector logical not returns the signed variant of the operand type.
-        resultType = GetSignedVectorType(resultType);
-        break;
-      } else if (Context.getLangOpts().CPlusPlus &&
-                 resultType->isVectorType()) {
-        const VectorType *VTy = resultType->castAs<VectorType>();
-        if (VTy->getVectorKind() != VectorKind::Generic)
-          return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-                           << resultType << Input.get()->getSourceRange());
-
-        // Vector logical not returns the signed variant of the operand type.
-        resultType = GetSignedVectorType(resultType);
-        break;
-      } else {
+    } else if (Context.getLangOpts().CPlusPlus && resultType->isVectorType()) {
+      const VectorType *VTy = resultType->castAs<VectorType>();
+      if (VTy->getVectorKind() != VectorKind::Generic)
         return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
                          << resultType << Input.get()->getSourceRange());
-      }
 
-      // LNot always has type int. C99 6.5.3.3p5.
-      // In C++, it's bool. C++ 5.3.1p8
-      resultType = Context.getLogicalOperationType();
-      break;
-    case UO_Real:
-    case UO_Imag:
-      resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real);
-      // _Real maps ordinary l-values into ordinary l-values. _Imag maps
-      // ordinary complex l-values to ordinary l-values and all other values to
-      // r-values.
-      if (Input.isInvalid())
-        return ExprError();
-      if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) {
-        if (Input.get()->isGLValue() &&
-            Input.get()->getObjectKind() == OK_Ordinary)
-          VK = Input.get()->getValueKind();
-      } else if (!getLangOpts().CPlusPlus) {
-        // In C, a volatile scalar is read by __imag. In C++, it is not.
-        Input = DefaultLvalueConversion(Input.get());
-      }
-      break;
-    case UO_Extension:
-      resultType = Input.get()->getType();
-      VK = Input.get()->getValueKind();
-      OK = Input.get()->getObjectKind();
+      // Vector logical not returns the signed variant of the operand type.
+      resultType = GetSignedVectorType(resultType);
       break;
-    case UO_Coawait:
-      // It's unnecessary to represent the pass-through operator co_await in the
-      // AST; just return the input expression instead.
-      assert(!Input.get()->getType()->isDependentType() &&
-             "the co_await expression must be non-dependant before "
-             "building operator co_await");
-      return Input;
+    } else {
+      return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
+        << resultType << Input.get()->getSourceRange());
     }
+
+    // LNot always has type int. C99 6.5.3.3p5.
+    // In C++, it's bool. C++ 5.3.1p8
+    resultType = Context.getLogicalOperationType();
+    break;
+  case UO_Real:
+  case UO_Imag:
+    resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real);
+    // _Real maps ordinary l-values into ordinary l-values. _Imag maps ordinary
+    // complex l-values to ordinary l-values and all other values to r-values.
+    if (Input.isInvalid()) return ExprError();
+    if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) {
+      if (Input.get()->isGLValue() &&
+          Input.get()->getObjectKind() == OK_Ordinary)
+        VK = Input.get()->getValueKind();
+    } else if (!getLangOpts().CPlusPlus) {
+      // In C, a volatile scalar is read by __imag. In C++, it is not.
+      Inp...
[truncated]

Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 6c8ebc053533c691099ab60c41261b3cb4ba2fa3 a55eb47a72fd6b5d703e7c20e2cbf5b2aa7fd78d -- clang/include/clang/AST/Type.h clang/lib/Sema/SemaExpr.cpp clang/test/AST/ast-dump-expr-json.cpp clang/test/AST/ast-dump-expr.cpp clang/test/AST/ast-dump-lambda.cpp clang/test/CXX/over/over.built/ast.cpp clang/test/CXX/over/over.built/p10.cpp clang/test/CXX/over/over.built/p11.cpp clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp clang/test/Frontend/noderef_templates.cpp clang/test/SemaCXX/cxx2b-deducing-this.cpp clang/test/SemaTemplate/class-template-spec.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
View the diff from clang-format here.
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e6c3fa51d5..ec84798e4c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13955,8 +13955,8 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
 static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
                                                ExprValueKind &VK,
                                                ExprObjectKind &OK,
-                                               SourceLocation OpLoc,
-                                               bool IsInc, bool IsPrefix) {
+                                               SourceLocation OpLoc, bool IsInc,
+                                               bool IsPrefix) {
   if (Op->isTypeDependent())
     return S.Context.DependentTy;
 
@@ -14041,7 +14041,6 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op,
   }
 }
 
-
 /// getPrimaryDecl - Helper function for CheckAddressOfOperand().
 /// This routine allows us to typecheck complex/recursive expressions
 /// where the declaration is needed for type checking. We only need to
@@ -15472,12 +15471,10 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
   case UO_PreDec:
   case UO_PostInc:
   case UO_PostDec:
-    resultType = CheckIncrementDecrementOperand(*this, Input.get(), VK, OK,
-                                                OpLoc,
-                                                Opc == UO_PreInc ||
-                                                Opc == UO_PostInc,
-                                                Opc == UO_PreInc ||
-                                                Opc == UO_PreDec);
+    resultType =
+        CheckIncrementDecrementOperand(*this, Input.get(), VK, OK, OpLoc,
+                                       Opc == UO_PreInc || Opc == UO_PostInc,
+                                       Opc == UO_PreInc || Opc == UO_PreDec);
     CanOverflow = isOverflowingIntegerType(Context, resultType);
     break;
   case UO_AddrOf:
@@ -15487,7 +15484,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     break;
   case UO_Deref: {
     Input = DefaultFunctionArrayLvalueConversion(Input.get());
-    if (Input.isInvalid()) return ExprError();
+    if (Input.isInvalid())
+      return ExprError();
     resultType =
         CheckIndirectionOperand(*this, Input.get(), VK, OpLoc, IsAfterAmp);
     break;
@@ -15497,7 +15495,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     CanOverflow = Opc == UO_Minus &&
                   isOverflowingIntegerType(Context, Input.get()->getType());
     Input = UsualUnaryConversions(Input.get());
-    if (Input.isInvalid()) return ExprError();
+    if (Input.isInvalid())
+      return ExprError();
     // Unary plus and minus require promoting an operand of half vector to a
     // float vector and truncating the result back to a half vector. For now, we
     // do this only when HalfArgsAndReturns is set (that is, when the target is
@@ -15521,12 +15520,11 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     else if (resultType->isSveVLSBuiltinType()) // SVE vectors allow + and -
       break;
     else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6
-             Opc == UO_Plus &&
-             resultType->isPointerType())
+             Opc == UO_Plus && resultType->isPointerType())
       break;
 
     return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-      << resultType << Input.get()->getSourceRange());
+                     << resultType << Input.get()->getSourceRange());
 
   case UO_Not: // bitwise complement
     Input = UsualUnaryConversions(Input.get());
@@ -15548,7 +15546,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
       QualType T = resultType->castAs<ExtVectorType>()->getElementType();
       if (!T->isIntegerType())
         return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-                          << resultType << Input.get()->getSourceRange());
+                         << resultType << Input.get()->getSourceRange());
     } else {
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
                        << resultType << Input.get()->getSourceRange());
@@ -15558,12 +15556,14 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
   case UO_LNot: // logical negation
     // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
     Input = DefaultFunctionArrayLvalueConversion(Input.get());
-    if (Input.isInvalid()) return ExprError();
+    if (Input.isInvalid())
+      return ExprError();
     resultType = Input.get()->getType();
 
     // Though we still have to promote half FP to float...
     if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) {
-      Input = ImpCastExprToType(Input.get(), Context.FloatTy, CK_FloatingCast).get();
+      Input = ImpCastExprToType(Input.get(), Context.FloatTy, CK_FloatingCast)
+                  .get();
       resultType = Context.FloatTy;
     }
 
@@ -15615,7 +15615,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
       break;
     } else {
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
-        << resultType << Input.get()->getSourceRange());
+                       << resultType << Input.get()->getSourceRange());
     }
 
     // LNot always has type int. C99 6.5.3.3p5.
@@ -15627,7 +15627,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real);
     // _Real maps ordinary l-values into ordinary l-values. _Imag maps ordinary
     // complex l-values to ordinary l-values and all other values to r-values.
-    if (Input.isInvalid()) return ExprError();
+    if (Input.isInvalid())
+      return ExprError();
     if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) {
       if (Input.get()->isGLValue() &&
           Input.get()->getObjectKind() == OK_Ordinary)
@@ -15646,8 +15647,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     // It's unnecessary to represent the pass-through operator co_await in the
     // AST; just return the input expression instead.
     assert(!Input.get()->getType()->isDependentType() &&
-                   "the co_await expression must be non-dependant before "
-                   "building operator co_await");
+           "the co_await expression must be non-dependant before "
+           "building operator co_await");
     return Input;
   }
   if (resultType.isNull() || Input.isInvalid())

@sdkrystian sdkrystian merged commit 97e35e0 into llvm:main May 14, 2024
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants