llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: PrabbyDD

<details>
<summary>Changes</summary>

…in templates. Fixes #<!-- -->190756 . Clang was rejecting array comparisons 
where types are known correctly, but not for dependent types like inside 
function templates or anything that wraps a template. Fix by not skipping the 
array comparison check when our operands in the template are arrays so we can 
send an error. Non array types in templates skip these checks.

---

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


2 Files Affected:

- (modified) clang/lib/Sema/SemaExpr.cpp (+1310-1218) 
- (added) clang/test/SemaCXX/array-compare-template.cpp (+8) 


``````````diff
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9fd8c6a0a5451..ef67a26a588ab 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -141,7 +141,7 @@ void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
     return NoteDeletedInheritingConstructor(Ctor);
 
   Diag(Decl->getLocation(), diag::note_availability_specified_here)
-    << Decl << 1;
+      << Decl << 1;
 }
 
 /// Determine whether a FunctionDecl was ever declared with an
@@ -219,7 +219,7 @@ void Sema::MaybeSuggestAddingStaticToDecl(const 
FunctionDecl *Cur) {
   if (!hasAnyExplicitStorageClass(First)) {
     SourceLocation DeclBegin = First->getSourceRange().getBegin();
     Diag(DeclBegin, diag::note_convert_inline_to_static)
-      << Cur << FixItHint::CreateInsertion(DeclBegin, "static ");
+        << Cur << FixItHint::CreateInsertion(DeclBegin, "static ");
   }
 }
 
@@ -258,7 +258,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, 
ArrayRef<SourceLocation> Locs,
   if (ParsingInitForAutoVars.count(D)) {
     if (isa<BindingDecl>(D)) {
       Diag(Loc, diag::err_binding_cannot_appear_in_own_initializer)
-        << D->getDeclName();
+          << D->getDeclName();
     } else {
       Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
           << diag::ParsingInitFor::Var << D->getDeclName()
@@ -300,8 +300,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, 
ArrayRef<SourceLocation> Locs,
         // constraint expression, for example)
         return true;
       if (!Satisfaction.IsSatisfied) {
-        Diag(Loc,
-             diag::err_reference_to_function_with_unsatisfied_constraints)
+        Diag(Loc, diag::err_reference_to_function_with_unsatisfied_constraints)
             << D;
         DiagnoseUnsatisfiedConstraint(Satisfaction);
         return true;
@@ -316,7 +315,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, 
ArrayRef<SourceLocation> Locs,
 
     if (getLangOpts().CUDA && !CUDA().CheckCall(Loc, FD))
       return true;
-
   }
 
   if (auto *Concept = dyn_cast<ConceptDecl>(D);
@@ -330,12 +328,12 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, 
ArrayRef<SourceLocation> Locs,
           cast<CXXConstructorDecl>(MD)->isDefaultConstructor()) ||
          MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())) {
       Diag(Loc, diag::warn_cxx17_compat_lambda_def_ctor_assign)
-        << !isa<CXXConstructorDecl>(MD);
+          << !isa<CXXConstructorDecl>(MD);
     }
   }
 
-  auto getReferencedObjCProp = [](const NamedDecl *D) ->
-                                      const ObjCPropertyDecl * {
+  auto getReferencedObjCProp =
+      [](const NamedDecl *D) -> const ObjCPropertyDecl * {
     if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
       return MD->findPropertyDecl();
     return nullptr;
@@ -344,7 +342,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, 
ArrayRef<SourceLocation> Locs,
     if (diagnoseArgIndependentDiagnoseIfAttrs(ObjCPDecl, Loc))
       return true;
   } else if (diagnoseArgIndependentDiagnoseIfAttrs(D, Loc)) {
-      return true;
+    return true;
   }
 
   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
@@ -521,7 +519,8 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, 
bool Diagnose) {
   // Handle any placeholder expressions which made it here.
   if (E->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
-    if (result.isInvalid()) return ExprError();
+    if (result.isInvalid())
+      return ExprError();
     E = result.get();
   }
 
@@ -535,7 +534,8 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E, 
bool Diagnose) {
           return ExprError();
 
     E = ImpCastExprToType(E, Context.getPointerType(Ty),
-                          CK_FunctionToPointerDecay).get();
+                          CK_FunctionToPointerDecay)
+            .get();
   } else if (Ty->isArrayType()) {
     // In C90 mode, arrays only promote to pointers if the array expression is
     // an lvalue.  The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
@@ -585,8 +585,7 @@ static void CheckForNullPointerDereference(Sema &S, Expr 
*E) {
 }
 
 static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE,
-                                    SourceLocation AssignLoc,
-                                    const Expr* RHS) {
+                                    SourceLocation AssignLoc, const Expr *RHS) 
{
   const ObjCIvarDecl *IV = OIRE->getDecl();
   if (!IV)
     return;
@@ -604,13 +603,12 @@ static void DiagnoseDirectIsaAccess(Sema &S, const 
ObjCIvarRefExpr *OIRE,
     if (ObjCInterfaceDecl *IDecl = OTy->getInterface()) {
       ObjCInterfaceDecl *ClassDeclared = nullptr;
       ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
-      if (!ClassDeclared->getSuperClass()
-          && (*ClassDeclared->ivar_begin()) == IV) {
+      if (!ClassDeclared->getSuperClass() &&
+          (*ClassDeclared->ivar_begin()) == IV) {
         if (RHS) {
-          NamedDecl *ObjectSetClass =
-            S.LookupSingleName(S.TUScope,
-                               &S.Context.Idents.get("object_setClass"),
-                               SourceLocation(), S.LookupOrdinaryName);
+          NamedDecl *ObjectSetClass = S.LookupSingleName(
+              S.TUScope, &S.Context.Idents.get("object_setClass"),
+              SourceLocation(), S.LookupOrdinaryName);
           if (ObjectSetClass) {
             SourceLocation RHSLocEnd = S.getLocForEndOfToken(RHS->getEndLoc());
             S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign)
@@ -619,14 +617,12 @@ static void DiagnoseDirectIsaAccess(Sema &S, const 
ObjCIvarRefExpr *OIRE,
                 << FixItHint::CreateReplacement(
                        SourceRange(OIRE->getOpLoc(), AssignLoc), ",")
                 << FixItHint::CreateInsertion(RHSLocEnd, ")");
-          }
-          else
+          } else
             S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign);
         } else {
-          NamedDecl *ObjectGetClass =
-            S.LookupSingleName(S.TUScope,
-                               &S.Context.Idents.get("object_getClass"),
-                               SourceLocation(), S.LookupOrdinaryName);
+          NamedDecl *ObjectGetClass = S.LookupSingleName(
+              S.TUScope, &S.Context.Idents.get("object_getClass"),
+              SourceLocation(), S.LookupOrdinaryName);
           if (ObjectGetClass)
             S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use)
                 << FixItHint::CreateInsertion(OIRE->getBeginLoc(),
@@ -645,14 +641,16 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
   // Handle any placeholder expressions which made it here.
   if (E->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
-    if (result.isInvalid()) return ExprError();
+    if (result.isInvalid())
+      return ExprError();
     E = result.get();
   }
 
   // C++ [conv.lval]p1:
   //   A glvalue of a non-function, non-array type T can be
   //   converted to a prvalue.
-  if (!E->isGLValue()) return E;
+  if (!E->isGLValue())
+    return E;
 
   QualType T = E->getType();
   assert(!T.isNull() && "r-value conversion on typeless expression?");
@@ -683,16 +681,15 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
   if (getLangOpts().OpenCL &&
       !getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts()) &&
       T->isHalfType()) {
-    Diag(E->getExprLoc(), diag::err_opencl_half_load_store)
-      << 0 << T;
+    Diag(E->getExprLoc(), diag::err_opencl_half_load_store) << 0 << T;
     return ExprError();
   }
 
   CheckForNullPointerDereference(*this, E);
   if (const ObjCIsaExpr *OISA = dyn_cast<ObjCIsaExpr>(E->IgnoreParenCasts())) {
-    NamedDecl *ObjectGetClass = LookupSingleName(TUScope,
-                                     &Context.Idents.get("object_getClass"),
-                                     SourceLocation(), LookupOrdinaryName);
+    NamedDecl *ObjectGetClass =
+        LookupSingleName(TUScope, &Context.Idents.get("object_getClass"),
+                         SourceLocation(), LookupOrdinaryName);
     if (ObjectGetClass)
       Diag(E->getExprLoc(), diag::warn_objc_isa_use)
           << FixItHint::CreateInsertion(OISA->getBeginLoc(), 
"object_getClass(")
@@ -700,10 +697,9 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
                  SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")");
     else
       Diag(E->getExprLoc(), diag::warn_objc_isa_use);
-  }
-  else if (const ObjCIvarRefExpr *OIRE =
-            dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts()))
-    DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/nullptr);
+  } else if (const ObjCIvarRefExpr *OIRE =
+                 dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts()))
+    DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/ nullptr);
 
   // C++ [conv.lval]p1:
   //   [...] If T is a non-class type, the type of the prvalue is the
@@ -727,8 +723,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
     return Res;
   E = Res.get();
 
-  // Loading a __weak object implicitly retains the value, so we need a 
cleanup to
-  // balance that.
+  // Loading a __weak object implicitly retains the value, so we need a cleanup
+  // to balance that.
   if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
     Cleanup.setExprNeedsCleanups(true);
 
@@ -937,8 +933,8 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
   // potentially potentially evaluated contexts.
   if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) {
     ExprResult Temp = PerformCopyInitialization(
-                       InitializedEntity::InitializeTemporary(E->getType()),
-                                                E->getExprLoc(), E);
+        InitializedEntity::InitializeTemporary(E->getType()), E->getExprLoc(),
+        E);
     if (Temp.isInvalid())
       return ExprError();
     E = Temp.get();
@@ -1134,8 +1130,10 @@ static bool handleComplexIntegerToFloatConversion(Sema 
&S, ExprResult &IntExpr,
                                                   QualType IntTy,
                                                   QualType ComplexTy,
                                                   bool SkipCast) {
-  if (IntTy->isComplexType() || IntTy->isRealFloatingType()) return true;
-  if (SkipCast) return false;
+  if (IntTy->isComplexType() || IntTy->isRealFloatingType())
+    return true;
+  if (SkipCast)
+    return false;
   if (IntTy->isIntegerType()) {
     QualType fpTy = ComplexTy->castAs<ComplexType>()->getElementType();
     IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating);
@@ -1211,8 +1209,8 @@ static QualType handleIntToFloatConversion(Sema &S, 
ExprResult &FloatExpr,
   if (IntTy->isIntegerType()) {
     if (ConvertInt)
       // Convert intExpr to the lhs floating point type.
-      IntExpr = S.ImpCastExprToType(IntExpr.get(), FloatTy,
-                                    CK_IntegralToFloating);
+      IntExpr =
+          S.ImpCastExprToType(IntExpr.get(), FloatTy, CK_IntegralToFloating);
     return FloatTy;
   }
 
@@ -1227,17 +1225,17 @@ static QualType handleIntToFloatConversion(Sema &S, 
ExprResult &FloatExpr,
 
   // float -> _Complex float
   if (ConvertFloat)
-    FloatExpr = S.ImpCastExprToType(FloatExpr.get(), result,
-                                    CK_FloatingRealToComplex);
+    FloatExpr =
+        S.ImpCastExprToType(FloatExpr.get(), result, CK_FloatingRealToComplex);
 
   return result;
 }
 
 /// Handle arithmethic conversion with floating point types.  Helper
 /// function of UsualArithmeticConversions()
-static QualType handleFloatConversion(Sema &S, ExprResult &LHS,
-                                      ExprResult &RHS, QualType LHSType,
-                                      QualType RHSType, bool IsCompAssign) {
+static QualType handleFloatConversion(Sema &S, ExprResult &LHS, ExprResult 
&RHS,
+                                      QualType LHSType, QualType RHSType,
+                                      bool IsCompAssign) {
   bool LHSFloat = LHSType->isRealFloatingType();
   bool RHSFloat = RHSType->isRealFloatingType();
 
@@ -1274,11 +1272,11 @@ static QualType handleFloatConversion(Sema &S, 
ExprResult &LHS,
 
     return handleIntToFloatConversion(S, LHS, RHS, LHSType, RHSType,
                                       /*ConvertFloat=*/!IsCompAssign,
-                                      /*ConvertInt=*/ true);
+                                      /*ConvertInt=*/true);
   }
   assert(RHSFloat);
   return handleIntToFloatConversion(S, RHS, LHS, RHSType, LHSType,
-                                    /*ConvertFloat=*/ true,
+                                    /*ConvertFloat=*/true,
                                     /*ConvertInt=*/!IsCompAssign);
 }
 
@@ -1323,7 +1321,7 @@ ExprResult doComplexIntegralCast(Sema &S, Expr *op, 
QualType toType) {
   return S.ImpCastExprToType(op, S.Context.getComplexType(toType),
                              CK_IntegralComplexCast);
 }
-}
+} // namespace
 
 /// Handle integer arithmetic conversions.  Helper function of
 /// UsualArithmeticConversions()
@@ -1368,7 +1366,7 @@ static QualType handleIntegerConversion(Sema &S, 
ExprResult &LHS,
     // on most 32-bit systems).  Use the unsigned type corresponding
     // to the signed type.
     QualType result =
-      S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType);
+        S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType);
     RHS = (*doRHSCast)(S, RHS.get(), result);
     if (!IsCompAssign)
       LHS = (*doLHSCast)(S, LHS.get(), result);
@@ -1389,8 +1387,8 @@ static QualType handleComplexIntConversion(Sema &S, 
ExprResult &LHS,
     QualType LHSEltType = LHSComplexInt->getElementType();
     QualType RHSEltType = RHSComplexInt->getElementType();
     QualType ScalarType =
-      handleIntegerConversion<doComplexIntegralCast, doComplexIntegralCast>
-        (S, LHS, RHS, LHSEltType, RHSEltType, IsCompAssign);
+        handleIntegerConversion<doComplexIntegralCast, doComplexIntegralCast>(
+            S, LHS, RHS, LHSEltType, RHSEltType, IsCompAssign);
 
     return S.Context.getComplexType(ScalarType);
   }
@@ -1398,11 +1396,10 @@ static QualType handleComplexIntConversion(Sema &S, 
ExprResult &LHS,
   if (LHSComplexInt) {
     QualType LHSEltType = LHSComplexInt->getElementType();
     QualType ScalarType =
-      handleIntegerConversion<doComplexIntegralCast, doIntegralCast>
-        (S, LHS, RHS, LHSEltType, RHSType, IsCompAssign);
+        handleIntegerConversion<doComplexIntegralCast, doIntegralCast>(
+            S, LHS, RHS, LHSEltType, RHSType, IsCompAssign);
     QualType ComplexType = S.Context.getComplexType(ScalarType);
-    RHS = S.ImpCastExprToType(RHS.get(), ComplexType,
-                              CK_IntegralRealToComplex);
+    RHS = S.ImpCastExprToType(RHS.get(), ComplexType, 
CK_IntegralRealToComplex);
 
     return ComplexType;
   }
@@ -1411,13 +1408,12 @@ static QualType handleComplexIntConversion(Sema &S, 
ExprResult &LHS,
 
   QualType RHSEltType = RHSComplexInt->getElementType();
   QualType ScalarType =
-    handleIntegerConversion<doIntegralCast, doComplexIntegralCast>
-      (S, LHS, RHS, LHSType, RHSEltType, IsCompAssign);
+      handleIntegerConversion<doIntegralCast, doComplexIntegralCast>(
+          S, LHS, RHS, LHSType, RHSEltType, IsCompAssign);
   QualType ComplexType = S.Context.getComplexType(ScalarType);
 
   if (!IsCompAssign)
-    LHS = S.ImpCastExprToType(LHS.get(), ComplexType,
-                              CK_IntegralRealToComplex);
+    LHS = S.ImpCastExprToType(LHS.get(), ComplexType, 
CK_IntegralRealToComplex);
   return ComplexType;
 }
 
@@ -1788,7 +1784,6 @@ QualType Sema::UsualArithmeticConversions(ExprResult 
&LHS, ExprResult &RHS,
 //  Semantic Analysis for various Expression Types
 
//===----------------------------------------------------------------------===//
 
-
 ExprResult Sema::ActOnGenericSelectionExpr(
     SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc,
     bool PredicateIsExpr, void *ControllingExprOrType,
@@ -1796,10 +1791,10 @@ ExprResult Sema::ActOnGenericSelectionExpr(
   unsigned NumAssocs = ArgTypes.size();
   assert(NumAssocs == ArgExprs.size());
 
-  TypeSourceInfo **Types = new TypeSourceInfo*[NumAssocs];
+  TypeSourceInfo **Types = new TypeSourceInfo *[NumAssocs];
   for (unsigned i = 0; i < NumAssocs; ++i) {
     if (ArgTypes[i])
-      (void) GetTypeFromParser(ArgTypes[i], &Types[i]);
+      (void)GetTypeFromParser(ArgTypes[i], &Types[i]);
     else
       Types[i] = nullptr;
   }
@@ -1817,7 +1812,7 @@ ExprResult Sema::ActOnGenericSelectionExpr(
   ExprResult ER = CreateGenericSelectionExpr(
       KeyLoc, DefaultLoc, RParenLoc, PredicateIsExpr, ControllingExprOrType,
       llvm::ArrayRef(Types, NumAssocs), ArgExprs);
-  delete [] Types;
+  delete[] Types;
   return ER;
 }
 
@@ -1966,19 +1961,17 @@ ExprResult Sema::CreateGenericSelectionExpr(
 
         // C11 6.5.1.1p2 "No two generic associations in the same generic
         // selection shall specify compatible types."
-        for (unsigned j = i+1; j < NumAssocs; ++j)
+        for (unsigned j = i + 1; j < NumAssocs; ++j)
           if (Types[j] && !Types[j]->getType()->isDependentType() &&
               areTypesCompatibleForGeneric(Context, Types[i]->getType(),
                                            Types[j]->getType())) {
             Diag(Types[j]->getTypeLoc().getBeginLoc(),
                  diag::err_assoc_compatible_types)
-              << Types[j]->getTypeLoc().getSourceRange()
-              << Types[j]->getType()
-              << Types[i]->getType();
-            Diag(Types[i]->getTypeLoc().getBeginLoc(),
-                 diag::note_compat_assoc)
-              << Types[i]->getTypeLoc().getSourceRange()
-              << Types[i]->getType();
+                << Types[j]->getTypeLoc().getSourceRange()
+                << Types[j]->getType() << Types[i]->getType();
+            Diag(Types[i]->getTypeLoc().getBeginLoc(), diag::note_compat_assoc)
+                << Types[i]->getTypeLoc().getSourceRange()
+                << Types[i]->getType();
             TypeErrorFound = true;
           }
       }
@@ -2047,10 +2040,8 @@ ExprResult Sema::CreateGenericSelectionExpr(
     Diag(SR.getBegin(), diag::err_generic_sel_multi_match)
         << SR << P.second << (unsigned)CompatIndices.size();
     for (unsigned I : CompatIndices) {
-      Diag(Types[I]->getTypeLoc().getBeginLoc(),
-           diag::note_compat_assoc)
-        << Types[I]->getTypeLoc().getSourceRange()
-        << Types[I]->getType();
+      Diag(Types[I]->getTypeLoc().getBeginLoc(), diag::note_compat_assoc)
+          << Types[I]->getTypeLoc().getSourceRange() << Types[I]->getType();
     }
     return ExprError();
   }
@@ -2071,8 +2062,7 @@ ExprResult Sema::CreateGenericSelectionExpr(
   // then the result expression of the generic selection is the expression
   // in that generic association. Otherwise, the result expression of the
   // generic selection is the expression in the default generic association."
-  unsigned ResultIndex =
-    CompatIndices.size() ? CompatIndices[0] : DefaultIndex;
+  unsigned ResultIndex = CompatIndices.size() ? CompatIndices[0] : 
DefaultIndex;
 
   if (ControllingExpr) {
     return GenericSelectionExpr::Create(
@@ -2127,7 +2117,7 @@ static SourceLocation getUDSuffixLoc(Sema &S, 
SourceLocation TokLoc,
 static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope,
                                                  IdentifierInfo *UDSuffix,
                                                  SourceLocation UDSuffixLoc,
-                                                 ArrayRef<Expr*> Args,
+                                                 ArrayRef<Expr *> Args,
                                                  SourceLocation LitEndLoc) {
   assert(Args.size() <= 2 && "too many arguments for literal operator");
 
@@ -2139,7 +2129,7 @@ static ExprResult BuildCookedLiteralOperatorCall(Sema &S, 
Scope *Scope,
   }
 
   DeclarationName OpName =
-    S.Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
+      S.Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix);
   DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc);
   OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc);
 
@@ -2231,8 +2221,8 @@ Sema::ExpandFunctionLocalPredefinedMacros(ArrayRef<Token> 
Toks)...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/191101
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to