Skip to content

Commit

Permalink
[Sema] Fix __array_rank queried type at template instantiation
Browse files Browse the repository at this point in the history
The type being queried was left as a template type parameter, making
the whole expression as dependent and thus not eligible to
static_assert.
  • Loading branch information
v01dxyz committed Jan 26, 2025
1 parent 8035d38 commit 8283e34
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
4 changes: 2 additions & 2 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -2847,8 +2847,8 @@ class TypeTraitExpr final
///
/// Example:
/// \code
/// __array_rank(int[10][20]) == 2
/// __array_extent(int, 1) == 20
/// __array_rank(int[10][20]) == 2
/// __array_extent(int[10][20], 1) == 20
/// \endcode
class ArrayTypeTraitExpr : public Expr {
/// The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
Expand Down
3 changes: 0 additions & 3 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -14947,9 +14947,6 @@ TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
if (SubExpr.isInvalid())
return ExprError();

if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
return E;
}

return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
Expand Down
37 changes: 37 additions & 0 deletions clang/test/SemaCXX/array-type-trait-with-template.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: %clang_cc1 -fsyntax-only %s

// When __array_rank is used with a template type parameter, this
// test ensures clang considers the final expression as having an
// integral type.
//
// Although array_extent was handled well, it is added here.
template <typename T, int N>
constexpr int array_rank(T (&lhs)[N]) {
return __array_rank(T[N]);
}

template <int I, typename T, int N>
constexpr int array_extent(T (&lhs)[N]) {
return __array_extent(T[N], I);
}

int main() {
constexpr int vec[] = {0, 1, 2, 1};
constexpr int mat[4][4] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};

(void) (array_rank(vec) == 1);
(void) (array_rank(vec) == 2);

static_assert(array_rank(vec) == 1);
static_assert(array_rank(mat) == 2);

static_assert(array_extent<0>(vec) == 4);
static_assert(array_extent<0>(mat) == 4);
static_assert(array_extent<1>(mat) == 4);
static_assert(array_extent<1>(vec) == 0);
}

0 comments on commit 8283e34

Please sign in to comment.