rsandifo-arm created this revision.
rsandifo-arm added reviewers: sdesmalen, efriedma, rovka, rjmccall.
Herald added subscribers: cfe-commits, danielkiss, psnobl, jfb, rkruppe, 
kristof.beyls, tschuett.
Herald added a reviewer: rengolin.
Herald added a project: clang.
rsandifo-arm added a parent revision: D76219: [Sema][SVE] Reject "delete" with 
sizeless types.

Sizeless types are defined to be a form of incomplete type, but with
more relaxed rules in certain cases.  Previous patches in the series
took the following approach:

- Add tests for things that are explicitly supposed to be valid for sizeless 
types and that clang already handled correctly.

- Add diagnostics for things that are explicitly supposed to be invalid for 
sizeless types, in many cases inheriting the same rules as for incomplete types.

For any other cases, we should conservatively treat sizeless types as
in the same way as incomplete types.  This patch therefore flips the
default behavior for RequireCompleteType and co.  Callers that want
to accept sizeless types must then explicitly pass AcceptSizeless.

The Sema::BuildObjCEncodeExpression change is needed to keep
clang/test/CodeGenObjC/aarch64-sve-types.m passing.  If @encoding a
sizeless type will never be useful, we could enforce that here instead.

For reference, here's a list of every other function that now passes
AcceptSizeless, along with one example line from Sema/sizeless-1.c
or SemaCXX/sizeless-1.cpp that would regress without the change.

- CastOperation::CheckCStyleCast

  local_int8 = (svint8_t)0; // expected-error {{...arithmetic or pointer type 
is required...}}

