From fed8695bb846bf99884c1b54863d58b369c2b340 Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Wed, 9 Oct 2024 09:56:37 +0200 Subject: [PATCH] [clang][bytecode] Emit better diagnostic for invalid shufflevector index (#111643) --- clang/lib/AST/ByteCode/Compiler.cpp | 3 ++- clang/lib/AST/ByteCode/Interp.cpp | 9 +++++++++ clang/lib/AST/ByteCode/Interp.h | 1 + clang/lib/AST/ByteCode/Opcodes.td | 3 +++ clang/test/AST/ByteCode/builtin-functions.cpp | 2 +- 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index e1326bba37269..f270de1054c61 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -3586,8 +3586,9 @@ bool Compiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) { } for (unsigned I = 0; I != NumOutputElems; ++I) { APSInt ShuffleIndex = E->getShuffleMaskIdx(Ctx.getASTContext(), I); + assert(ShuffleIndex >= -1); if (ShuffleIndex == -1) - return this->emitInvalid(E); // FIXME: Better diagnostic. + return this->emitInvalidShuffleVectorIndex(I, E); assert(ShuffleIndex < (NumInputElems * 2)); if (!this->emitGetLocal(PT_Ptr, diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index b3ba81f04ff1f..050de67c2e77d 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -21,6 +21,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/Basic/DiagnosticSema.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/StringExtras.h" #include @@ -1406,6 +1407,14 @@ bool handleFixedPointOverflow(InterpState &S, CodePtr OpPC, return S.noteUndefinedBehavior(); } +bool InvalidShuffleVectorIndex(InterpState &S, CodePtr OpPC, uint32_t Index) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, + diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr) + << Index; + return false; +} + // https://github.com/llvm/llvm-project/issues/102513 #if defined(_WIN32) && !defined(__clang__) && !defined(NDEBUG) #pragma optimize("", off) diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 5c3ee5e689f1c..2c5538d221bf0 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -161,6 +161,7 @@ bool CallBI(InterpState &S, CodePtr OpPC, const Function *Func, bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize, const CallExpr *CE); bool CheckLiteralType(InterpState &S, CodePtr OpPC, const Type *T); +bool InvalidShuffleVectorIndex(InterpState &S, CodePtr OpPC, uint32_t Index); template static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue) { diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 61b6f2e8daa2f..7b65138e5a3c9 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -773,6 +773,9 @@ def InvalidDeclRef : Opcode { } def SizelessVectorElementSize : Opcode; +def InvalidShuffleVectorIndex : Opcode { + let Args = [ArgUint32]; +} def Assume : Opcode; diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index 18ccee382d44e..450ff5671314d 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -956,7 +956,7 @@ namespace shufflevector { static_assert(vectorShuffle6[7] == 7, ""); constexpr vector4char vectorShuffleFail1 = __builtin_shufflevector( // both-error {{must be initialized by a constant expression}}\ - // ref-error {{index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position 0 is not permitted in a constexpr context}} + // both-error {{index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position 0 is not permitted in a constexpr context}} vector4charConst1, vector4charConst2, -1, -1, -1, -1); }