diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp index ef579bc5d8972..0fc93c14131e6 100644 --- a/clang/lib/AST/Interp/Compiler.cpp +++ b/clang/lib/AST/Interp/Compiler.cpp @@ -1698,10 +1698,8 @@ bool Compiler::VisitUnaryExprOrTypeTraitExpr( if (Kind == UETT_VectorElements) { if (const auto *VT = E->getTypeOfArgument()->getAs()) return this->emitConst(VT->getNumElements(), E); - - // FIXME: Apparently we need to catch the fact that a sizeless vector type - // has been passed and diagnose that (at run time). assert(E->getTypeOfArgument()->isSizelessVectorType()); + return this->emitSizelessVectorElementSize(E); } if (Kind == UETT_VecStep) { diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index f86b787fb034e..ff2748f91adfe 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -2735,6 +2735,15 @@ inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC, return CheckDeclRef(S, OpPC, DR); } +inline bool SizelessVectorElementSize(InterpState &S, CodePtr OpPC) { + if (S.inConstantContext()) { + const SourceRange &ArgRange = S.Current->getRange(OpPC); + const Expr *E = S.Current->getExpr(OpPC); + S.CCEDiag(E, diag::note_constexpr_non_const_vectorelements) << ArgRange; + } + return false; +} + inline bool Assume(InterpState &S, CodePtr OpPC) { const auto Val = S.Stk.pop(); diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 49ebb156ab2fb..9f29fa9272711 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -733,6 +733,8 @@ def InvalidDeclRef : Opcode { let Args = [ArgDeclRef]; } +def SizelessVectorElementSize : Opcode; + def Assume : Opcode; def ArrayDecay : Opcode; diff --git a/clang/test/SemaCXX/builtin_vectorelements.cpp b/clang/test/SemaCXX/builtin_vectorelements.cpp index 59ff09ac72e42..b23675ea0ac6a 100644 --- a/clang/test/SemaCXX/builtin_vectorelements.cpp +++ b/clang/test/SemaCXX/builtin_vectorelements.cpp @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -triple x86_64 -std=c++20 -fsyntax-only -verify -disable-llvm-passes %s +// RUN: %clang_cc1 -triple x86_64 -std=c++20 -fsyntax-only -verify -disable-llvm-passes -fexperimental-new-constant-interpreter %s // REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -triple aarch64 -target-feature +sve -std=c++20 -fsyntax-only -verify -disable-llvm-passes %s +// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -std=c++20 -fsyntax-only -verify -disable-llvm-passes -fexperimental-new-constant-interpreter %s template using VecT __attribute__((vector_size(16))) = T;