- Sema::CheckParmsForFunctionDef

  int vararg_receiver(int count, svint8_t first, ...) {

- Sema::AddInitializerToDecl

  svint8_t init_int8 = local_int8;

- Sema::ActOnInitializerError

  svint8_t bad_init_int8 = for; // expected-error {{expected expression}}

- Sema::ActOnUninitializedDecl

  svint8_t local_int8;

- Sema::ActOnStartOfFunctionDef

  svint8_t ret_bad_conv() { return explicit_conv(); }

- Sema::SetParamDefaultArgument

  void with_default(svint8_t = svint8_t());

- Sema::BuildExceptionDeclaration

  } catch (svint8_t) { // expected-error {{...sizeless type...}}

- Sema::CheckSpecifiedExceptionType

  void throwing_func() throw(svint8_t); // expected-error {{...sizeless...}}

- Sema::DefaultVariadicArgumentPromotion

  varargs(1, local_int8, local_int16);

- Sema::GatherArgumentsForCall

  pass_int8(local_int8);

- Sema::BuildResolvedCallExpr

  noproto(local_int8);

- CheckCommaOperands

  0, local_int8;

- Sema::BuildVAArgExpr

  __builtin_va_arg(va, svint8_t);

- Sema::CheckCXXThrowOperand

  throw local_int8; // expected-error {{...sizeless type...}}

- Sema::BuildCXXTypeConstructExpr

  void with_default(svint8_t = svint8_t());

- CheckUnaryTypeTraitTypeCompleteness

  _Static_assert(__is_trivially_destructible(svint8_t), "");

- evaluateTypeTrait

  _Static_assert(__is_constructible(svint8_t), "");

- EvaluateBinaryTypeTrait

  _Static_assert(__is_convertible_to(svint8_t, svint8_t), ""); 
_Static_assert(!__is_assignable(svint8_t, svint8_t), "");

- Sema::IgnoredValueConversions

  (void)local_int8;

- CopyObject

  widget w(1);

- InitializationSequence::Diagnose

  svint8_t ret_bad_conv() { return explicit_conv(); }

- Sema::buildLambdaScope

  local_int8 = ([]() { return svint8_t(); })();

- TryListConversion

  template_fn_direct<svint8_t>({wrapper<svint8_t>()});

- Sema::AddConversionCandidate

  local_int8 = wrapper<svint8_t>();

- Sema::BuildCXXForRangeStmt

  for (auto x : local_int8) {

- Sema::BuildAtomicType

  _Atomic svint8_t atomic_int8; // expected-error {{...sizeless...}}


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76221

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaCast.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaExprObjC.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaType.cpp

Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -7924,7 +7924,7 @@
 
 bool Sema::RequireCompleteExprType(Expr *E, unsigned DiagID) {
   BoundTypeDiagnoser<> Diagnoser(DiagID);
-  return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser);
+  return RequireCompleteExprType(E, CompleteTypeKind::Normal, Diagnoser);
 }
 
 /// Ensure that the type T is a complete type.
@@ -8555,7 +8555,10 @@
   if (!T->isDependentType()) {
     // FIXME: It isn't entirely clear whether incomplete atomic types
     // are allowed or not; for simplicity, ban them for the moment.
-    if (RequireCompleteType(Loc, T, diag::err_atomic_specifier_bad_type, 0))
+    //
+    // Fall through to the code below for sizeless types.
+    if (RequireCompleteType(Loc, T, CompleteTypeKind::AcceptSizeless,
+                            diag::err_atomic_specifier_bad_type, 0))
       return QualType();
 
     int DisallowedKind = -1;
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -2420,7 +2420,10 @@
       return StmtError();
     QualType RangeType = Range->getType();
 
+    // For sizeless types it's better to report the same "no viable
+    // 'begin' function" diagnostic as we would for scalars.
     if (RequireCompleteType(RangeLoc, RangeType,
+                            CompleteTypeKind::AcceptSizeless,
                             diag::err_for_range_incomplete_type))
       return StmtError();
 
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -4935,9 +4935,11 @@
   ImplicitConversionSequence Result;
   Result.setBad(BadConversionSequence::no_conversion, From, ToType);
 
-  // We need a complete type for what follows. Incomplete types can never be
-  // initialized from init lists.
-  if (!S.isCompleteType(From->getBeginLoc(), ToType))
+  // We need a completely-defined (but possibly sizeless) type for what
+  // follows. Incompletely-defined types can never be initialized from
+  // init lists.
+  if (!S.isCompleteType(From->getBeginLoc(), ToType,
+                        Sema::CompleteTypeKind::AcceptSizeless))
     return Result;
 
   // Per DR1467:
@@ -7266,7 +7268,8 @@
                                 &ConversionRef, VK_RValue);
 
   QualType ConversionType = Conversion->getConversionType();
-  if (!isCompleteType(From->getBeginLoc(), ConversionType)) {
+  if (!isCompleteType(From->getBeginLoc(), ConversionType,
+                      CompleteTypeKind::AcceptSizeless)) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_bad_final_conversion;
     return;
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -505,6 +505,8 @@
     if (!LSI->ReturnType->isDependentType() &&
         !LSI->ReturnType->isVoidType()) {
       if (RequireCompleteType(CallOperator->getBeginLoc(), LSI->ReturnType,
+                              // Lambdas can return sizeless types.
+                              CompleteTypeKind::AcceptSizeless,
                               diag::err_lambda_incomplete_result)) {
         // Do nothing.
       }
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -6194,6 +6194,8 @@
     for (unsigned I = 1, N = Constructor->getNumParams(); I != N; ++I) {
       ParmVarDecl *Parm = Constructor->getParamDecl(I);
       if (S.RequireCompleteType(Loc, Parm->getType(),
+                                // Function arguments can have sizeless type.
+                                Sema::CompleteTypeKind::AcceptSizeless,
                                 diag::err_call_incomplete_argument))
         break;
 
@@ -8834,10 +8836,13 @@
 
     case OR_No_Viable_Function: {
       auto Cands = FailedCandidateSet.CompleteCandidates(S, OCD_AllCandidates, Args);
-      if (!S.RequireCompleteType(Kind.getLocation(),
-                                 DestType.getNonReferenceType(),
-                          diag::err_typecheck_nonviable_condition_incomplete,
-                               OnlyArg->getType(), Args[0]->getSourceRange()))
+      // Sizeless objects can be initialized, so sizelessness itself
+      // isn't the problem.  Prefer the more detailed diagnostic below.
+      if (!S.RequireCompleteType(
+              Kind.getLocation(), DestType.getNonReferenceType(),
+              Sema::CompleteTypeKind::AcceptSizeless,
+              diag::err_typecheck_nonviable_condition_incomplete,
+              OnlyArg->getType(), Args[0]->getSourceRange()))
         S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
           << (Entity.getKind() == InitializedEntity::EK_Result)
           << OnlyArg->getType() << Args[0]->getSourceRange()
Index: clang/lib/Sema/SemaExprObjC.cpp
===================================================================
--- clang/lib/Sema/SemaExprObjC.cpp
+++ clang/lib/Sema/SemaExprObjC.cpp
@@ -1079,7 +1079,11 @@
   else {
     if (!EncodedType->getAsArrayTypeUnsafe() && //// Incomplete array is handled.
         !EncodedType->isVoidType()) // void is handled too.
+      // Leave later messages to complain about sizeless types that
+      // can't be @encoded.  Sizelessness itself doesn't really prevent
+      // the use of @encode.
       if (RequireCompleteType(AtLoc, EncodedType,
+                              CompleteTypeKind::AcceptSizeless,
                               diag::err_incomplete_type_objc_at_encode,
                               EncodedTypeInfo->getTypeLoc()))
         return ExprError();
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -950,7 +950,8 @@
     isPointer = true;
   }
   if (!isPointer || !Ty->isVoidType()) {
-    if (RequireCompleteType(ThrowLoc, Ty,
+    // See below for the handling of sizeless types.
+    if (RequireCompleteType(ThrowLoc, Ty, CompleteTypeKind::AcceptSizeless,
                             isPointer ? diag::err_throw_incomplete_ptr
                                       : diag::err_throw_incomplete,
                             E->getSourceRange()))
@@ -1480,6 +1481,9 @@
   //   prvalue of the specified type that performs no initialization.
   if (!Ty->isVoidType() &&
       RequireCompleteType(TyBeginLoc, ElemTy,
+                          // Local sizeless objects can be initialized in the
+                          // normal way.
+                          CompleteTypeKind::AcceptSizeless,
                           diag::err_invalid_incomplete_type_use, FullRange))
     return ExprError();
 
@@ -4635,7 +4639,8 @@
       return true;
 
     return !S.RequireCompleteType(
-        Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
+        Loc, ArgTy, Sema::CompleteTypeKind::AcceptSizeless,
+        diag::err_incomplete_type_used_in_type_trait_expr);
   }
 }
 
@@ -5116,8 +5121,9 @@
       if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
         continue;
 
-      if (S.RequireCompleteType(KWLoc, ArgTy,
-          diag::err_incomplete_type_used_in_type_trait_expr))
+      if (S.RequireCompleteType(
+              KWLoc, ArgTy, Sema::CompleteTypeKind::AcceptSizeless,
+              diag::err_incomplete_type_used_in_type_trait_expr))
         return false;
     }
 
@@ -5340,7 +5346,9 @@
       return LhsT->isVoidType();
 
     // A function definition requires a complete, non-abstract return type.
-    if (!Self.isCompleteType(KeyLoc, RhsT) || Self.isAbstractType(KeyLoc, RhsT))
+    if (!Self.isCompleteType(KeyLoc, RhsT,
+                             Sema::CompleteTypeKind::AcceptSizeless) ||
+        Self.isAbstractType(KeyLoc, RhsT))
       return false;
 
     // Compute the result of add_rvalue_reference.
@@ -5384,12 +5392,14 @@
     //   For both, T and U shall be complete types, (possibly cv-qualified)
     //   void, or arrays of unknown bound.
     if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
-        Self.RequireCompleteType(KeyLoc, LhsT,
-          diag::err_incomplete_type_used_in_type_trait_expr))
+        Self.RequireCompleteType(
+            KeyLoc, LhsT, Sema::CompleteTypeKind::AcceptSizeless,
+            diag::err_incomplete_type_used_in_type_trait_expr))
       return false;
     if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
-        Self.RequireCompleteType(KeyLoc, RhsT,
-          diag::err_incomplete_type_used_in_type_trait_expr))
+        Self.RequireCompleteType(
+            KeyLoc, RhsT, Sema::CompleteTypeKind::AcceptSizeless,
+            diag::err_incomplete_type_used_in_type_trait_expr))
       return false;
 
     // cv void is never assignable.
@@ -7793,6 +7803,8 @@
 
   if (!E->getType()->isVoidType())
     RequireCompleteType(E->getExprLoc(), E->getType(),
+                        // Ignored results can have sizeless type.
+                        CompleteTypeKind::AcceptSizeless,
                         diag::err_incomplete_type);
   return E;
 }
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -973,6 +973,8 @@
 
   if (!getLangOpts().CPlusPlus &&
       RequireCompleteType(E->getExprLoc(), E->getType(),
+                          // Function arguments can have sizeless type.
+                          CompleteTypeKind::AcceptSizeless,
                           diag::err_call_incomplete_argument))
     return ExprError();
 
