================
@@ -8374,20 +8376,212 @@ 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;
+        }
+      }
----------------
ojhunt wrote:

@cor3ntin re: string_view: I'm trying not to add anything beyond the bare 
minimum here, I thought the existing behavior of EvaluateString is a superset 
of what we know existing code requires so I didn't want to trying to add more 
complexity to a pile of already complex PRs, that said it looks like I haven't 
pulled those specific tests across so I could be wrong.

Re: non-ascii: I'm not sure I understand the semantics of 
StringLiteral::toString and EvaluateString(...) if presented w.r.t utf8 or wide 
chars so I wanted consistent behavior between them, and the easiest way to 
ensure that was an early out on non-ascii. StringLiteral::getString() 
specifically has an assertion specifically about expecting char sized 
characters which was worrying to me. If that assertion is actually trying to 
say sizeof(string code point)==sizeof(char) then that's much simpler.

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