================
@@ -8631,17 +8632,162 @@ static void HandleNeonVectorTypeAttr(QualType 
&CurType, const ParsedAttr &Attr,
   CurType = S.Context.getVectorType(CurType, numElts, VecKind);
 }
 
+struct PointerAuthQualifierOptions {
+  PointerAuthenticationMode AuthenticationMode =
+      PointerAuthenticationMode::SignAndAuth;
+  bool IsIsaPointer = false;
+  bool AuthenticatesNullValues = false;
+};
+
+static bool
+checkPointerAuthQualiferOptions(Sema &S, Expr *OptionsExpr,
+                                PointerAuthQualifierOptions &Result) {
+  if (!OptionsExpr)
+    return true;
+  if (OptionsExpr->containsErrors())
+    return false;
+
+  if (OptionsExpr->isValueDependent() || OptionsExpr->isTypeDependent()) {
+    S.Diag(OptionsExpr->getExprLoc(),
+           diag::err_ptrauth_dependent_options_string)
+        << OptionsExpr->getSourceRange();
+    return false;
+  }
+
+  ASTContext &Ctx = S.getASTContext();
+  std::string EvaluatedOptionsBuffer;
+  StringRef OptionsString;
+  const StringLiteral *OptionsLiteral = dyn_cast<StringLiteral>(OptionsExpr);
+  if (OptionsLiteral)
+    OptionsString = OptionsLiteral->getString();
+  else if (auto EvaluatedString = OptionsExpr->tryEvaluateString(Ctx)) {
+    EvaluatedString->swap(EvaluatedOptionsBuffer);
+    OptionsString = EvaluatedOptionsBuffer;
+  } else if (!S.EvaluateAsString(
+                 OptionsExpr, EvaluatedOptionsBuffer, Ctx,
+                 Sema::StringEvaluationContext::PointerAuthOptions,
+                 /*ErrorOnInvalidMessage=*/true))
+    OptionsString = EvaluatedOptionsBuffer;
+  else
+    return false;
+
+  auto Failed = [&](SourceRange Range = {}, unsigned DiagId = 0,
+                    auto... DiagArgs) {
+    if (Range.isValid())
+      (S.Diag(Range.getBegin(), DiagId) << ... << DiagArgs) << Range;
+    if (!OptionsLiteral)
+      S.Diag(OptionsExpr->getExprLoc(), diag::note_ptrauth_evaluated_options)
+          << EvaluatedOptionsBuffer << OptionsExpr->getSourceRange();
+    return false;
+  };
+
+  SmallVector<StringRef, 4> Options;
+  auto ParseString = OptionsString.trim();
+  if (ParseString.empty())
+    return true;
+
+  auto FindDiagnosticRange = [&](auto Token) {
+    if (!OptionsLiteral)
+      return OptionsExpr->getSourceRange();
+    unsigned StartOffset = Token.begin() - OptionsString.begin();
+    unsigned EndOffset = StartOffset + Token.size();
+    SourceLocation StartLoc =
+        S.getLocationOfStringLiteralByte(OptionsLiteral, StartOffset);
+    SourceLocation EndLoc =
+        S.getLocationOfStringLiteralByte(OptionsLiteral, EndOffset);
+    return SourceRange(StartLoc, EndLoc);
+  };
+
+  // Split up the options
+  auto IsOptionCharacter = [](char Ch) {
+    return llvm::isAlpha(Ch) || Ch == '-';
+  };
+  while (!ParseString.empty()) {
+    if (!Options.empty()) {
+      if (ParseString.size() <= 1 || !ParseString.consume_front(','))
+        break;
+      ParseString = ParseString.ltrim();
+    }
+    StringRef Option = ParseString.take_while(IsOptionCharacter);
+    if (Option.empty())
+      break;
+    Options.push_back(Option);
+    ParseString = ParseString.drop_front(Option.size()).ltrim();
+  }
+
+  if (!ParseString.empty()) {
+    StringRef LastOption;
+    if (!Options.empty())
+      LastOption = Options.back();
+    if (StringRef UnexpectedOption = ParseString.take_while(IsOptionCharacter);
+        !UnexpectedOption.empty()) {
+      SourceRange DiagRange = FindDiagnosticRange(UnexpectedOption);
+      return Failed(DiagRange, diag::err_ptrauth_options_parse_error,
+                    /*Expected Comma*/ 3, UnexpectedOption);
+    }
+    unsigned DiagIdx = 2; // unexpected character
+    if (ParseString.starts_with(','))
+      DiagIdx = ParseString.size() == 1;
+    StringRef ErrorToken = ParseString.take_front();
+    SourceRange DiagRange = FindDiagnosticRange(ErrorToken);
+    return Failed(DiagRange, diag::err_ptrauth_options_parse_error, DiagIdx,
+                  ErrorToken, LastOption);
+  }
+
+  StringRef AuthenticationModeOption;
+  StringRef IsIsaPointerOption;
+  StringRef AuthenticatesNullValuesOption;
+  for (StringRef CurrentOption : Options) {
+    StringRef *Storage = nullptr;
----------------
cor3ntin wrote:

There is no reason for this to be a pointer.

https://github.com/llvm/llvm-project/pull/136828
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to