================ @@ -8374,20 +8376,191 @@ static void HandlePtrAuthQualifier(ASTContext &Ctx, QualType &T, IsInvalid |= !S.checkPointerAuthDiscriminatorArg( ExtraDiscriminatorArg, Sema::PADAK_ExtraDiscPtrAuth, ExtraDiscriminator); - if (IsInvalid) { - Attr.setInvalid(); - return; + std::optional<PointerAuthenticationMode> AuthenticationMode = std::nullopt; + SourceRange AuthenticationModeRange; + + if (AuthenticationOptionsArg && !AuthenticationOptionsArg->containsErrors() ) { + std::string OptionsString; + bool IsInitialized = false; + const StringLiteral *OptionsStringLiteral = dyn_cast<StringLiteral>(AuthenticationOptionsArg); + auto ReportEvaluationOfExpressionIfNeeded = [&](){ + if (OptionsStringLiteral || !IsInitialized) + return; + S.Diag(AuthenticationOptionsArg->getBeginLoc(), + diag::note_ptrauth_evaluating_options) << OptionsString << AuthenticationOptionsArg->getSourceRange(); + }; + auto DiagnoseInvalidOptionsParameter = [&](llvm::StringRef Reason, std::optional<char> InvalidCh, auto Location) { + S.Diag(AuthenticationOptionsArg->getExprLoc(), + diag::err_ptrauth_invalid_option) + << AttrName << Reason << Location << !!InvalidCh << (InvalidCh ? *InvalidCh : '\0'); + Attr.setInvalid(); + ReportEvaluationOfExpressionIfNeeded(); + }; + if (AuthenticationOptionsArg->isValueDependent() || AuthenticationOptionsArg->isTypeDependent()) { + DiagnoseInvalidOptionsParameter("is dependent", std::nullopt, AuthenticationOptionsArg->getSourceRange()); + return; + } + if (OptionsStringLiteral) { + if (OptionsStringLiteral->containsNonAsciiOrNull()) { + DiagnoseInvalidOptionsParameter("contains invalid characters", std::nullopt, AuthenticationOptionsArg->getSourceRange()); + return; + } + OptionsString = OptionsStringLiteral->getString(); + } else if (S.EvaluateAsString(AuthenticationOptionsArg, OptionsString, S.Context, Sema::StringEvaluationContext::PtrauthOptions, /*ErrorOnInvalidMessage=*/false)) { + for (char Ch : OptionsString) { + if (!Ch || !isascii(Ch)) { + DiagnoseInvalidOptionsParameter("contains invalid characters", Ch, AuthenticationOptionsArg->getSourceRange()); + return; + } + } + } else { + Attr.setInvalid(); + return; + } + IsInitialized = true; + bool HasSeenOption = false; + unsigned CurrentIdx = 0; + + auto OptionStringIdxLocation = [&](unsigned Idx) { ---------------- ojhunt wrote:
This code is moderately concise parser of the grammar: option :- [a-z\-]+ options :- option (',' option)* The reason for the complexity - vs. just a split(',').map(trim) - is just error messaging. We could simplify if people think it's warranted, but the error message tests are already reduced from what it could be. https://github.com/llvm/llvm-project/pull/136828 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits