================
@@ -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

Reply via email to