@@ -5281,6 +5283,8 @@
       Arg = Args[ArgIx++];
 
       if (RequireCompleteType(Arg->getBeginLoc(), ProtoArgType,
+                              // Function arguments can have sizeless type.
+                              CompleteTypeKind::AcceptSizeless,
                               diag::err_call_incomplete_argument, Arg))
         return true;
 
@@ -6120,6 +6124,8 @@
       }
 
       if (RequireCompleteType(Arg->getBeginLoc(), Arg->getType(),
+                              // Function arguments can have sizeless type.
+                              CompleteTypeKind::AcceptSizeless,
                               diag::err_call_incomplete_argument, Arg))
         return ExprError();
 
@@ -12234,6 +12240,9 @@
       return QualType();
     if (!RHS.get()->getType()->isVoidType())
       S.RequireCompleteType(Loc, RHS.get()->getType(),
+                            // Expressions of sizeless type are allowed
+                            // on either side of ",".
+                            Sema::CompleteTypeKind::AcceptSizeless,
                             diag::err_incomplete_type);
   }
 
@@ -14664,6 +14673,10 @@
 
   if (!TInfo->getType()->isDependentType()) {
     if (RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), TInfo->getType(),
+                            // Function arguments can have sizeless type and
+                            // sizelessness doesn't prevent them from being
+                            // passed through "...".
+                            CompleteTypeKind::AcceptSizeless,
                             diag::err_second_parameter_to_va_arg_incomplete,
                             TInfo->getTypeLoc()))
       return ExprError();
