================
@@ -8479,10 +8480,131 @@ static void HandlePtrAuthQualifier(ASTContext &Ctx,
QualType &T,
IsAddressDiscriminated);
IsInvalid |= !S.checkPointerAuthDiscriminatorArg(
ExtraDiscriminatorArg, PointerAuthDiscArgKind::Extra,
ExtraDiscriminator);
+ std::string LastAuthenticationMode;
+ std::optional<PointerAuthenticationMode> AuthenticationMode = std::nullopt;
+ bool IsIsaPointer = false;
+ bool AuthenticatesNullValues = false;
+
+ if (AuthenticationOptionsArg && !AuthenticationOptionsArg->containsErrors())
{
+ StringRef OptionsString;
+ std::string EvaluatedString;
+ bool HasEvaluatedOptionsString = false;
+ const StringLiteral *OptionsStringLiteral =
+ dyn_cast<StringLiteral>(AuthenticationOptionsArg);
+ SourceRange AuthenticationOptionsRange =
+ AuthenticationOptionsArg->getSourceRange();
+ bool ReportedEvaluation = false;
+ auto ReportEvaluationOfExpressionIfNeeded = [&]() {
+ if (OptionsStringLiteral || !HasEvaluatedOptionsString ||
+ ReportedEvaluation)
+ return;
+ ReportedEvaluation = true;
+ S.Diag(AuthenticationOptionsRange.getBegin(),
+ diag::note_ptrauth_evaluating_options)
+ << OptionsString << AuthenticationOptionsRange;
+ };
+ auto DiagnoseInvalidOptionsParameter = [&](llvm::StringRef Reason) {
+ S.Diag(AuthenticationOptionsRange.getBegin(),
+ diag::err_ptrauth_invalid_option)
+ << Reason;
+ Attr.setInvalid();
+ IsInvalid = true;
+ ReportEvaluationOfExpressionIfNeeded();
+ };
+ if (AuthenticationOptionsArg->isValueDependent() ||
+ AuthenticationOptionsArg->isTypeDependent()) {
+ DiagnoseInvalidOptionsParameter("is dependent");
+ return;
+ }
+ if (OptionsStringLiteral) {
+ OptionsString = OptionsStringLiteral->getString();
+ HasEvaluatedOptionsString = true;
+ } else {
+ Expr::EvalResult Eval;
+ bool Result = AuthenticationOptionsArg->EvaluateAsRValue(Eval, Ctx);
+ if (Result && Eval.Val.isLValue()) {
+ auto *BaseExpr = Eval.Val.getLValueBase().dyn_cast<const Expr *>();
+ const StringLiteral *EvaluatedStringLiteral =
+ dyn_cast<StringLiteral>(const_cast<Expr *>(BaseExpr));
+ if (EvaluatedStringLiteral) {
+ CharUnits StartOffset = Eval.Val.getLValueOffset();
+ EvaluatedString = EvaluatedStringLiteral->getString().drop_front(
+ StartOffset.getQuantity());
+ OptionsString = EvaluatedString;
+ HasEvaluatedOptionsString = true;
+ }
+ }
+ }
+ if (!HasEvaluatedOptionsString) {
+ DiagnoseInvalidOptionsParameter(
+ "must be a string of comma separated flags");
+ return;
+ }
+ for (char Ch : OptionsString) {
+ if (Ch != '-' && Ch != ',' && !isWhitespace(Ch) && !isalpha(Ch)) {
+ DiagnoseInvalidOptionsParameter("contains invalid characters");
+ return;
+ }
+ }
+ HasEvaluatedOptionsString = true;
+ OptionsString = OptionsString.trim();
+ llvm::SmallVector<StringRef> Options;
+ if (!OptionsString.empty())
+ OptionsString.split(Options, ',');
+
+ for (unsigned Idx = 0; Idx < Options.size(); ++Idx) {
+ StringRef OptionString = Options[Idx].trim();
+ auto HandleOption = [&](auto Value, auto *Option,
+ std::string *LastOption = nullptr) {
+ if (!*Option) {
+ *Option = Value;
+ if (LastOption)
+ *LastOption = OptionString;
+ return true;
+ }
+ bool IsAuthenticationMode =
+ std::is_same_v<decltype(Value), PointerAuthenticationMode>;
+ S.Diag(AuthenticationOptionsRange.getBegin(),
+ diag::err_ptrauth_repeated_authentication_option)
+ << !IsAuthenticationMode << OptionString
+ << (LastOption ? *LastOption : "");
+ return false;
+ };
- if (IsInvalid) {
- Attr.setInvalid();
- return;
+ if (OptionString.empty()) {
+ bool IsLastOption = Idx == (Options.size() - 1);
+ DiagnoseInvalidOptionsParameter(
+ IsLastOption ? "has a trailing comma" : "contains an empty
option");
+ continue;
+ }
+ std::optional<PointerAuthenticationOption> Option =
+ PointerAuthenticationOption::from(OptionString);
+ if (!Option) {
+ auto TrailingOption = OptionString.drop_until(isWhitespace).trim();
----------------
cor3ntin wrote:
In which scenario is this useful? We already trimmed above
https://github.com/llvm/llvm-project/pull/136828
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits