aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 8798851..bce941c 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -183,6 +183,33 @@ bool Sema::checkArgCount(CallExpr *Call, unsigned DesiredArgCount) {
<< /*is non object*/ 0 << Call->getArg(1)->getSourceRange();
}
+static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S) {
+ bool HasError = false;
+
+ for (unsigned I = 0; I < Call->getNumArgs(); ++I) {
+ Expr *Arg = Call->getArg(I);
+
+ if (Arg->isValueDependent())
+ continue;
+
+ std::optional<std::string> ArgString = Arg->tryEvaluateString(S.Context);
+ int DiagMsgKind = -1;
+ // Arguments must be pointers to constant strings and cannot use '$'.
+ if (!ArgString.has_value())
+ DiagMsgKind = 0;
+ else if (ArgString->find('$') != std::string::npos)
+ DiagMsgKind = 1;
+
+ if (DiagMsgKind >= 0) {
+ S.Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
+ << DiagMsgKind << Arg->getSourceRange();
+ HasError = true;
+ }
+ }
+
+ return !HasError;
+}
+
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty) {
if (Value->isTypeDependent())
return false;
@@ -3351,6 +3378,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
case Builtin::BI__builtin_matrix_column_major_store:
return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
+ case Builtin::BI__builtin_verbose_trap:
+ if (!checkBuiltinVerboseTrap(TheCall, *this))
+ return ExprError();
+ break;
+
case Builtin::BI__builtin_get_device_side_mangled_name: {
auto Check = [](CallExpr *TheCall) {
if (TheCall->getNumArgs() != 1)