[clang] [flang] [llvm] [clang][flang][OpenMP] Fix context selector matching and scoring (PR #224431)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 01:23:37 PDT 2026


================
@@ -2453,6 +2454,132 @@ static void AppendConstructTraitsForDirective(
     add(llvm::omp::TraitProperty::construct_dispatch_dispatch);
 }
 
+void AppendDirectiveContextTraits(llvm::omp::Directive directive,
+    llvm::SmallVectorImpl<llvm::omp::TraitProperty> &constructTraits) {
+  using llvm::omp::Directive;
+  using llvm::omp::TraitProperty;
+
+  for (Directive leaf : llvm::omp::getLeafConstructsOrSelf(directive)) {
+    if (leaf == Directive::OMPD_nothing ||
+        leaf == Directive::OMPD_metadirective ||
+        leaf == Directive::OMPD_unknown || leaf == Directive::OMPD_section ||
+        leaf == Directive::OMPD_dispatch ||
+        llvm::omp::getDirectiveCategory(leaf) ==
+            llvm::omp::Category::Informational) {
+      continue;
+    }
+
+    llvm::omp::VariantMatchInfo vmi;
+    AppendConstructTraitsForDirective(leaf, vmi);
+    if (vmi.RequiredTraits.test(
+            static_cast<unsigned>(TraitProperty::construct_target_target))) {
+      constructTraits.clear();
+    }
+    if (vmi.ConstructTraits.empty()) {
+      constructTraits.push_back(TraitProperty::invalid);
+    } else {
+      constructTraits.append(
+          vmi.ConstructTraits.begin(), vmi.ConstructTraits.end());
+    }
+  }
+}
+
+namespace {
+// Profile the original parse tree: folding a whole expression would lose
+// declaration identity. Parse-tree operators already unify alternate spellings;
+// analyze only literals to normalize their values and effective kinds.
+struct ConditionIdentity {
+  SemanticsContext &context;
+  llvm::FoldingSetNodeID id;
+
+  template <typename A> void AddNode() {
+    // Type tags and symbol addresses are local to this compilation. Profiles
+    // are rebuilt when importing symbols, never serialized as pointers.
+    static char tag;
+    id.AddPointer(&tag);
+  }
+  template <typename A> bool Pre(const A &x) {
+    AddNode<A>();
+    if constexpr (std::is_enum_v<A> || std::is_integral_v<A>)
+      id.AddInteger(static_cast<uint64_t>(x));
+    else if constexpr (std::is_same_v<A, std::string>)
+      id.AddString(x);
+    return true;
+  }
+  template <typename A> void Post(const A &) { id.AddInteger(0); }
+  // CharBlocks in expression nodes carry source locations, not structure.
+  bool Pre(const parser::CharBlock &) { return false; }
+  bool Pre(const parser::Name &name) {
+    AddNode<parser::Name>();
+    if (name.symbol)
+      id.AddPointer(&name.symbol->GetUltimate());
+    else
+      id.AddString(name.source.ToString());
+    return false;
+  }
+  bool Pre(const parser::SignedIntLiteralConstant &literal) {
+    AddNode<parser::SignedIntLiteralConstant>();
+    auto value{evaluate::ExpressionAnalyzer{context}.Analyze(literal)};
+    CHECK(value);
+    id.AddString(value->AsFortran());
+    return false;
+  }
+  bool Pre(const parser::SignedRealLiteralConstant &literal) {
+    AddNode<parser::SignedRealLiteralConstant>();
+    auto value{evaluate::ExpressionAnalyzer{context}.Analyze(literal)};
+    CHECK(value);
+    id.AddString(value->AsFortran());
+    return false;
+  }
+  bool Pre(const parser::Expr &expr) {
+    if (const auto *parens{std::get_if<parser::Expr::Parentheses>(&expr.u)}) {
+      parser::Walk(parens->v.value(), *this);
+      return false;
+    }
+    AddNode<parser::Expr>();
+    if (const auto *negate{std::get_if<parser::Expr::Negate>(&expr.u)}) {
+      if (const auto *literal{
+              std::get_if<parser::LiteralConstant>(&negate->v.value().u)}) {
+        if (std::holds_alternative<parser::IntLiteralConstant>(literal->u)) {
+          // The magnitude of the most negative integer is not representable
+          // in its kind. Analyze the signed literal together, as semantics
+          // does, rather than reanalyzing its positive magnitude.
+          auto value{evaluate::ExpressionAnalyzer{context}.Analyze(expr)};
+          CHECK(value);
----------------
MattPD wrote:

Confirmed at 3080eca: Flang now diagnoses an invalid literal in a condition as it did at the merge base.

https://github.com/llvm/llvm-project/pull/224431


More information about the llvm-commits mailing list