Repository: llvm/llvm-project
File: clang/lib/Sema/SemaTemplate.cpp (C++)

Code before:
      for (llvm::APSInt I(NumArgs.getBitWidth(), NumArgs.isUnsigned());
           I < NumArgs; ++I) {
        TemplateArgument TA(Context, I, OrigType);
        SyntheticTemplateArgs.addArgument(SemaRef.getTrivialTemplateArgumentLoc(
            TA, OrigType, TemplateArgs[2].getLocation()));
      }
    } else {
      // C++14 [inteseq.make]p1:
      //   If N is negative the program is ill-formed.
      SemaRef.Diag(TemplateArgs[2].getLocation(),
                   diag::err_integer_sequence_negative_length);
      return QualType();
    }

    // The first template argument will be reused as the template decl that
    // our synthetic template arguments will be applied to.
    return SemaRef.CheckTemplateIdType(Keyword, Converted[0].getAsTemplate(),
                                       TemplateLoc, SyntheticTemplateArgs,
                                       /*Scope=*/nullptr,
                                       /*ForNestedNameSpecifier=*/false);
  }

  case BTK__type_pack_element: {
    assert(Converted.size() == 2 &&
           "__type_pack_element should be given an index and a parameter pack");
    if (Converted[0].isDependent() || Converted[1].isDependent())
      return QualType();

    TemplateArgument IndexArg = Converted[0], Ts = Converted[1];

    llvm::APSInt Index = IndexArg.getAsIntegral();
    assert(Index >= 0 && "the index used with __type_pack_element should be of "
                         "type std::size_t, and hence be non-negative");
    // If the Index is out of bounds, the program is ill-formed.
    if (Index >= Ts.pack_size()) {
      SemaRef.Diag(TemplateArgs[0].getLocation(),
                   diag::err_type_pack_element_out_of_bounds);
      return QualType();
    }

    // We simply return the type at index `Index`.
    int64_t N = Index.getExtValue();
    return Ts.getPackAsArray()[N].getAsType();
  }

  case BTK__builtin_common_type: {
    assert(Converted.size() == 4);
    if (Converted[3].isDependent())
      return QualType();

    TemplateName BaseTemplate = Converted[0].getAsTemplate();

Review comment (suggestion):
I think these lifted dependence checks are due to removing the attempt to do the checks universally prior to the switch, so they should just be reverted.

Code after:
           I < NumArgs; ++I) {
        TemplateArgument TA(Context, I, OrigType);
        SyntheticTemplateArgs.addArgument(SemaRef.getTrivialTemplateArgumentLoc(
            TA, OrigType, TemplateArgs[2].getLocation()));
      }
    } else {
      // C++14 [inteseq.make]p1:
      //   If N is negative the program is ill-formed.
      SemaRef.Diag(TemplateArgs[2].getLocation(),
                   diag::err_integer_sequence_negative_length);
      return QualType();
    }

    // The first template argument will be reused as the template decl that
    // our synthetic template arguments will be applied to.
    return SemaRef.CheckTemplateIdType(Keyword, Converted[0].getAsTemplate(),
                                       TemplateLoc, SyntheticTemplateArgs,
                                       /*Scope=*/nullptr,
                                       /*ForNestedNameSpecifier=*/false);
  }

  case BTK__type_pack_element: {
    // Specializations of
    //    __type_pack_element<Index, T_1, ..., T_N>
    // are treated like T_Index.
    assert(Converted.size() == 2 &&
           "__type_pack_element should be given an index and a parameter pack");

    TemplateArgument IndexArg = Converted[0], Ts = Converted[1];
    if (IndexArg.isDependent() || Ts.isDependent())
      return QualType();

    llvm::APSInt Index = IndexArg.getAsIntegral();
    assert(Index >= 0 && "the index used with __type_pack_element should be of "
                         "type std::size_t, and hence be non-negative");
    // If the Index is out of bounds, the program is ill-formed.
    if (Index >= Ts.pack_size()) {
      SemaRef.Diag(TemplateArgs[0].getLocation(),
                   diag::err_type_pack_element_out_of_bounds);
      return QualType();
    }

    // We simply return the type at index `Index`.
    int64_t N = Index.getExtValue();
    return Ts.getPackAsArray()[N].getAsType();
  }

  case BTK__builtin_common_type: {
    assert(Converted.size() == 4);
    if (llvm::any_of(Converted, [](auto &C) { return C.isDependent(); }))
      return QualType();