-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[flang] Support for warning and error compiler directives. #151510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-flang-parser Author: None (shivaramaarao) ChangesThe warning directive These directives can be used to inform the user about deprecated features. Full diff: https://github.com/llvm/llvm-project/pull/151510.diff 7 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 11725991e9c9a..a8947fddaf216 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -208,6 +208,8 @@ class ParseTreeDumper {
NODE(CompilerDirective, NameValue)
NODE(CompilerDirective, Unrecognized)
NODE(CompilerDirective, VectorAlways)
+ NODE(CompilerDirective, Error)
+ NODE(CompilerDirective, Warning)
NODE(parser, ComplexLiteralConstant)
NODE(parser, ComplexPart)
NODE(parser, ComponentArraySpec)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 00d85aa05fb3a..700cad310960e 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3363,6 +3363,12 @@ struct CompilerDirective {
TUPLE_CLASS_BOILERPLATE(AssumeAligned);
std::tuple<common::Indirection<Designator>, uint64_t> t;
};
+ struct Error {
+ WRAPPER_CLASS_BOILERPLATE(Error, std::string);
+ };
+ struct Warning {
+ WRAPPER_CLASS_BOILERPLATE(Warning, std::string);
+ };
EMPTY_CLASS(VectorAlways);
struct NameValue {
TUPLE_CLASS_BOILERPLATE(NameValue);
@@ -3370,8 +3376,8 @@ struct CompilerDirective {
};
EMPTY_CLASS(Unrecognized);
CharBlock source;
- std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
- VectorAlways, std::list<NameValue>, Unrecognized>
+ std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>, Error,
+ Warning, VectorAlways, std::list<NameValue>, Unrecognized>
u;
};
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index 7cb35c1f173bb..2b9f8ef6ca695 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -1294,6 +1294,8 @@ TYPE_PARSER(construct<StatOrErrmsg>("STAT =" >> statVariable) ||
// !DIR$ LOOP COUNT (n1[, n2]...)
// !DIR$ name[=value] [, name[=value]]...
// !DIR$ <anything else>
+// !DIR$ ERROR error-string
+// !DIR$ WARNING warning-string
constexpr auto ignore_tkr{
"IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>(
maybe(parenthesized(many(letter))), name))};
@@ -1305,11 +1307,17 @@ constexpr auto assumeAligned{"ASSUME_ALIGNED" >>
indirect(designator), ":"_tok >> digitString64))};
constexpr auto vectorAlways{
"VECTOR ALWAYS" >> construct<CompilerDirective::VectorAlways>()};
+constexpr auto error{"ERROR" >>
+ construct<CompilerDirective::Error>(charLiteralConstantWithoutKind)};
+constexpr auto warning{"WARNING" >>
+ construct<CompilerDirective::Warning>(charLiteralConstantWithoutKind)};
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
sourced((construct<CompilerDirective>(ignore_tkr) ||
construct<CompilerDirective>(loopCount) ||
construct<CompilerDirective>(assumeAligned) ||
construct<CompilerDirective>(vectorAlways) ||
+ construct<CompilerDirective>(error) ||
+ construct<CompilerDirective>(warning) ||
construct<CompilerDirective>(
many(construct<CompilerDirective::NameValue>(
name, maybe(("="_tok || ":"_tok) >> digitString64))))) /
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 7bf404bba2c3e..5c92a59d334db 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -1847,6 +1847,8 @@ class UnparseVisitor {
[&](const std::list<CompilerDirective::NameValue> &names) {
Walk("!DIR$ ", names, " ");
},
+ [&](const CompilerDirective::Error &) { Word("!DIR$ ERROR"); },
+ [&](const CompilerDirective::Warning &) { Word("!DIR$ WARNING"); },
[&](const CompilerDirective::Unrecognized &) {
Word("!DIR$ ");
Word(x.source.ToString());
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f3c2a5bf094d0..1e00eb29aabd3 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -9248,7 +9248,12 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {
if (std::holds_alternative<parser::CompilerDirective::VectorAlways>(x.u)) {
return;
}
- if (const auto *tkr{
+ if (const auto *err{std::get_if<parser::CompilerDirective::Error>(&x.u)}) {
+ Say(err->v, "%s"_err_en_US);
+ }
+ else if (const auto *warn{std::get_if<parser::CompilerDirective::Warning>(&x.u)}) {
+ Say(warn->v, "%s"_warn_en_US);
+ } else if (const auto *tkr{
std::get_if<std::list<parser::CompilerDirective::IgnoreTKR>>(&x.u)}) {
if (currScope().IsTopLevel() ||
GetProgramUnitContaining(currScope()).kind() !=
diff --git a/flang/test/Parser/compiler-directive-error.f90 b/flang/test/Parser/compiler-directive-error.f90
new file mode 100644
index 0000000000000..fa4d3cbc0cba8
--- /dev/null
+++ b/flang/test/Parser/compiler-directive-error.f90
@@ -0,0 +1,8 @@
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+! Test that error compiler directive issues error
+program warn
+!dir$ error "Error!"
+!CHECK: error: Error!
+end program
+
diff --git a/flang/test/Parser/compiler-directive-warning.f90 b/flang/test/Parser/compiler-directive-warning.f90
new file mode 100644
index 0000000000000..3fa5ede7105fc
--- /dev/null
+++ b/flang/test/Parser/compiler-directive-warning.f90
@@ -0,0 +1,8 @@
+! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+! Test that warning compiler directive issues warning
+program warn
+!dir$ warning "Warning!"
+!CHECK: warning: Warning!
+end program
+
|
@llvm/pr-subscribers-flang-semantics Author: None (shivaramaarao) ChangesThe warning directive These directives can be used to inform the user about deprecated features. Full diff: https://github.com/llvm/llvm-project/pull/151510.diff 7 Files Affected:
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 11725991e9c9a..a8947fddaf216 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -208,6 +208,8 @@ class ParseTreeDumper {
NODE(CompilerDirective, NameValue)
NODE(CompilerDirective, Unrecognized)
NODE(CompilerDirective, VectorAlways)
+ NODE(CompilerDirective, Error)
+ NODE(CompilerDirective, Warning)
NODE(parser, ComplexLiteralConstant)
NODE(parser, ComplexPart)
NODE(parser, ComponentArraySpec)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 00d85aa05fb3a..700cad310960e 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3363,6 +3363,12 @@ struct CompilerDirective {
TUPLE_CLASS_BOILERPLATE(AssumeAligned);
std::tuple<common::Indirection<Designator>, uint64_t> t;
};
+ struct Error {
+ WRAPPER_CLASS_BOILERPLATE(Error, std::string);
+ };
+ struct Warning {
+ WRAPPER_CLASS_BOILERPLATE(Warning, std::string);
+ };
EMPTY_CLASS(VectorAlways);
struct NameValue {
TUPLE_CLASS_BOILERPLATE(NameValue);
@@ -3370,8 +3376,8 @@ struct CompilerDirective {
};
EMPTY_CLASS(Unrecognized);
CharBlock source;
- std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
- VectorAlways, std::list<NameValue>, Unrecognized>
+ std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>, Error,
+ Warning, VectorAlways, std::list<NameValue>, Unrecognized>
u;
};
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index 7cb35c1f173bb..2b9f8ef6ca695 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -1294,6 +1294,8 @@ TYPE_PARSER(construct<StatOrErrmsg>("STAT =" >> statVariable) ||
// !DIR$ LOOP COUNT (n1[, n2]...)
// !DIR$ name[=value] [, name[=value]]...
// !DIR$ <anything else>
+// !DIR$ ERROR error-string
+// !DIR$ WARNING warning-string
constexpr auto ignore_tkr{
"IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>(
maybe(parenthesized(many(letter))), name))};
@@ -1305,11 +1307,17 @@ constexpr auto assumeAligned{"ASSUME_ALIGNED" >>
indirect(designator), ":"_tok >> digitString64))};
constexpr auto vectorAlways{
"VECTOR ALWAYS" >> construct<CompilerDirective::VectorAlways>()};
+constexpr auto error{"ERROR" >>
+ construct<CompilerDirective::Error>(charLiteralConstantWithoutKind)};
+constexpr auto warning{"WARNING" >>
+ construct<CompilerDirective::Warning>(charLiteralConstantWithoutKind)};
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
sourced((construct<CompilerDirective>(ignore_tkr) ||
construct<CompilerDirective>(loopCount) ||
construct<CompilerDirective>(assumeAligned) ||
construct<CompilerDirective>(vectorAlways) ||
+ construct<CompilerDirective>(error) ||
+ construct<CompilerDirective>(warning) ||
construct<CompilerDirective>(
many(construct<CompilerDirective::NameValue>(
name, maybe(("="_tok || ":"_tok) >> digitString64))))) /
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 7bf404bba2c3e..5c92a59d334db 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -1847,6 +1847,8 @@ class UnparseVisitor {
[&](const std::list<CompilerDirective::NameValue> &names) {
Walk("!DIR$ ", names, " ");
},
+ [&](const CompilerDirective::Error &) { Word("!DIR$ ERROR"); },
+ [&](const CompilerDirective::Warning &) { Word("!DIR$ WARNING"); },
[&](const CompilerDirective::Unrecognized &) {
Word("!DIR$ ");
Word(x.source.ToString());
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index f3c2a5bf094d0..1e00eb29aabd3 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -9248,7 +9248,12 @@ void ResolveNamesVisitor::Post(const parser::CompilerDirective &x) {
if (std::holds_alternative<parser::CompilerDirective::VectorAlways>(x.u)) {
return;
}
- if (const auto *tkr{
+ if (const auto *err{std::get_if<parser::CompilerDirective::Error>(&x.u)}) {
+ Say(err->v, "%s"_err_en_US);
+ }
+ else if (const auto *warn{std::get_if<parser::CompilerDirective::Warning>(&x.u)}) {
+ Say(warn->v, "%s"_warn_en_US);
+ } else if (const auto *tkr{
std::get_if<std::list<parser::CompilerDirective::IgnoreTKR>>(&x.u)}) {
if (currScope().IsTopLevel() ||
GetProgramUnitContaining(currScope()).kind() !=
diff --git a/flang/test/Parser/compiler-directive-error.f90 b/flang/test/Parser/compiler-directive-error.f90
new file mode 100644
index 0000000000000..fa4d3cbc0cba8
--- /dev/null
+++ b/flang/test/Parser/compiler-directive-error.f90
@@ -0,0 +1,8 @@
+! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+! Test that error compiler directive issues error
+program warn
+!dir$ error "Error!"
+!CHECK: error: Error!
+end program
+
diff --git a/flang/test/Parser/compiler-directive-warning.f90 b/flang/test/Parser/compiler-directive-warning.f90
new file mode 100644
index 0000000000000..3fa5ede7105fc
--- /dev/null
+++ b/flang/test/Parser/compiler-directive-warning.f90
@@ -0,0 +1,8 @@
+! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+! Test that warning compiler directive issues warning
+program warn
+!dir$ warning "Warning!"
+!CHECK: warning: Warning!
+end program
+
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be mentioned in the documentation somewhere
ab6e881
to
5bc8d6c
Compare
The compiler already has |
@@ -1305,11 +1307,17 @@ constexpr auto assumeAligned{"ASSUME_ALIGNED" >> | |||
indirect(designator), ":"_tok >> digitString64))}; | |||
constexpr auto vectorAlways{ | |||
"VECTOR ALWAYS" >> construct<CompilerDirective::VectorAlways>()}; | |||
constexpr auto error{"ERROR" >> | |||
construct<CompilerDirective::Error>(charLiteralConstantWithoutKind)}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the PR comment, these character literals are parenthesized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. updated the PR comment.
@@ -1847,6 +1847,8 @@ class UnparseVisitor { | |||
[&](const std::list<CompilerDirective::NameValue> &names) { | |||
Walk("!DIR$ ", names, " "); | |||
}, | |||
[&](const CompilerDirective::Error &) { Word("!DIR$ ERROR"); }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will you test this? The directive will emit a fatal error in semantics, and then unpausing won't be run.
if (const auto *tkr{ | ||
if (const auto *err{std::get_if<parser::CompilerDirective::Error>(&x.u)}) { | ||
Say(err->v, "%s"_err_en_US); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put the else
on this line too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. thank you.
The warning directive !$dir warning "warning message" can be used to issue warning in the codepath. Similarly, the directive !$dir error "error message" can be used to issue error in the codepath.
5bc8d6c
to
dcdea04
Compare
The warning directive
!$dir warning "warning message"
can be used to issue warning in the codepath. Similarly, the directive!$dir error "error message"
can be used to issue error in the codepath.These directives can be used to inform the user about deprecated features.