Index: clang/lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- clang/lib/Sema/SemaExceptionSpec.cpp
+++ clang/lib/Sema/SemaExceptionSpec.cpp
@@ -164,7 +164,10 @@
   }
   if (!(PointeeT->isRecordType() &&
         PointeeT->castAs<RecordType>()->isBeingDefined()) &&
-      RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range))
+      RequireCompleteType(Range.getBegin(), PointeeT,
+                          // See below for the handling of sizeless types.
+                          CompleteTypeKind::AcceptSizeless, DiagID, Kind,
+                          Range))
     return ReturnValueOnError;
 
   // The MSVC compatibility mode doesn't extend to sizeless types,
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -250,6 +250,8 @@
 Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg,
                               SourceLocation EqualLoc) {
   if (RequireCompleteType(Param->getLocation(), Param->getType(),
+                          // Parameters can have sizeless type.
+                          CompleteTypeKind::AcceptSizeless,
                           diag::err_typecheck_decl_incomplete_type)) {
     Param->setInvalidDecl();
     return true;
@@ -15561,7 +15563,9 @@
     DK = diag::err_catch_incomplete_ref;
   }
   if (!Invalid && (Mode == 0 || !BaseType->isVoidType()) &&
-      !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK))
+      !BaseType->isDependentType() &&
+      // See below for the handling of sizeless types.
+      RequireCompleteType(Loc, BaseType, CompleteTypeKind::AcceptSizeless, DK))
     Invalid = true;
 
   if (!Invalid && Mode != 1 && BaseType->isSizelessType()) {
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11854,6 +11854,9 @@
     if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType))
       BaseDeclType = Array->getElementType();
     if (RequireCompleteType(VDecl->getLocation(), BaseDeclType,
+                            // Local variables can have sizeless type.
+                            // We diagnose invalid sizeless decls later.
+                            CompleteTypeKind::AcceptSizeless,
                             diag::err_typecheck_decl_incomplete_type)) {
       RealDecl->setInvalidDecl();
       return;
@@ -12254,8 +12257,10 @@
   if (Ty->isDependentType()) return;
 
   // Require a complete type.
-  if (RequireCompleteType(VD->getLocation(),
-                          Context.getBaseElementType(Ty),
+  if (RequireCompleteType(VD->getLocation(), Context.getBaseElementType(Ty),
+                          // Sizeless variables can be initialized,
+                          // so sizelessness itself isn't the problem.
+                          CompleteTypeKind::AcceptSizeless,
                           diag::err_typecheck_decl_incomplete_type)) {
     VD->setInvalidDecl();
     return;
@@ -12441,6 +12446,9 @@
     if (!Var->hasAttr<AliasAttr>()) {
       if (RequireCompleteType(Var->getLocation(),
                               Context.getBaseElementType(Type),
+                              // Local variables can have sizeless type.
+                              // We diagnose invalid sizeless decls later.
+                              CompleteTypeKind::AcceptSizeless,
                               diag::err_typecheck_decl_incomplete_type)) {
         Var->setInvalidDecl();
         return;
@@ -13822,6 +13830,8 @@
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
       !FD->isInvalidDecl() &&
       RequireCompleteType(FD->getLocation(), ResultType,
+                          // Functions can return sizeless types by value.
+                          CompleteTypeKind::AcceptSizeless,
                           diag::err_func_def_incomplete_result))
     FD->setInvalidDecl();
 
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -12848,6 +12848,8 @@
     // This is also C++ [dcl.fct]p6.
     if (!Param->isInvalidDecl() &&
         RequireCompleteType(Param->getLocation(), Param->getType(),
+                            // Function parameters can have sizeless type.
+                            CompleteTypeKind::AcceptSizeless,
                             diag::err_typecheck_decl_incomplete_type)) {
       Param->setInvalidDecl();
       HasInvalidParm = true;
Index: clang/lib/Sema/SemaCast.cpp
===================================================================
--- clang/lib/Sema/SemaCast.cpp
+++ clang/lib/Sema/SemaCast.cpp
@@ -2646,7 +2646,10 @@
   if (SrcExpr.isInvalid())
     return;
 
+  // Being sizeless doesn't in itself prevent casting, so diagnose invalid
+  // cases below instead.
   if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
+                               Sema::CompleteTypeKind::AcceptSizeless,
                                diag::err_typecheck_cast_to_incomplete)) {
     SrcExpr = ExprError();
     return;
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1788,11 +1788,7 @@
 
     /// Relax the normal rules for complete types so that they include
     /// sizeless built-in types.
-    AcceptSizeless,
-
-    // FIXME: Eventually we should flip the default to Normal and opt in
-    // to AcceptSizeless rather than opt out of it.
-    Default = AcceptSizeless
+    AcceptSizeless
   };
 
 private:
@@ -1900,7 +1896,7 @@
   bool isUsualDeallocationFunction(const CXXMethodDecl *FD);
 
   bool isCompleteType(SourceLocation Loc, QualType T,
-                      CompleteTypeKind Kind = CompleteTypeKind::Default) {
+                      CompleteTypeKind Kind = CompleteTypeKind::Normal) {
     return !RequireCompleteTypeImpl(Loc, T, Kind, nullptr);
   }
   bool RequireCompleteType(SourceLocation Loc, QualType T,
@@ -1910,10 +1906,10 @@
 
   bool RequireCompleteType(SourceLocation Loc, QualType T,
                            TypeDiagnoser &Diagnoser) {
-    return RequireCompleteType(Loc, T, CompleteTypeKind::Default, Diagnoser);
+    return RequireCompleteType(Loc, T, CompleteTypeKind::Normal, Diagnoser);
   }
   bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID) {
-    return RequireCompleteType(Loc, T, CompleteTypeKind::Default, DiagID);
+    return RequireCompleteType(Loc, T, CompleteTypeKind::Normal, DiagID);
   }
 
   template <typename... Ts>
@@ -1922,6 +1918,13 @@
     BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
     return RequireCompleteType(Loc, T, Diagnoser);
   }
+  template <typename... Ts>
+  bool RequireCompleteType(SourceLocation Loc, QualType T,
+                           CompleteTypeKind Kind, unsigned DiagID,
+                           const Ts &... Args) {
+    BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
+    return RequireCompleteType(Loc, T, Kind, Diagnoser);
+  }
 
   template <typename... Ts>
   bool RequireCompleteSizedType(SourceLocation Loc, QualType T, unsigned DiagID,
@@ -1935,10 +1938,16 @@
                                TypeDiagnoser &Diagnoser);
   bool RequireCompleteExprType(Expr *E, unsigned DiagID);
 
+  template <typename... Ts>
+  bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, unsigned DiagID,
+                               const Ts &... Args) {
+    BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
+    return RequireCompleteExprType(E, Kind, Diagnoser);
+  }
   template <typename... Ts>
   bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) {
     BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...);
-    return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser);
+    return RequireCompleteExprType(E, CompleteTypeKind::Normal, Diagnoser);
   }
 
   template <typename... Ts>
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to