[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