Skip to content

Conversation

kparzysz
Copy link
Contributor

It was an alias for OmpDirectiveName, which could cause confusion in parse-tree visitors: a visitor for OmpDirectiveNameModifier could be executed for an OmpDirectiveName node, leading to unexpected results.

It was an alias for OmpDirectiveName, which could cause confusion in
parse-tree visitors: a visitor for OmpDirectiveNameModifier could be
executed for an OmpDirectiveName node, leading to unexpected results.
@kparzysz kparzysz requested review from skatrak and tblah July 26, 2025 14:56
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:parser labels Jul 26, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 26, 2025

@llvm/pr-subscribers-flang-parser

Author: Krzysztof Parzyszek (kparzysz)

Changes

It was an alias for OmpDirectiveName, which could cause confusion in parse-tree visitors: a visitor for OmpDirectiveNameModifier could be executed for an OmpDirectiveName node, leading to unexpected results.


Full diff: https://github.com/llvm/llvm-project/pull/150768.diff

2 Files Affected:

  • (modified) flang/include/flang/Parser/parse-tree.h (+11-1)
  • (modified) flang/lib/Parser/openmp-parsers.cpp (+4-1)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 3a28f6f9731c3..0fb66c9f683e4 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3469,6 +3469,12 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
 
 // --- Common definitions
 
+#define INHERITED_WRAPPER_CLASS_BOILERPLATE(classname, basename) \
+  BOILERPLATE(classname); \
+  classname(decltype(basename::v) &&x) : basename(std::move(x)) {} \
+  classname(basename &&base) : basename(std::move(base)) {} \
+  using WrapperTrait = std::true_type
+
 struct OmpClause;
 struct OmpDirectiveSpecification;
 
@@ -3476,6 +3482,7 @@ struct OmpDirectiveName {
   // No boilerplates: this class should be copyable, movable, etc.
   constexpr OmpDirectiveName() = default;
   constexpr OmpDirectiveName(const OmpDirectiveName &) = default;
+  constexpr OmpDirectiveName(llvm::omp::Directive x) : v(x) {}
   // Construct from an already parsed text. Use Verbatim for this because
   // Verbatim's source corresponds to an actual source location.
   // This allows "construct<OmpDirectiveName>(Verbatim("<name>"))".
@@ -3848,7 +3855,10 @@ struct OmpDeviceModifier {
 // [*] The IF clause is allowed on CANCEL in OpenMP 4.5, but only without
 // the directive-name-modifier. For the sake of uniformity CANCEL can be
 // considered a valid value in 4.5 as well.
-using OmpDirectiveNameModifier = OmpDirectiveName;
+struct OmpDirectiveNameModifier : public OmpDirectiveName {
+  INHERITED_WRAPPER_CLASS_BOILERPLATE(
+      OmpDirectiveNameModifier, OmpDirectiveName);
+};
 
 // Ref: [5.1:205-209], [5.2:166-168]
 //
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 1c626148a03ae..9abec5aef8329 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -466,6 +466,8 @@ TYPE_PARSER(construct<OmpDeviceModifier>(
     "ANCESTOR" >> pure(OmpDeviceModifier::Value::Ancestor) ||
     "DEVICE_NUM" >> pure(OmpDeviceModifier::Value::Device_Num)))
 
+TYPE_PARSER(construct<OmpDirectiveNameModifier>(OmpDirectiveNameParser{}))
+
 TYPE_PARSER(construct<OmpExpectation>( //
     "PRESENT" >> pure(OmpExpectation::Value::Present)))
 
@@ -609,7 +611,8 @@ TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
 TYPE_PARSER(sourced(
     construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{})))
 
-TYPE_PARSER(sourced(construct<OmpIfClause::Modifier>(OmpDirectiveNameParser{})))
+TYPE_PARSER(sourced(
+    construct<OmpIfClause::Modifier>(Parser<OmpDirectiveNameModifier>{})))
 
 TYPE_PARSER(sourced(
     construct<OmpInitClause::Modifier>(

@kparzysz
Copy link
Contributor Author

Ping

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay in reviewing this. I was on holiday.


#define INHERITED_WRAPPER_CLASS_BOILERPLATE(classname, basename) \
BOILERPLATE(classname); \
classname(decltype(basename::v) &&x) : basename(std::move(x)) {} \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Could we instead just inherit all of the base class's constructor(s)? e.g.

using basename::basename;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


// --- Common definitions

#define INHERITED_WRAPPER_CLASS_BOILERPLATE(classname, basename) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you did this to follow the style in other parts of the parse tree, but in this case I wonder if it would be more foolproof to roll the whole struct declaration into the macro. It is up to you if you want to do this or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding a similar macro for tuple classes in the last PR in the stack. Let me think a bit about this and I may end up making this change in that other PR.

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update

@kparzysz kparzysz merged commit 6ffcfc5 into main Jul 31, 2025
9 checks passed
@kparzysz kparzysz deleted the users/kparzysz/a01-distinct-directive-name-modifier branch July 31, 2025 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants