https://github.com/v01dXYZ created https://github.com/llvm/llvm-project/pull/124491
The type being queried was left as a template type parameter, making the whole expression as dependent and thus not eligible to static_assert. Fixes #123498 >From 8283e34bb0144604e52196e0a69a56355eb51e43 Mon Sep 17 00:00:00 2001 From: v01dxyz <v01d...@v01d.xyz> Date: Sun, 26 Jan 2025 23:07:13 +0100 Subject: [PATCH] [Sema] Fix __array_rank queried type at template instantiation The type being queried was left as a template type parameter, making the whole expression as dependent and thus not eligible to static_assert. --- clang/include/clang/AST/ExprCXX.h | 4 +- clang/lib/Sema/TreeTransform.h | 3 -- .../array-type-trait-with-template.cpp | 37 +++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 clang/test/SemaCXX/array-type-trait-with-template.cpp diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index aa10945addf78f..2a130bc6da79a0 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -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. diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 12680843a434a0..f04adf7fdf8ad2 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -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, diff --git a/clang/test/SemaCXX/array-type-trait-with-template.cpp b/clang/test/SemaCXX/array-type-trait-with-template.cpp new file mode 100644 index 00000000000000..b0cc9a12d6efb6 --- /dev/null +++ b/clang/test/SemaCXX/array-type-trait-with-template.cpp @@ -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); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits