[flang-commits] [flang] [llvm] Add print statements to lit for tracing purposes (PR #92694)
Vlad Serebrennikov via flang-commits
flang-commits at lists.llvm.org
Sun May 19 19:31:35 PDT 2024
https://github.com/Endilll updated https://github.com/llvm/llvm-project/pull/92694
>From 2d419dd0910260272fea457beb59414798ee2594 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 15:54:44 +0300
Subject: [PATCH 01/30] Add print statements to lit for tracing purposes
---
llvm/utils/lit/lit/main.py | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index db9f24f748d9e..288558b90b77a 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -118,34 +118,56 @@ def main(builtin_params={}):
mark_xfail(discovered_tests, opts)
+ print("Endill 10")
+
mark_excluded(discovered_tests, selected_tests)
+ print("Endill 20")
+
start = time.time()
+ print("Endill 30")
run_tests(selected_tests, lit_config, opts, len(discovered_tests))
+ print("Endill 40")
elapsed = time.time() - start
+ print("Endill 50")
+
record_test_times(selected_tests, lit_config)
+ print("Endill 60")
+
selected_tests, discovered_tests = GoogleTest.post_process_shard_results(
selected_tests, discovered_tests
)
+ print("Endill 70")
+
if opts.time_tests:
print_histogram(discovered_tests)
+ print("Endill 80")
+
print_results(discovered_tests, elapsed, opts)
+ print("Endill 90")
+
tests_for_report = selected_tests if opts.shard else discovered_tests
for report in opts.reports:
report.write_results(tests_for_report, elapsed)
+ print("Endill 100")
+
if lit_config.numErrors:
sys.stderr.write("\n%d error(s) in tests\n" % lit_config.numErrors)
sys.exit(2)
+
+ print("Endill 110")
if lit_config.numWarnings:
sys.stderr.write("\n%d warning(s) in tests\n" % lit_config.numWarnings)
+ print("Endill 120")
+
has_failure = any(t.isFailure() for t in discovered_tests)
if has_failure:
if opts.ignoreFail:
>From 7edeaee2dfa50586406f27609bbd55d75e590aef Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 17:12:16 +0300
Subject: [PATCH 02/30] Add more tracing
---
llvm/utils/lit/lit/main.py | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index 288558b90b77a..91e9d2310e52f 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -266,19 +266,23 @@ def mark_excluded(discovered_tests, selected_tests):
def run_tests(tests, lit_config, opts, discovered_tests):
+ print("Endill 310")
workers = min(len(tests), opts.workers)
+ print("Endill 320")
display = lit.display.create_display(opts, tests, discovered_tests, workers)
-
+ print("Endill 330")
run = lit.run.Run(
tests, lit_config, workers, display.update, opts.max_failures, opts.timeout
)
-
+ print("Endill 340")
display.print_header()
-
+ print("Endill 350")
interrupted = False
error = None
try:
+ print("Endill 360")
execute_in_tmp_dir(run, lit_config)
+ print("Endill 370")
except KeyboardInterrupt:
interrupted = True
error = " interrupted by user"
@@ -286,10 +290,13 @@ def run_tests(tests, lit_config, opts, discovered_tests):
error = "warning: reached maximum number of test failures"
except lit.run.TimeoutError:
error = "warning: reached timeout"
+ print("Endill 380")
display.clear(interrupted)
+ print("Endill 390")
if error:
sys.stderr.write("%s, skipping remaining tests\n" % error)
+ print("Endill 3100")
def execute_in_tmp_dir(run, lit_config):
>From 13a86f1060c84e82bfbb925e16f5985907b29dd0 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 17:12:45 +0300
Subject: [PATCH 03/30] Fix indentation
---
llvm/utils/lit/lit/main.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index 91e9d2310e52f..ee991f5360a4d 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -293,7 +293,7 @@ def run_tests(tests, lit_config, opts, discovered_tests):
print("Endill 380")
display.clear(interrupted)
- print("Endill 390")
+ print("Endill 390")
if error:
sys.stderr.write("%s, skipping remaining tests\n" % error)
print("Endill 3100")
>From 34619d6b865645e30af729aed03ff2d35a974062 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 17:16:15 +0300
Subject: [PATCH 04/30] Add even more tracing
---
llvm/utils/lit/lit/main.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index ee991f5360a4d..09354b3092d8a 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -300,6 +300,7 @@ def run_tests(tests, lit_config, opts, discovered_tests):
def execute_in_tmp_dir(run, lit_config):
+ print("Endill 3600")
# Create a temp directory inside the normal temp directory so that we can
# try to avoid temporary test file leaks. The user can avoid this behavior
# by setting LIT_PRESERVES_TMP in the environment, so they can easily use
@@ -308,26 +309,36 @@ def execute_in_tmp_dir(run, lit_config):
tmp_dir = None
if "LIT_PRESERVES_TMP" not in os.environ:
import tempfile
-
+ print("Endill 3610")
# z/OS linker does not support '_' in paths, so use '-'.
tmp_dir = tempfile.mkdtemp(prefix="lit-tmp-")
+ print("Endill 3620")
tmp_dir_envs = {k: tmp_dir for k in ["TMP", "TMPDIR", "TEMP", "TEMPDIR"]}
os.environ.update(tmp_dir_envs)
+ print("Endill 3630")
for cfg in {t.config for t in run.tests}:
cfg.environment.update(tmp_dir_envs)
+ print("Endill 3640")
try:
+ print("Endill 3650")
run.execute()
+ print("Endill 3660")
finally:
+ print("Endill 3670")
if tmp_dir:
try:
+ print("Endill 3680")
import shutil
-
+ print("Endill 3690")
shutil.rmtree(tmp_dir)
+ print("Endill 36100")
except Exception as e:
+ print("Endill 36110")
lit_config.warning(
"Failed to delete temp directory '%s', try upgrading your version of Python to fix this"
% tmp_dir
)
+ print("Endill 36120")
def print_histogram(tests):
>From bc6d8fd4a834a2a48fb450e1627680f36a35e066 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 18:17:34 +0300
Subject: [PATCH 05/30] Add even more tracing
---
llvm/utils/lit/lit/formats/googletest.py | 11 ++++++++--
llvm/utils/lit/lit/run.py | 28 ++++++++++++++++++++++++
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/llvm/utils/lit/lit/formats/googletest.py b/llvm/utils/lit/lit/formats/googletest.py
index 8037094a91067..25dcc85df81e4 100644
--- a/llvm/utils/lit/lit/formats/googletest.py
+++ b/llvm/utils/lit/lit/formats/googletest.py
@@ -140,18 +140,20 @@ def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, localConfig):
)
def execute(self, test, litConfig):
+ print("Endill gt-0")
if test.gtest_json_file is None:
return lit.Test.FAIL, ""
testPath = test.getSourcePath()
from lit.cl_arguments import TestOrder
-
+ print("Endill gt-1")
use_shuffle = TestOrder(litConfig.order) == TestOrder.RANDOM
shard_env = {
"GTEST_OUTPUT": "json:" + test.gtest_json_file,
"GTEST_SHUFFLE": "1" if use_shuffle else "0",
}
if litConfig.gtest_sharding:
+ print("Endill gt-2")
testPath, testName = os.path.split(test.getSourcePath())
while not os.path.exists(testPath):
# Handle GTest parameterized and typed tests, whose name includes
@@ -186,13 +188,16 @@ def get_shard_header(shard_env):
shard_header = get_shard_header(shard_env)
try:
+ print("Endill gt-3")
out, _, exitCode = lit.util.executeCommand(
cmd,
env=test.config.environment,
timeout=litConfig.maxIndividualTestTime,
redirect_stderr=True,
)
+ print("Endill gt-4")
except lit.util.ExecuteCommandTimeoutException as e:
+ print("Endill gt-5")
stream_msg = f"\n{e.out}\n--\nexit: {e.exitCode}\n--\n"
return (
lit.Test.TIMEOUT,
@@ -225,7 +230,9 @@ def get_test_stdout(test_name):
found_failed_test = False
with open(test.gtest_json_file, encoding="utf-8") as f:
+ print("Endill gt-6")
jf = json.load(f)
+ print("Endill gt-7")
if use_shuffle:
shard_env["GTEST_RANDOM_SEED"] = str(jf["random_seed"])
@@ -258,7 +265,7 @@ def get_test_stdout(test_name):
# the shard could still fail due to memory issues.
if not found_failed_test:
output += f"\n{out}\n--\nexit: {exitCode}\n--\n"
-
+ print("Endill gt-8")
return lit.Test.FAIL, output
def prepareCmd(self, cmd):
diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py
index 535c859352cc4..ebbce0e75a9ce 100644
--- a/llvm/utils/lit/lit/run.py
+++ b/llvm/utils/lit/lit/run.py
@@ -30,6 +30,7 @@ def __init__(
assert workers > 0
def execute(self):
+ print("Endill 36500")
"""
Execute the tests in the run using up to the specified number of
parallel tasks, and inform the caller of each individual result. The
@@ -55,25 +56,36 @@ def execute(self):
deadline = time.time() + timeout
try:
+ print("Endill 36510")
self._execute(deadline)
+ print("Endill 36520")
finally:
+ print("Endill 36530")
skipped = lit.Test.Result(lit.Test.SKIPPED)
+ print("Endill 36540")
for test in self.tests:
+ print("Endill 36550")
if test.result is None:
test.setResult(skipped)
+ print("Endill 36560")
+
def _execute(self, deadline):
+ print("Endill 365100")
self._increase_process_limit()
+ print("Endill 365110")
semaphores = {
k: multiprocessing.BoundedSemaphore(v)
for k, v in self.lit_config.parallelism_groups.items()
if v is not None
}
+ print("Endill 365120")
pool = multiprocessing.Pool(
self.workers, lit.worker.initialize, (self.lit_config, semaphores)
)
+ print("Endill 365130")
async_results = [
pool.apply_async(
@@ -81,29 +93,45 @@ def _execute(self, deadline):
)
for test in self.tests
]
+ print("Endill 365140")
pool.close()
+ print("Endill 365150")
try:
+ print("Endill 365160")
self._wait_for(async_results, deadline)
+ print("Endill 365170")
except:
+ print("Endill 365180")
pool.terminate()
+ print("Endill 365190")
raise
finally:
+ print("Endill 3651100")
pool.join()
+ print("Endill 3651110")
def _wait_for(self, async_results, deadline):
+ print("Endill 3651600")
timeout = deadline - time.time()
for idx, ar in enumerate(async_results):
+ print("Endill 3651610")
try:
+ print("Endill 3651620")
test = ar.get(timeout)
+ print("Endill 3651630")
except multiprocessing.TimeoutError:
+ print("Endill 3651640")
raise TimeoutError()
else:
+ print("Endill 3651650")
self._update_test(self.tests[idx], test)
+ print("Endill 3651660")
if test.isFailure():
self.failures += 1
if self.failures == self.max_failures:
raise MaxFailuresError()
+ print("Endill 3651670")
# Update local test object "in place" from remote test object. This
# ensures that the original test object which is used for printing test
>From e6256b3019b721077847c23b648d0b98eb2fe872 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 19:20:13 +0300
Subject: [PATCH 06/30] Print individual test details
---
llvm/utils/lit/lit/formats/googletest.py | 4 ++++
llvm/utils/lit/lit/run.py | 4 +++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/llvm/utils/lit/lit/formats/googletest.py b/llvm/utils/lit/lit/formats/googletest.py
index 25dcc85df81e4..a054e044beff9 100644
--- a/llvm/utils/lit/lit/formats/googletest.py
+++ b/llvm/utils/lit/lit/formats/googletest.py
@@ -205,12 +205,15 @@ def get_shard_header(shard_env):
f"timeout of {litConfig.maxIndividualTestTime} seconds",
)
+ print("Endill gt-5-1")
if not os.path.exists(test.gtest_json_file):
+ print("Endill gt-5-2")
errmsg = f"shard JSON output does not exist: %s" % (test.gtest_json_file)
stream_msg = f"\n{out}\n--\nexit: {exitCode}\n--\n"
return lit.Test.FAIL, shard_header + stream_msg + errmsg
if exitCode == 0:
+ print("Endill gt-5-3")
return lit.Test.PASS, ""
def get_test_stdout(test_name):
@@ -229,6 +232,7 @@ def get_test_stdout(test_name):
found_failed_test = False
+ print("Endill gt-5-4")
with open(test.gtest_json_file, encoding="utf-8") as f:
print("Endill gt-6")
jf = json.load(f)
diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py
index ebbce0e75a9ce..54482071a67b2 100644
--- a/llvm/utils/lit/lit/run.py
+++ b/llvm/utils/lit/lit/run.py
@@ -64,7 +64,6 @@ def execute(self):
skipped = lit.Test.Result(lit.Test.SKIPPED)
print("Endill 36540")
for test in self.tests:
- print("Endill 36550")
if test.result is None:
test.setResult(skipped)
print("Endill 36560")
@@ -120,6 +119,9 @@ def _wait_for(self, async_results, deadline):
print("Endill 3651620")
test = ar.get(timeout)
print("Endill 3651630")
+ print("Endill: test.file_path: {}".format(test.file_path))
+ print("Endill: test.path_in_suite: {}".format(test.path_in_suite))
+ print("Endill 3651635")
except multiprocessing.TimeoutError:
print("Endill 3651640")
raise TimeoutError()
>From 15fc2f17fbb6aa4b1500f713ea00540b2b70df53 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 20:27:31 +0300
Subject: [PATCH 07/30] Print names of unit tests in shards
---
llvm/utils/lit/lit/formats/googletest.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/llvm/utils/lit/lit/formats/googletest.py b/llvm/utils/lit/lit/formats/googletest.py
index a054e044beff9..e665ac6a98cae 100644
--- a/llvm/utils/lit/lit/formats/googletest.py
+++ b/llvm/utils/lit/lit/formats/googletest.py
@@ -214,6 +214,16 @@ def get_shard_header(shard_env):
if exitCode == 0:
print("Endill gt-5-3")
+ print("Endill: shard header: {}".format(get_shard_header(shard_env)))
+ with open(test.gtest_json_file, encoding="utf-8") as f:
+ print("Endill gt-5-6")
+ jf = json.load(f)
+ print("Endill gt-5-7")
+ for testcase in jf["testsuites"]:
+ for testinfo in testcase["testsuite"]:
+ testname = testcase["name"] + "." + testinfo["name"]
+ print("Endill: testnamae: {}".format(testname))
+
return lit.Test.PASS, ""
def get_test_stdout(test_name):
>From 1c785a63d029dc55fc06ec236e55983729767e2f Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 21:30:55 +0300
Subject: [PATCH 08/30] Disable a bunch of flang tests
---
.../Optimizer/Builder/ComplexTest.cpp | 44 ++--
.../Optimizer/Builder/DoLoopHelperTest.cpp | 30 +--
.../Optimizer/Builder/FIRBuilderTest.cpp | 12 +-
.../Optimizer/Builder/HLFIRToolsTest.cpp | 64 +++---
.../Builder/Runtime/CharacterTest.cpp | 22 +-
.../Optimizer/Builder/Runtime/CommandTest.cpp | 12 +-
.../Builder/Runtime/ReductionTest.cpp | 42 ++--
flang/unittests/Optimizer/FIRTypesTest.cpp | 54 ++---
.../Optimizer/FortranVariableTest.cpp | 44 ++--
.../unittests/Optimizer/InternalNamesTest.cpp | 64 +++---
flang/unittests/Runtime/CharacterTest.cpp | 96 ++++-----
flang/unittests/Runtime/CommandTest.cpp | 74 +++----
flang/unittests/Runtime/Complex.cpp | 34 +--
flang/unittests/Runtime/ExternalIOTest.cpp | 194 +++++++++---------
flang/unittests/Runtime/Format.cpp | 24 +--
flang/unittests/Runtime/ListInputTest.cpp | 58 +++---
flang/unittests/Runtime/MiscIntrinsic.cpp | 36 ++--
flang/unittests/Runtime/Numeric.cpp | 120 +++++------
.../unittests/Runtime/NumericalFormatTest.cpp | 30 +--
flang/unittests/Runtime/Pointer.cpp | 38 ++--
flang/unittests/Runtime/RuntimeCrashTest.cpp | 18 +-
flang/unittests/Runtime/Stop.cpp | 36 ++--
flang/unittests/Runtime/TemporaryStack.cpp | 160 +++++++--------
23 files changed, 653 insertions(+), 653 deletions(-)
diff --git a/flang/unittests/Optimizer/Builder/ComplexTest.cpp b/flang/unittests/Optimizer/Builder/ComplexTest.cpp
index 17171512470ac..b17ef9ef2f348 100644
--- a/flang/unittests/Optimizer/Builder/ComplexTest.cpp
+++ b/flang/unittests/Optimizer/Builder/ComplexTest.cpp
@@ -62,30 +62,30 @@ struct ComplexTest : public testing::Test {
mlir::Value rFour;
};
-TEST_F(ComplexTest, verifyTypes) {
- mlir::Value cVal1 = helper->createComplex(complexTy1, rOne, rTwo);
- mlir::Value cVal2 = helper->createComplex(4, rOne, rTwo);
- EXPECT_TRUE(fir::isa_complex(cVal1.getType()));
- EXPECT_TRUE(fir::isa_complex(cVal2.getType()));
- EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal1)));
- EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal2)));
+// TEST_F(ComplexTest, verifyTypes) {
+// mlir::Value cVal1 = helper->createComplex(complexTy1, rOne, rTwo);
+// mlir::Value cVal2 = helper->createComplex(4, rOne, rTwo);
+// EXPECT_TRUE(fir::isa_complex(cVal1.getType()));
+// EXPECT_TRUE(fir::isa_complex(cVal2.getType()));
+// EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal1)));
+// EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal2)));
- mlir::Value real1 = helper->extractComplexPart(cVal1, /*isImagPart=*/false);
- mlir::Value imag1 = helper->extractComplexPart(cVal1, /*isImagPart=*/true);
- mlir::Value real2 = helper->extractComplexPart(cVal2, /*isImagPart=*/false);
- mlir::Value imag2 = helper->extractComplexPart(cVal2, /*isImagPart=*/true);
- EXPECT_EQ(realTy1, real1.getType());
- EXPECT_EQ(realTy1, imag1.getType());
- EXPECT_EQ(realTy1, real2.getType());
- EXPECT_EQ(realTy1, imag2.getType());
+// mlir::Value real1 = helper->extractComplexPart(cVal1, /*isImagPart=*/false);
+// mlir::Value imag1 = helper->extractComplexPart(cVal1, /*isImagPart=*/true);
+// mlir::Value real2 = helper->extractComplexPart(cVal2, /*isImagPart=*/false);
+// mlir::Value imag2 = helper->extractComplexPart(cVal2, /*isImagPart=*/true);
+// EXPECT_EQ(realTy1, real1.getType());
+// EXPECT_EQ(realTy1, imag1.getType());
+// EXPECT_EQ(realTy1, real2.getType());
+// EXPECT_EQ(realTy1, imag2.getType());
- mlir::Value cVal3 =
- helper->insertComplexPart(cVal1, rThree, /*isImagPart=*/false);
- mlir::Value cVal4 =
- helper->insertComplexPart(cVal3, rFour, /*isImagPart=*/true);
- EXPECT_TRUE(fir::isa_complex(cVal4.getType()));
- EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal4)));
-}
+// mlir::Value cVal3 =
+// helper->insertComplexPart(cVal1, rThree, /*isImagPart=*/false);
+// mlir::Value cVal4 =
+// helper->insertComplexPart(cVal3, rFour, /*isImagPart=*/true);
+// EXPECT_TRUE(fir::isa_complex(cVal4.getType()));
+// EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal4)));
+// }
TEST_F(ComplexTest, verifyConvertWithSemantics) {
auto loc = firBuilder->getUnknownLoc();
diff --git a/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp b/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp
index d0a9342914a39..9da6cde3e1d1e 100644
--- a/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp
+++ b/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp
@@ -69,19 +69,19 @@ TEST_F(DoLoopHelperTest, createLoopWithLowerAndUpperBound) {
checkConstantValue(loop.getStep(), 1);
}
-TEST_F(DoLoopHelperTest, createLoopWithStep) {
- auto firBuilder = getBuilder();
- fir::factory::DoLoopHelper helper(firBuilder, firBuilder.getUnknownLoc());
+// TEST_F(DoLoopHelperTest, createLoopWithStep) {
+// auto firBuilder = getBuilder();
+// fir::factory::DoLoopHelper helper(firBuilder, firBuilder.getUnknownLoc());
- auto lb = firBuilder.createIntegerConstant(
- firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 1);
- auto ub = firBuilder.createIntegerConstant(
- firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 20);
- auto step = firBuilder.createIntegerConstant(
- firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 2);
- auto loop = helper.createLoop(
- lb, ub, step, [&](fir::FirOpBuilder &, mlir::Value index) {});
- checkConstantValue(loop.getLowerBound(), 1);
- checkConstantValue(loop.getUpperBound(), 20);
- checkConstantValue(loop.getStep(), 2);
-}
+// auto lb = firBuilder.createIntegerConstant(
+// firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 1);
+// auto ub = firBuilder.createIntegerConstant(
+// firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 20);
+// auto step = firBuilder.createIntegerConstant(
+// firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 2);
+// auto loop = helper.createLoop(
+// lb, ub, step, [&](fir::FirOpBuilder &, mlir::Value index) {});
+// checkConstantValue(loop.getLowerBound(), 1);
+// checkConstantValue(loop.getUpperBound(), 20);
+// checkConstantValue(loop.getStep(), 2);
+// }
diff --git a/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp b/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp
index e5e5454ee88ad..3f18ea073711f 100644
--- a/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp
+++ b/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp
@@ -154,12 +154,12 @@ TEST_F(FIRBuilderTest, createRealZeroConstant) {
0u, mlir::cast<FloatAttr>(cstOp.getValue()).getValue().convertToDouble());
}
-TEST_F(FIRBuilderTest, createBool) {
- auto builder = getBuilder();
- auto loc = builder.getUnknownLoc();
- auto b = builder.createBool(loc, false);
- checkIntegerConstant(b, builder.getIntegerType(1), 0);
-}
+// TEST_F(FIRBuilderTest, createBool) {
+// auto builder = getBuilder();
+// auto loc = builder.getUnknownLoc();
+// auto b = builder.createBool(loc, false);
+// checkIntegerConstant(b, builder.getIntegerType(1), 0);
+// }
TEST_F(FIRBuilderTest, getVarLenSeqTy) {
auto builder = getBuilder();
diff --git a/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp b/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp
index 1858b276f1fc3..616045f275e16 100644
--- a/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp
+++ b/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp
@@ -126,38 +126,38 @@ TEST_F(HLFIRToolsTest, testScalarCharRoundTrip) {
EXPECT_FALSE(scalarCharEntity.isValue());
}
-TEST_F(HLFIRToolsTest, testArrayCharRoundTrip) {
- auto &builder = getBuilder();
- mlir::Location loc = getLoc();
- llvm::SmallVector<mlir::Value> extents{
- createConstant(20), createConstant(30)};
- llvm::SmallVector<mlir::Value> lbounds{
- createConstant(-1), createConstant(-2)};
- mlir::Value len = createConstant(42);
- mlir::Type charType = fir::CharacterType::getUnknownLen(&context, 1);
- mlir::Type seqCharType = builder.getVarLenSeqTy(charType, 2);
- mlir::Type arrayCharType = builder.getRefType(seqCharType);
- mlir::Value arrayCharAddr = builder.create<fir::UndefOp>(loc, arrayCharType);
- fir::CharArrayBoxValue arrayChar{arrayCharAddr, len, extents, lbounds};
- hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar));
- auto [arrayCharResult, cleanup] =
- hlfir::translateToExtendedValue(loc, builder, arrayCharEntity);
- auto *res = arrayCharResult.getBoxOf<fir::CharArrayBoxValue>();
- EXPECT_FALSE(cleanup.has_value());
- ASSERT_NE(res, nullptr);
- // gtest has a terrible time printing mlir::Value in case of failing
- // EXPECT_EQ(mlir::Value, mlir::Value). So use EXPECT_TRUE instead.
- EXPECT_TRUE(fir::getBase(*res) == arrayCharEntity.getFirBase());
- EXPECT_TRUE(res->getLen() == arrayChar.getLen());
- ASSERT_EQ(res->getExtents().size(), arrayChar.getExtents().size());
- for (unsigned i = 0; i < arrayChar.getExtents().size(); ++i)
- EXPECT_TRUE(res->getExtents()[i] == arrayChar.getExtents()[i]);
- ASSERT_EQ(res->getLBounds().size(), arrayChar.getLBounds().size());
- for (unsigned i = 0; i < arrayChar.getLBounds().size(); ++i)
- EXPECT_TRUE(res->getLBounds()[i] == arrayChar.getLBounds()[i]);
- EXPECT_TRUE(arrayCharEntity.isVariable());
- EXPECT_FALSE(arrayCharEntity.isValue());
-}
+// TEST_F(HLFIRToolsTest, testArrayCharRoundTrip) {
+// auto &builder = getBuilder();
+// mlir::Location loc = getLoc();
+// llvm::SmallVector<mlir::Value> extents{
+// createConstant(20), createConstant(30)};
+// llvm::SmallVector<mlir::Value> lbounds{
+// createConstant(-1), createConstant(-2)};
+// mlir::Value len = createConstant(42);
+// mlir::Type charType = fir::CharacterType::getUnknownLen(&context, 1);
+// mlir::Type seqCharType = builder.getVarLenSeqTy(charType, 2);
+// mlir::Type arrayCharType = builder.getRefType(seqCharType);
+// mlir::Value arrayCharAddr = builder.create<fir::UndefOp>(loc, arrayCharType);
+// fir::CharArrayBoxValue arrayChar{arrayCharAddr, len, extents, lbounds};
+// hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar));
+// auto [arrayCharResult, cleanup] =
+// hlfir::translateToExtendedValue(loc, builder, arrayCharEntity);
+// auto *res = arrayCharResult.getBoxOf<fir::CharArrayBoxValue>();
+// EXPECT_FALSE(cleanup.has_value());
+// ASSERT_NE(res, nullptr);
+// // gtest has a terrible time printing mlir::Value in case of failing
+// // EXPECT_EQ(mlir::Value, mlir::Value). So use EXPECT_TRUE instead.
+// EXPECT_TRUE(fir::getBase(*res) == arrayCharEntity.getFirBase());
+// EXPECT_TRUE(res->getLen() == arrayChar.getLen());
+// ASSERT_EQ(res->getExtents().size(), arrayChar.getExtents().size());
+// for (unsigned i = 0; i < arrayChar.getExtents().size(); ++i)
+// EXPECT_TRUE(res->getExtents()[i] == arrayChar.getExtents()[i]);
+// ASSERT_EQ(res->getLBounds().size(), arrayChar.getLBounds().size());
+// for (unsigned i = 0; i < arrayChar.getLBounds().size(); ++i)
+// EXPECT_TRUE(res->getLBounds()[i] == arrayChar.getLBounds()[i]);
+// EXPECT_TRUE(arrayCharEntity.isVariable());
+// EXPECT_FALSE(arrayCharEntity.isValue());
+// }
TEST_F(HLFIRToolsTest, testArrayCharBoxRoundTrip) {
auto &builder = getBuilder();
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp
index 315f8c80dc33f..18f7dd0743a73 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp
@@ -113,17 +113,17 @@ TEST_F(RuntimeCallTest, genIndexTest) {
checkGenIndex(*firBuilder, "_FortranAIndex4", 4);
}
-TEST_F(RuntimeCallTest, genIndexDescriptorTest) {
- auto loc = firBuilder->getUnknownLoc();
- mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
- mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
- mlir::Value substringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
- mlir::Value backOpt = firBuilder->create<fir::UndefOp>(loc, boxTy);
- mlir::Value kind = firBuilder->create<fir::UndefOp>(loc, i32Ty);
- fir::runtime::genIndexDescriptor(
- *firBuilder, loc, resultBox, stringBox, substringBox, backOpt, kind);
- checkCallOpFromResultBox(resultBox, "_FortranAIndex", 5);
-}
+// TEST_F(RuntimeCallTest, genIndexDescriptorTest) {
+// auto loc = firBuilder->getUnknownLoc();
+// mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
+// mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
+// mlir::Value substringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
+// mlir::Value backOpt = firBuilder->create<fir::UndefOp>(loc, boxTy);
+// mlir::Value kind = firBuilder->create<fir::UndefOp>(loc, i32Ty);
+// fir::runtime::genIndexDescriptor(
+// *firBuilder, loc, resultBox, stringBox, substringBox, backOpt, kind);
+// checkCallOpFromResultBox(resultBox, "_FortranAIndex", 5);
+// }
TEST_F(RuntimeCallTest, genRepeatTest) {
auto loc = firBuilder->getUnknownLoc();
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
index 58a151447d5b4..57347e56b4c61 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
@@ -10,12 +10,12 @@
#include "RuntimeCallTestBase.h"
#include "gtest/gtest.h"
-TEST_F(RuntimeCallTest, genCommandArgumentCountTest) {
- mlir::Location loc = firBuilder->getUnknownLoc();
- mlir::Value result = fir::runtime::genCommandArgumentCount(*firBuilder, loc);
- checkCallOp(result.getDefiningOp(), "_FortranAArgumentCount", /*nbArgs=*/0,
- /*addLocArgs=*/false);
-}
+// TEST_F(RuntimeCallTest, genCommandArgumentCountTest) {
+// mlir::Location loc = firBuilder->getUnknownLoc();
+// mlir::Value result = fir::runtime::genCommandArgumentCount(*firBuilder, loc);
+// checkCallOp(result.getDefiningOp(), "_FortranAArgumentCount", /*nbArgs=*/0,
+// /*addLocArgs=*/false);
+// }
TEST_F(RuntimeCallTest, genGetCommandArgument) {
mlir::Location loc = firBuilder->getUnknownLoc();
diff --git a/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp
index a4006c6b59c12..994e113da70e4 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp
@@ -52,15 +52,15 @@ TEST_F(RuntimeCallTest, genCountTest) {
checkCallOp(count.getDefiningOp(), "_FortranACount", 2);
}
-TEST_F(RuntimeCallTest, genCountDimTest) {
- mlir::Location loc = firBuilder->getUnknownLoc();
- mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
- mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
- mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
- mlir::Value kind = firBuilder->createIntegerConstant(loc, i32Ty, 1);
- fir::runtime::genCountDim(*firBuilder, loc, result, mask, dim, kind);
- checkCallOpFromResultBox(result, "_FortranACountDim", 4);
-}
+// TEST_F(RuntimeCallTest, genCountDimTest) {
+// mlir::Location loc = firBuilder->getUnknownLoc();
+// mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+// mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+// mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
+// mlir::Value kind = firBuilder->createIntegerConstant(loc, i32Ty, 1);
+// fir::runtime::genCountDim(*firBuilder, loc, result, mask, dim, kind);
+// checkCallOpFromResultBox(result, "_FortranACountDim", 4);
+// }
void testGenMaxVal(
fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {
@@ -120,14 +120,14 @@ TEST_F(RuntimeCallTest, genParityTest) {
checkCallOp(parity.getDefiningOp(), "_FortranAParity", 2);
}
-TEST_F(RuntimeCallTest, genParityDescriptorTest) {
- mlir::Location loc = firBuilder->getUnknownLoc();
- mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
- mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
- mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
- fir::runtime::genParityDescriptor(*firBuilder, loc, result, mask, dim);
- checkCallOpFromResultBox(result, "_FortranAParityDim", 3);
-}
+// TEST_F(RuntimeCallTest, genParityDescriptorTest) {
+// mlir::Location loc = firBuilder->getUnknownLoc();
+// mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+// mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+// mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
+// fir::runtime::genParityDescriptor(*firBuilder, loc, result, mask, dim);
+// checkCallOpFromResultBox(result, "_FortranAParityDim", 3);
+// }
void testGenSum(
fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {
@@ -349,10 +349,10 @@ TEST_F(RuntimeCallTest, genMaxvalCharTest) {
*firBuilder, fir::runtime::genMaxvalChar, "_FortranAMaxvalCharacter", 3);
}
-TEST_F(RuntimeCallTest, genMinvalCharTest) {
- checkGenMxxvalChar(
- *firBuilder, fir::runtime::genMinvalChar, "_FortranAMinvalCharacter", 3);
-}
+// TEST_F(RuntimeCallTest, genMinvalCharTest) {
+// checkGenMxxvalChar(
+// *firBuilder, fir::runtime::genMinvalChar, "_FortranAMinvalCharacter", 3);
+// }
void checkGen4argsDim(fir::FirOpBuilder &builder,
void (*genFct)(fir::FirOpBuilder &, mlir::Location, mlir::Value,
diff --git a/flang/unittests/Optimizer/FIRTypesTest.cpp b/flang/unittests/Optimizer/FIRTypesTest.cpp
index 238aa6939d5df..5ea621eebcdd4 100644
--- a/flang/unittests/Optimizer/FIRTypesTest.cpp
+++ b/flang/unittests/Optimizer/FIRTypesTest.cpp
@@ -125,33 +125,33 @@ TEST_F(FIRTypesTest, isUnlimitedPolymorphicTypeTest) {
}
// Test fir::isBoxedRecordType from flang/Optimizer/Dialect/FIRType.h.
-TEST_F(FIRTypesTest, isBoxedRecordType) {
- mlir::Type recTy = fir::RecordType::get(&context, "dt");
- mlir::Type seqRecTy =
- fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);
- mlir::Type ty = fir::BoxType::get(recTy);
- EXPECT_TRUE(fir::isBoxedRecordType(ty));
- EXPECT_TRUE(fir::isBoxedRecordType(fir::ReferenceType::get(ty)));
-
- // TYPE(T), ALLOCATABLE
- ty = fir::BoxType::get(fir::HeapType::get(recTy));
- EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
- // TYPE(T), POINTER
- ty = fir::BoxType::get(fir::PointerType::get(recTy));
- EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
- // TYPE(T), DIMENSION(10)
- ty = fir::BoxType::get(fir::SequenceType::get({10}, recTy));
- EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
- // TYPE(T), DIMENSION(:)
- ty = fir::BoxType::get(seqRecTy);
- EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
- EXPECT_FALSE(fir::isBoxedRecordType(fir::BoxType::get(
- fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)))));
-}
+// TEST_F(FIRTypesTest, isBoxedRecordType) {
+// mlir::Type recTy = fir::RecordType::get(&context, "dt");
+// mlir::Type seqRecTy =
+// fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);
+// mlir::Type ty = fir::BoxType::get(recTy);
+// EXPECT_TRUE(fir::isBoxedRecordType(ty));
+// EXPECT_TRUE(fir::isBoxedRecordType(fir::ReferenceType::get(ty)));
+
+// // TYPE(T), ALLOCATABLE
+// ty = fir::BoxType::get(fir::HeapType::get(recTy));
+// EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+// // TYPE(T), POINTER
+// ty = fir::BoxType::get(fir::PointerType::get(recTy));
+// EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+// // TYPE(T), DIMENSION(10)
+// ty = fir::BoxType::get(fir::SequenceType::get({10}, recTy));
+// EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+// // TYPE(T), DIMENSION(:)
+// ty = fir::BoxType::get(seqRecTy);
+// EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+// EXPECT_FALSE(fir::isBoxedRecordType(fir::BoxType::get(
+// fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)))));
+// }
// Test fir::isScalarBoxedRecordType from flang/Optimizer/Dialect/FIRType.h.
TEST_F(FIRTypesTest, isScalarBoxedRecordType) {
diff --git a/flang/unittests/Optimizer/FortranVariableTest.cpp b/flang/unittests/Optimizer/FortranVariableTest.cpp
index 87efb624735cf..ae48cdb18533e 100644
--- a/flang/unittests/Optimizer/FortranVariableTest.cpp
+++ b/flang/unittests/Optimizer/FortranVariableTest.cpp
@@ -42,29 +42,29 @@ struct FortranVariableTest : public testing::Test {
std::unique_ptr<mlir::OpBuilder> builder;
};
-TEST_F(FortranVariableTest, SimpleScalar) {
- mlir::Location loc = getLoc();
- mlir::Type eleType = mlir::FloatType::getF32(&context);
- mlir::Value addr = builder->create<fir::AllocaOp>(loc, eleType);
- auto name = mlir::StringAttr::get(&context, "x");
- auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
- /*shape=*/mlir::Value{}, /*typeParams=*/std::nullopt,
- /*dummy_scope=*/nullptr, name,
- /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
- /*data_attr=*/cuf::DataAttributeAttr{});
+// TEST_F(FortranVariableTest, SimpleScalar) {
+// mlir::Location loc = getLoc();
+// mlir::Type eleType = mlir::FloatType::getF32(&context);
+// mlir::Value addr = builder->create<fir::AllocaOp>(loc, eleType);
+// auto name = mlir::StringAttr::get(&context, "x");
+// auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
+// /*shape=*/mlir::Value{}, /*typeParams=*/std::nullopt,
+// /*dummy_scope=*/nullptr, name,
+// /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
+// /*data_attr=*/cuf::DataAttributeAttr{});
- fir::FortranVariableOpInterface fortranVariable = declare;
- EXPECT_FALSE(fortranVariable.isArray());
- EXPECT_FALSE(fortranVariable.isCharacter());
- EXPECT_FALSE(fortranVariable.isPointer());
- EXPECT_FALSE(fortranVariable.isAllocatable());
- EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
- EXPECT_EQ(fortranVariable.getElementType(), eleType);
- EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
- fortranVariable.getElementType());
- EXPECT_NE(fortranVariable.getBase(), addr);
- EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
-}
+// fir::FortranVariableOpInterface fortranVariable = declare;
+// EXPECT_FALSE(fortranVariable.isArray());
+// EXPECT_FALSE(fortranVariable.isCharacter());
+// EXPECT_FALSE(fortranVariable.isPointer());
+// EXPECT_FALSE(fortranVariable.isAllocatable());
+// EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
+// EXPECT_EQ(fortranVariable.getElementType(), eleType);
+// EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
+// fortranVariable.getElementType());
+// EXPECT_NE(fortranVariable.getBase(), addr);
+// EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
+// }
TEST_F(FortranVariableTest, CharacterScalar) {
mlir::Location loc = getLoc();
diff --git a/flang/unittests/Optimizer/InternalNamesTest.cpp b/flang/unittests/Optimizer/InternalNamesTest.cpp
index 058bbeef9b007..470791d41541a 100644
--- a/flang/unittests/Optimizer/InternalNamesTest.cpp
+++ b/flang/unittests/Optimizer/InternalNamesTest.cpp
@@ -88,38 +88,38 @@ TEST(InternalNamesTest, doTypeTest) {
ASSERT_EQ(actual, expectedMangledName);
}
-TEST(InternalNamesTest, doIntrinsicTypeDescriptorTest) {
- using IntrinsicType = fir::NameUniquer::IntrinsicType;
- std::string actual = NameUniquer::doIntrinsicTypeDescriptor(
- {}, {}, 0, IntrinsicType::REAL, 42);
- std::string expectedMangledName = "_QYIrealK42";
- ASSERT_EQ(actual, expectedMangledName);
-
- actual = NameUniquer::doIntrinsicTypeDescriptor(
- {}, {}, 0, IntrinsicType::REAL, {});
- expectedMangledName = "_QYIrealK0";
- ASSERT_EQ(actual, expectedMangledName);
-
- actual = NameUniquer::doIntrinsicTypeDescriptor(
- {}, {}, 0, IntrinsicType::INTEGER, 3);
- expectedMangledName = "_QYIintegerK3";
- ASSERT_EQ(actual, expectedMangledName);
-
- actual = NameUniquer::doIntrinsicTypeDescriptor(
- {}, {}, 0, IntrinsicType::LOGICAL, 2);
- expectedMangledName = "_QYIlogicalK2";
- ASSERT_EQ(actual, expectedMangledName);
-
- actual = NameUniquer::doIntrinsicTypeDescriptor(
- {}, {}, 0, IntrinsicType::CHARACTER, 4);
- expectedMangledName = "_QYIcharacterK4";
- ASSERT_EQ(actual, expectedMangledName);
-
- actual = NameUniquer::doIntrinsicTypeDescriptor(
- {}, {}, 0, IntrinsicType::COMPLEX, 4);
- expectedMangledName = "_QYIcomplexK4";
- ASSERT_EQ(actual, expectedMangledName);
-}
+// TEST(InternalNamesTest, doIntrinsicTypeDescriptorTest) {
+// using IntrinsicType = fir::NameUniquer::IntrinsicType;
+// std::string actual = NameUniquer::doIntrinsicTypeDescriptor(
+// {}, {}, 0, IntrinsicType::REAL, 42);
+// std::string expectedMangledName = "_QYIrealK42";
+// ASSERT_EQ(actual, expectedMangledName);
+
+// actual = NameUniquer::doIntrinsicTypeDescriptor(
+// {}, {}, 0, IntrinsicType::REAL, {});
+// expectedMangledName = "_QYIrealK0";
+// ASSERT_EQ(actual, expectedMangledName);
+
+// actual = NameUniquer::doIntrinsicTypeDescriptor(
+// {}, {}, 0, IntrinsicType::INTEGER, 3);
+// expectedMangledName = "_QYIintegerK3";
+// ASSERT_EQ(actual, expectedMangledName);
+
+// actual = NameUniquer::doIntrinsicTypeDescriptor(
+// {}, {}, 0, IntrinsicType::LOGICAL, 2);
+// expectedMangledName = "_QYIlogicalK2";
+// ASSERT_EQ(actual, expectedMangledName);
+
+// actual = NameUniquer::doIntrinsicTypeDescriptor(
+// {}, {}, 0, IntrinsicType::CHARACTER, 4);
+// expectedMangledName = "_QYIcharacterK4";
+// ASSERT_EQ(actual, expectedMangledName);
+
+// actual = NameUniquer::doIntrinsicTypeDescriptor(
+// {}, {}, 0, IntrinsicType::COMPLEX, 4);
+// expectedMangledName = "_QYIcomplexK4";
+// ASSERT_EQ(actual, expectedMangledName);
+// }
TEST(InternalNamesTest, doDispatchTableTest) {
std::string actual =
diff --git a/flang/unittests/Runtime/CharacterTest.cpp b/flang/unittests/Runtime/CharacterTest.cpp
index e54fd8a5075f6..e9522fae9a2c8 100644
--- a/flang/unittests/Runtime/CharacterTest.cpp
+++ b/flang/unittests/Runtime/CharacterTest.cpp
@@ -199,32 +199,32 @@ struct CharacterComparisonTests : public ::testing::Test {
TYPED_TEST_SUITE(CharacterComparisonTests, CharacterTypes, );
-TYPED_TEST(CharacterComparisonTests, CompareCharacters) {
- for (auto &[x, y, xBytes, yBytes, expect] : this->parameters) {
- int cmp{this->characterComparisonFunc(x, y, xBytes, yBytes)};
- TypeParam buf[2][8];
- std::memset(buf, 0, sizeof buf);
- std::memcpy(buf[0], x, xBytes);
- std::memcpy(buf[1], y, yBytes);
- ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
- << y << "'(" << yBytes << "), got " << cmp
- << ", should be " << expect << '\n';
-
- // Perform the same test with the parameters reversed and the difference
- // negated
- std::swap(x, y);
- std::swap(xBytes, yBytes);
- expect = -expect;
-
- cmp = this->characterComparisonFunc(x, y, xBytes, yBytes);
- std::memset(buf, 0, sizeof buf);
- std::memcpy(buf[0], x, xBytes);
- std::memcpy(buf[1], y, yBytes);
- ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
- << y << "'(" << yBytes << "'), got " << cmp
- << ", should be " << expect << '\n';
- }
-}
+// TYPED_TEST(CharacterComparisonTests, CompareCharacters) {
+// for (auto &[x, y, xBytes, yBytes, expect] : this->parameters) {
+// int cmp{this->characterComparisonFunc(x, y, xBytes, yBytes)};
+// TypeParam buf[2][8];
+// std::memset(buf, 0, sizeof buf);
+// std::memcpy(buf[0], x, xBytes);
+// std::memcpy(buf[1], y, yBytes);
+// ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
+// << y << "'(" << yBytes << "), got " << cmp
+// << ", should be " << expect << '\n';
+
+// // Perform the same test with the parameters reversed and the difference
+// // negated
+// std::swap(x, y);
+// std::swap(xBytes, yBytes);
+// expect = -expect;
+
+// cmp = this->characterComparisonFunc(x, y, xBytes, yBytes);
+// std::memset(buf, 0, sizeof buf);
+// std::memcpy(buf[0], x, xBytes);
+// std::memcpy(buf[1], y, yBytes);
+// ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
+// << y << "'(" << yBytes << "'), got " << cmp
+// << ", should be " << expect << '\n';
+// }
+// }
// Test MIN() and MAX()
struct ExtremumTestCase {
@@ -275,14 +275,14 @@ TYPED_TEST(ExtremumTests, MinTests) {
RunExtremumTests<TypeParam>("MIN", RTNAME(CharacterMin), tests);
}
-TYPED_TEST(ExtremumTests, MaxTests) {
- static std::vector<ExtremumTestCase> tests{
- {{}, {"a"}, {"z"}, {"z"}},
- {{1}, {"zaa"}, {"aaaaa"}, {"zaa "}},
- {{1, 1, 1}, {"aaaaa"}, {"aazaa"}, {"aazaa"}},
- };
- RunExtremumTests<TypeParam>("MAX", RTNAME(CharacterMax), tests);
-}
+// TYPED_TEST(ExtremumTests, MaxTests) {
+// static std::vector<ExtremumTestCase> tests{
+// {{}, {"a"}, {"z"}, {"z"}},
+// {{1}, {"zaa"}, {"aaaaa"}, {"zaa "}},
+// {{1, 1, 1}, {"aaaaa"}, {"aazaa"}, {"aazaa"}},
+// };
+// RunExtremumTests<TypeParam>("MAX", RTNAME(CharacterMax), tests);
+// }
template <typename CHAR>
void RunAllocationTest(const char *xRaw, const char *yRaw) {
@@ -373,20 +373,20 @@ TYPED_TEST(SearchTests, ScanTests) {
RunSearchTests("SCAN", tests, std::get<SearchFunction<TypeParam>>(functions));
}
-TYPED_TEST(SearchTests, VerifyTests) {
- static SearchFunctions functions{
- RTNAME(Verify1), RTNAME(Verify2), RTNAME(Verify4)};
- static std::vector<SearchTestCase> tests{
- {"abc", "abc", false, 0},
- {"abc", "abc", true, 0},
- {"abc", "cde", false, 1},
- {"abc", "cde", true, 2},
- {"abc", "x", false, 1},
- {"", "x", false, 0},
- };
- RunSearchTests(
- "VERIFY", tests, std::get<SearchFunction<TypeParam>>(functions));
-}
+// TYPED_TEST(SearchTests, VerifyTests) {
+// static SearchFunctions functions{
+// RTNAME(Verify1), RTNAME(Verify2), RTNAME(Verify4)};
+// static std::vector<SearchTestCase> tests{
+// {"abc", "abc", false, 0},
+// {"abc", "abc", true, 0},
+// {"abc", "cde", false, 1},
+// {"abc", "cde", true, 2},
+// {"abc", "x", false, 1},
+// {"", "x", false, 0},
+// };
+// RunSearchTests(
+// "VERIFY", tests, std::get<SearchFunction<TypeParam>>(functions));
+// }
// Test REPEAT()
template <typename CHAR> struct RepeatTests : public ::testing::Test {};
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index 08daa4ba37f26..c67eb091d0b11 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -308,21 +308,21 @@ TEST_F(ZeroArguments, GetCommandArgument) {
TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }
-TEST_F(ZeroArguments, ECLValidCommandAndPadSync) {
- OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
- bool wait{true};
- OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
- OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor()};
- OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
-
- RTNAME(ExecuteCommandLine)
- (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
-
- std::string spaces(cmdMsg->ElementBytes(), ' ');
- CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 0);
- CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 0);
- CheckDescriptorEqStr(cmdMsg.get(), "No change");
-}
+// TEST_F(ZeroArguments, ECLValidCommandAndPadSync) {
+// OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
+// bool wait{true};
+// OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
+// OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor()};
+// OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
+
+// RTNAME(ExecuteCommandLine)
+// (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
+
+// std::string spaces(cmdMsg->ElementBytes(), ' ');
+// CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 0);
+// CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 0);
+// CheckDescriptorEqStr(cmdMsg.get(), "No change");
+// }
TEST_F(ZeroArguments, ECLValidCommandStatusSetSync) {
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
@@ -404,14 +404,14 @@ TEST_F(ZeroArguments, ECLInvalidCommandParentNotTerminatedAsync) {
CheckDescriptorEqStr(cmdMsg.get(), "No change");
}
-TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectSync) {
- OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
+// TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectSync) {
+// OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
- EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
- *command.get(), false, nullptr, nullptr, nullptr));
- EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
- *command.get(), true, nullptr, nullptr, nullptr));
-}
+// EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
+// *command.get(), false, nullptr, nullptr, nullptr));
+// EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
+// *command.get(), true, nullptr, nullptr, nullptr));
+// }
TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectAsync) {
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
@@ -560,18 +560,18 @@ TEST_F(SeveralArguments, GetCommand) {
CheckMissingCommandValue("Missing argument");
}
-TEST_F(SeveralArguments, CommandErrMsgTooShort) {
- OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()};
- OwningPtr<Descriptor> length{EmptyIntDescriptor()};
- OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()};
+// TEST_F(SeveralArguments, CommandErrMsgTooShort) {
+// OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()};
+// OwningPtr<Descriptor> length{EmptyIntDescriptor()};
+// OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()};
- EXPECT_GT(RTNAME(GetCommand)(value.get(), length.get(), errMsg.get()), 0);
+// EXPECT_GT(RTNAME(GetCommand)(value.get(), length.get(), errMsg.get()), 0);
- std::string spaces(value->ElementBytes(), ' ');
- CheckDescriptorEqStr(value.get(), spaces);
- CheckDescriptorEqInt<std::int64_t>(length.get(), 0);
- CheckDescriptorEqStr(errMsg.get(), "Mis");
-}
+// std::string spaces(value->ElementBytes(), ' ');
+// CheckDescriptorEqStr(value.get(), spaces);
+// CheckDescriptorEqInt<std::int64_t>(length.get(), 0);
+// CheckDescriptorEqStr(errMsg.get(), "Mis");
+// }
TEST_F(SeveralArguments, GetCommandCanTakeNull) {
EXPECT_GT(RTNAME(GetCommand)(nullptr, nullptr, nullptr), 0);
@@ -700,11 +700,11 @@ TEST_F(EnvironmentVariables, NoTrim) {
}
}
-TEST_F(EnvironmentVariables, Empty) {
- if (EnableFineGrainedTests()) {
- CheckEnvVarValue("", "EMPTY");
- }
-}
+// TEST_F(EnvironmentVariables, Empty) {
+// if (EnableFineGrainedTests()) {
+// CheckEnvVarValue("", "EMPTY");
+// }
+// }
TEST_F(EnvironmentVariables, NoValueOrErrmsg) {
ASSERT_EQ(std::getenv("DOESNT_EXIST"), nullptr)
diff --git a/flang/unittests/Runtime/Complex.cpp b/flang/unittests/Runtime/Complex.cpp
index 46f3ad2f2712b..f87b890c825d3 100644
--- a/flang/unittests/Runtime/Complex.cpp
+++ b/flang/unittests/Runtime/Complex.cpp
@@ -133,23 +133,23 @@ TEST(Complex, cpowk) {
cpowk(0.f + 1if, std::numeric_limits<std::int64_t>::min()), 1.f + 0if);
}
-TEST(Complex, zpowi) {
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 0), 1. + 0i);
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 1), 3. + 4i);
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 2), -7. + 24i);
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 3), -117. + 44i);
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 4), -527. - 336i);
-
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, -2), -0.0112 - 0.0384i);
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 10), -237. - 3116i);
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
-
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 5), -38. + 41i);
- EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
-
- EXPECT_COMPLEX_DOUBLE_EQ(
- zpowi(0. + 1i, std::numeric_limits<std::int32_t>::min()), 1. + 0i);
-}
+// TEST(Complex, zpowi) {
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 0), 1. + 0i);
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 1), 3. + 4i);
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 2), -7. + 24i);
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 3), -117. + 44i);
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 4), -527. - 336i);
+
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, -2), -0.0112 - 0.0384i);
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 10), -237. - 3116i);
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
+
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 5), -38. + 41i);
+// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
+
+// EXPECT_COMPLEX_DOUBLE_EQ(
+// zpowi(0. + 1i, std::numeric_limits<std::int32_t>::min()), 1. + 0i);
+// }
TEST(Complex, zpowk) {
EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 0), 1. + 0i);
diff --git a/flang/unittests/Runtime/ExternalIOTest.cpp b/flang/unittests/Runtime/ExternalIOTest.cpp
index 13327964e12a4..0f3da0784f9d4 100644
--- a/flang/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang/unittests/Runtime/ExternalIOTest.cpp
@@ -585,103 +585,103 @@ TEST(ExternalIOTests, TestNonAvancingInput) {
<< "EndIoStatement() for Close";
}
-TEST(ExternalIOTests, TestWriteAfterNonAvancingInput) {
- // OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
- // FORM='FORMATTED',STATUS='SCRATCH')
- auto *io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
- ASSERT_TRUE(IONAME(SetAccess)(io, "SEQUENTIAL", 10))
- << "SetAccess(SEQUENTIAL)";
- ASSERT_TRUE(IONAME(SetAction)(io, "READWRITE", 9)) << "SetAction(READWRITE)";
- ASSERT_TRUE(IONAME(SetForm)(io, "FORMATTED", 9)) << "SetForm(FORMATTED)";
- ASSERT_TRUE(IONAME(SetStatus)(io, "SCRATCH", 7)) << "SetStatus(SCRATCH)";
-
- int unit{-1};
- ASSERT_TRUE(IONAME(GetNewUnit)(io, unit)) << "GetNewUnit()";
- ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
- << "EndIoStatement() for OpenNewUnit";
-
- // Write the file to be used for the input test.
- static constexpr std::string_view records[] = {"ABCDEFGHIJKLMNOPQRST"};
- static constexpr std::string_view fmt{"(A)"};
- for (const auto &record : records) {
- // WRITE(UNIT=unit,FMT=fmt) record
- io = IONAME(BeginExternalFormattedOutput)(
- fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
- ASSERT_TRUE(IONAME(OutputAscii)(io, record.data(), record.length()))
- << "OutputAscii()";
- ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
- << "EndIoStatement() for OutputAscii";
- }
-
- // REWIND(UNIT=unit)
- io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
- ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
- << "EndIoStatement() for Rewind";
-
- struct TestItems {
- std::string item;
- int expectedIoStat;
- std::string expectedItemValue;
- };
- // Actual non advancing input IO test
- TestItems inputItems[]{
- {std::string(4, '+'), IostatOk, "ABCD"},
- {std::string(4, '+'), IostatOk, "EFGH"},
- };
-
- int j{0};
- for (auto &inputItem : inputItems) {
- // READ(UNIT=unit, FMT=fmt, ADVANCE='NO', IOSTAT=iostat) inputItem
- io = IONAME(BeginExternalFormattedInput)(
- fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
- IONAME(EnableHandlers)(io, true, false, false, false, false);
- ASSERT_TRUE(IONAME(SetAdvance)(io, "NO", 2)) << "SetAdvance(NO)" << j;
- ASSERT_TRUE(
- IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length()))
- << "InputAscii() " << j;
- ASSERT_EQ(IONAME(EndIoStatement)(io), inputItem.expectedIoStat)
- << "EndIoStatement() for Read " << j;
- ASSERT_EQ(inputItem.item, inputItem.expectedItemValue)
- << "Input-item value after non advancing read " << j;
- j++;
- }
-
- // WRITE(UNIT=unit, FMT=fmt, IOSTAT=iostat) outputItem.
- static constexpr std::string_view outputItem{"XYZ"};
- // WRITE(UNIT=unit,FMT=fmt) record
- io = IONAME(BeginExternalFormattedOutput)(
- fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
- ASSERT_TRUE(IONAME(OutputAscii)(io, outputItem.data(), outputItem.length()))
- << "OutputAscii()";
- ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
- << "EndIoStatement() for OutputAscii";
-
- // Verify that the output was written in the record read in non advancing
- // mode, after the read part, and that the end was truncated.
-
- // REWIND(UNIT=unit)
- io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
- ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
- << "EndIoStatement() for Rewind";
-
- std::string resultRecord(20, '+');
- std::string expectedRecord{"ABCDEFGHXYZ "};
- // READ(UNIT=unit, FMT=fmt, IOSTAT=iostat) result
- io = IONAME(BeginExternalFormattedInput)(
- fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
- IONAME(EnableHandlers)(io, true, false, false, false, false);
- ASSERT_TRUE(
- IONAME(InputAscii)(io, resultRecord.data(), resultRecord.length()))
- << "InputAscii() ";
- ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
- << "EndIoStatement() for Read ";
- ASSERT_EQ(resultRecord, expectedRecord)
- << "Record after non advancing read followed by write";
- // CLOSE(UNIT=unit)
- io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
- ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
- << "EndIoStatement() for Close";
-}
+// TEST(ExternalIOTests, TestWriteAfterNonAvancingInput) {
+// // OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
+// // FORM='FORMATTED',STATUS='SCRATCH')
+// auto *io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
+// ASSERT_TRUE(IONAME(SetAccess)(io, "SEQUENTIAL", 10))
+// << "SetAccess(SEQUENTIAL)";
+// ASSERT_TRUE(IONAME(SetAction)(io, "READWRITE", 9)) << "SetAction(READWRITE)";
+// ASSERT_TRUE(IONAME(SetForm)(io, "FORMATTED", 9)) << "SetForm(FORMATTED)";
+// ASSERT_TRUE(IONAME(SetStatus)(io, "SCRATCH", 7)) << "SetStatus(SCRATCH)";
+
+// int unit{-1};
+// ASSERT_TRUE(IONAME(GetNewUnit)(io, unit)) << "GetNewUnit()";
+// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+// << "EndIoStatement() for OpenNewUnit";
+
+// // Write the file to be used for the input test.
+// static constexpr std::string_view records[] = {"ABCDEFGHIJKLMNOPQRST"};
+// static constexpr std::string_view fmt{"(A)"};
+// for (const auto &record : records) {
+// // WRITE(UNIT=unit,FMT=fmt) record
+// io = IONAME(BeginExternalFormattedOutput)(
+// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+// ASSERT_TRUE(IONAME(OutputAscii)(io, record.data(), record.length()))
+// << "OutputAscii()";
+// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+// << "EndIoStatement() for OutputAscii";
+// }
+
+// // REWIND(UNIT=unit)
+// io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
+// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+// << "EndIoStatement() for Rewind";
+
+// struct TestItems {
+// std::string item;
+// int expectedIoStat;
+// std::string expectedItemValue;
+// };
+// // Actual non advancing input IO test
+// TestItems inputItems[]{
+// {std::string(4, '+'), IostatOk, "ABCD"},
+// {std::string(4, '+'), IostatOk, "EFGH"},
+// };
+
+// int j{0};
+// for (auto &inputItem : inputItems) {
+// // READ(UNIT=unit, FMT=fmt, ADVANCE='NO', IOSTAT=iostat) inputItem
+// io = IONAME(BeginExternalFormattedInput)(
+// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+// IONAME(EnableHandlers)(io, true, false, false, false, false);
+// ASSERT_TRUE(IONAME(SetAdvance)(io, "NO", 2)) << "SetAdvance(NO)" << j;
+// ASSERT_TRUE(
+// IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length()))
+// << "InputAscii() " << j;
+// ASSERT_EQ(IONAME(EndIoStatement)(io), inputItem.expectedIoStat)
+// << "EndIoStatement() for Read " << j;
+// ASSERT_EQ(inputItem.item, inputItem.expectedItemValue)
+// << "Input-item value after non advancing read " << j;
+// j++;
+// }
+
+// // WRITE(UNIT=unit, FMT=fmt, IOSTAT=iostat) outputItem.
+// static constexpr std::string_view outputItem{"XYZ"};
+// // WRITE(UNIT=unit,FMT=fmt) record
+// io = IONAME(BeginExternalFormattedOutput)(
+// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+// ASSERT_TRUE(IONAME(OutputAscii)(io, outputItem.data(), outputItem.length()))
+// << "OutputAscii()";
+// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+// << "EndIoStatement() for OutputAscii";
+
+// // Verify that the output was written in the record read in non advancing
+// // mode, after the read part, and that the end was truncated.
+
+// // REWIND(UNIT=unit)
+// io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
+// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+// << "EndIoStatement() for Rewind";
+
+// std::string resultRecord(20, '+');
+// std::string expectedRecord{"ABCDEFGHXYZ "};
+// // READ(UNIT=unit, FMT=fmt, IOSTAT=iostat) result
+// io = IONAME(BeginExternalFormattedInput)(
+// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+// IONAME(EnableHandlers)(io, true, false, false, false, false);
+// ASSERT_TRUE(
+// IONAME(InputAscii)(io, resultRecord.data(), resultRecord.length()))
+// << "InputAscii() ";
+// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+// << "EndIoStatement() for Read ";
+// ASSERT_EQ(resultRecord, expectedRecord)
+// << "Record after non advancing read followed by write";
+// // CLOSE(UNIT=unit)
+// io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
+// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+// << "EndIoStatement() for Close";
+// }
TEST(ExternalIOTests, TestWriteAfterEndfile) {
// OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
diff --git a/flang/unittests/Runtime/Format.cpp b/flang/unittests/Runtime/Format.cpp
index 01803c628de26..cdcdc19aff54a 100644
--- a/flang/unittests/Runtime/Format.cpp
+++ b/flang/unittests/Runtime/Format.cpp
@@ -145,18 +145,18 @@ TEST(FormatTests, FormatStringTraversal) {
struct InvalidFormatFailure : CrashHandlerFixture {};
-TEST(InvalidFormatFailure, ParenMismatch) {
- static constexpr const char *format{"("};
- static constexpr int repeat{1};
-
- TestFormatContext context;
- FormatControl<decltype(context)> control{
- context, format, std::strlen(format)};
-
- ASSERT_DEATH(
- context.Report(/*edit=*/control.GetNextDataEdit(context, repeat)),
- R"(FORMAT missing at least one '\)')");
-}
+// TEST(InvalidFormatFailure, ParenMismatch) {
+// static constexpr const char *format{"("};
+// static constexpr int repeat{1};
+
+// TestFormatContext context;
+// FormatControl<decltype(context)> control{
+// context, format, std::strlen(format)};
+
+// ASSERT_DEATH(
+// context.Report(/*edit=*/control.GetNextDataEdit(context, repeat)),
+// R"(FORMAT missing at least one '\)')");
+// }
TEST(InvalidFormatFailure, MissingPrecision) {
static constexpr const char *format{"(F9.)"};
diff --git a/flang/unittests/Runtime/ListInputTest.cpp b/flang/unittests/Runtime/ListInputTest.cpp
index a4eba5283add6..c53a10a0af640 100644
--- a/flang/unittests/Runtime/ListInputTest.cpp
+++ b/flang/unittests/Runtime/ListInputTest.cpp
@@ -155,35 +155,35 @@ using ParamTy = std::tuple<std::string, std::vector<int>>;
struct SimpleListInputTest : testing::TestWithParam<ParamTy> {};
-TEST_P(SimpleListInputTest, TestListInput) {
- auto [formatBuffer, expectedOutput] = GetParam();
- constexpr int numBuffers{1};
-
- StaticDescriptor<1> staticDescriptor;
- Descriptor &whole{staticDescriptor.descriptor()};
- SubscriptValue extent[]{numBuffers};
- whole.Establish(TypeCode{CFI_type_char}, formatBuffer.size(),
- formatBuffer.data(), 1, extent, CFI_attribute_pointer);
- whole.Check();
- auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
-
- const auto listInputLength{expectedOutput.size()};
- std::vector<std::int64_t> actualOutput(listInputLength);
- for (std::size_t j = 0; j < listInputLength; ++j) {
- IONAME(InputInteger)(cookie, actualOutput[j]);
- }
-
- const auto status{IONAME(EndIoStatement)(cookie)};
- ASSERT_EQ(status, 0) << "list-directed input failed, status "
- << static_cast<int>(status) << '\n';
-
- // Verify the calls to _InputInteger_ resulted in _expectedOutput_
- for (std::size_t j = 0; j < listInputLength; ++j) {
- ASSERT_EQ(actualOutput[j], expectedOutput[j])
- << "wanted actualOutput[" << j << "]==" << expectedOutput[j] << ", got "
- << actualOutput[j] << '\n';
- }
-}
+// TEST_P(SimpleListInputTest, TestListInput) {
+// auto [formatBuffer, expectedOutput] = GetParam();
+// constexpr int numBuffers{1};
+
+// StaticDescriptor<1> staticDescriptor;
+// Descriptor &whole{staticDescriptor.descriptor()};
+// SubscriptValue extent[]{numBuffers};
+// whole.Establish(TypeCode{CFI_type_char}, formatBuffer.size(),
+// formatBuffer.data(), 1, extent, CFI_attribute_pointer);
+// whole.Check();
+// auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
+
+// const auto listInputLength{expectedOutput.size()};
+// std::vector<std::int64_t> actualOutput(listInputLength);
+// for (std::size_t j = 0; j < listInputLength; ++j) {
+// IONAME(InputInteger)(cookie, actualOutput[j]);
+// }
+
+// const auto status{IONAME(EndIoStatement)(cookie)};
+// ASSERT_EQ(status, 0) << "list-directed input failed, status "
+// << static_cast<int>(status) << '\n';
+
+// // Verify the calls to _InputInteger_ resulted in _expectedOutput_
+// for (std::size_t j = 0; j < listInputLength; ++j) {
+// ASSERT_EQ(actualOutput[j], expectedOutput[j])
+// << "wanted actualOutput[" << j << "]==" << expectedOutput[j] << ", got "
+// << actualOutput[j] << '\n';
+// }
+// }
INSTANTIATE_TEST_SUITE_P(SimpleListInputTestInstantiation, SimpleListInputTest,
testing::Values(std::make_tuple("", std::vector<int>{}),
diff --git a/flang/unittests/Runtime/MiscIntrinsic.cpp b/flang/unittests/Runtime/MiscIntrinsic.cpp
index 7e19ed250bdc0..6dff30a5c1efc 100644
--- a/flang/unittests/Runtime/MiscIntrinsic.cpp
+++ b/flang/unittests/Runtime/MiscIntrinsic.cpp
@@ -68,21 +68,21 @@ TEST(MiscIntrinsic, TransferSize) {
EXPECT_EQ(result.OffsetElement<float>()[1], 2.2F);
result.Destroy();
}
-TEST(MiscIntrinsic, TransferSizeScalarMold) {
- StaticDescriptor<2, true, 2> staticDesc[2];
- auto &result{staticDesc[0].descriptor()};
- std::complex<float> sourecStorage{1.1F, -2.2F};
- auto source{Descriptor::Create(TypeCategory::Complex, 4,
- reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
- CFI_attribute_pointer)};
- auto &mold{staticDesc[1].descriptor()};
- mold.Establish(TypeCategory::Real, 4, nullptr, 0, nullptr);
- RTNAME(TransferSize)(result, *source, mold, __FILE__, __LINE__, 2);
- EXPECT_EQ(result.rank(), 1);
- EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
- EXPECT_EQ(result.GetDimension(0).Extent(), 2);
- EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Real, 4}.raw()));
- EXPECT_EQ(result.OffsetElement<float>()[0], 1.1F);
- EXPECT_EQ(result.OffsetElement<float>()[1], -2.2F);
- result.Destroy();
-}
+// TEST(MiscIntrinsic, TransferSizeScalarMold) {
+// StaticDescriptor<2, true, 2> staticDesc[2];
+// auto &result{staticDesc[0].descriptor()};
+// std::complex<float> sourecStorage{1.1F, -2.2F};
+// auto source{Descriptor::Create(TypeCategory::Complex, 4,
+// reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
+// CFI_attribute_pointer)};
+// auto &mold{staticDesc[1].descriptor()};
+// mold.Establish(TypeCategory::Real, 4, nullptr, 0, nullptr);
+// RTNAME(TransferSize)(result, *source, mold, __FILE__, __LINE__, 2);
+// EXPECT_EQ(result.rank(), 1);
+// EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
+// EXPECT_EQ(result.GetDimension(0).Extent(), 2);
+// EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Real, 4}.raw()));
+// EXPECT_EQ(result.OffsetElement<float>()[0], 1.1F);
+// EXPECT_EQ(result.OffsetElement<float>()[1], -2.2F);
+// result.Destroy();
+// }
diff --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp
index b69ff21ea79fb..98ec88abf9a93 100644
--- a/flang/unittests/Runtime/Numeric.cpp
+++ b/flang/unittests/Runtime/Numeric.cpp
@@ -31,15 +31,15 @@ TEST(Numeric, Floor) {
EXPECT_EQ(RTNAME(Floor4_1)(Real<4>{0}), 0);
}
-TEST(Numeric, Exponent) {
- EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
- EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
- EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3);
- EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()),
- std::numeric_limits<Int<8>>::max());
- EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()),
- std::numeric_limits<Int<8>>::max());
-}
+// TEST(Numeric, Exponent) {
+// EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
+// EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
+// EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3);
+// EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()),
+// std::numeric_limits<Int<8>>::max());
+// EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()),
+// std::numeric_limits<Int<8>>::max());
+// }
TEST(Numeric, Fraction) {
EXPECT_EQ(RTNAME(Fraction4)(Real<4>{0}), 0);
@@ -192,57 +192,57 @@ TEST(Numeric, SelectedIntKind) {
EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r5, 4), -1);
}
-TEST(Numeric, SelectedRealKind) {
- std::int8_t p_s = 1;
- std::int16_t p[11] = {-10, 1, 1, 4, 50, 1, 1, 4, 1, 1, 50};
- std::int32_t r[11] = {-1, 1, 1, 1, 2, 1, 20, 20, 100, 5000, 5000};
- std::int64_t d[11] = {2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2};
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[0], 2, &r[0], 4, &d[0], 8),
- 2);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[1], 2, &r[1], 4, &d[1], 8),
- -5);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[2], 2, &r[2], 4, &d[2], 8),
- 2);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[3], 2, &r[3], 4, &d[3], 8),
- 4);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[4], 2, &r[4], 4, &d[4], 8),
- -1);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[5], 2, &r[5], 4, &d[5], 8),
- 2);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[6], 2, &r[6], 4, &d[6], 8),
- 3);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[7], 2, &r[7], 4, &d[7], 8),
- 4);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[8], 2, &r[8], 4, &d[8], 8),
- 8);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[9], 2, &r[9], 4, &d[9], 8),
- -2);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[10], 2, &r[10], 4, &d[10], 8),
- -3);
- EXPECT_EQ(
- RTNAME(SelectedRealKind)(__FILE__, __LINE__, &p_s, 1, &r[0], 4, &d[0], 8),
- 2);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, nullptr, 0, &r[0], 4, &d[0], 8),
- 2);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[0], 2, nullptr, 0, &d[0], 8),
- 2);
- EXPECT_EQ(RTNAME(SelectedRealKind)(
- __FILE__, __LINE__, &p[0], 2, &r[0], 4, nullptr, 0),
- 2);
-}
+// TEST(Numeric, SelectedRealKind) {
+// std::int8_t p_s = 1;
+// std::int16_t p[11] = {-10, 1, 1, 4, 50, 1, 1, 4, 1, 1, 50};
+// std::int32_t r[11] = {-1, 1, 1, 1, 2, 1, 20, 20, 100, 5000, 5000};
+// std::int64_t d[11] = {2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2};
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[0], 2, &r[0], 4, &d[0], 8),
+// 2);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[1], 2, &r[1], 4, &d[1], 8),
+// -5);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[2], 2, &r[2], 4, &d[2], 8),
+// 2);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[3], 2, &r[3], 4, &d[3], 8),
+// 4);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[4], 2, &r[4], 4, &d[4], 8),
+// -1);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[5], 2, &r[5], 4, &d[5], 8),
+// 2);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[6], 2, &r[6], 4, &d[6], 8),
+// 3);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[7], 2, &r[7], 4, &d[7], 8),
+// 4);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[8], 2, &r[8], 4, &d[8], 8),
+// 8);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[9], 2, &r[9], 4, &d[9], 8),
+// -2);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[10], 2, &r[10], 4, &d[10], 8),
+// -3);
+// EXPECT_EQ(
+// RTNAME(SelectedRealKind)(__FILE__, __LINE__, &p_s, 1, &r[0], 4, &d[0], 8),
+// 2);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, nullptr, 0, &r[0], 4, &d[0], 8),
+// 2);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[0], 2, nullptr, 0, &d[0], 8),
+// 2);
+// EXPECT_EQ(RTNAME(SelectedRealKind)(
+// __FILE__, __LINE__, &p[0], 2, &r[0], 4, nullptr, 0),
+// 2);
+// }
TEST(Numeric, Spacing) {
EXPECT_EQ(RTNAME(Spacing8)(Real<8>{0}), std::numeric_limits<Real<8>>::min());
diff --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index 2a9f8f8d1dc4f..d480e41268b6b 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -336,21 +336,21 @@ TEST(IOApiTests, FormatOnes) {
}
}
-TEST(IOApiTests, FormatNegativeOnes) {
- static constexpr std::tuple<const char *, const char *> negOnes[]{
- {"(E32.17,';')", " -0.10000000000000000E+01;"},
- {"(F32.17,';')", " -1.00000000000000000;"},
- {"(G32.17,';')", " -1.0000000000000000 ;"},
- {"(EX32.17,';')", " -0X8.00000000000000000P-3;"},
- {"(G0,';')", "-1.;"},
- };
- for (auto const &[format, expect] : negOnes) {
- std::string got;
- ASSERT_TRUE(CompareFormatReal(format, -1.0, expect, got))
- << "Failed to format " << format << ", expected '" << expect
- << "', got '" << got << "'";
- }
-}
+// TEST(IOApiTests, FormatNegativeOnes) {
+// static constexpr std::tuple<const char *, const char *> negOnes[]{
+// {"(E32.17,';')", " -0.10000000000000000E+01;"},
+// {"(F32.17,';')", " -1.00000000000000000;"},
+// {"(G32.17,';')", " -1.0000000000000000 ;"},
+// {"(EX32.17,';')", " -0X8.00000000000000000P-3;"},
+// {"(G0,';')", "-1.;"},
+// };
+// for (auto const &[format, expect] : negOnes) {
+// std::string got;
+// ASSERT_TRUE(CompareFormatReal(format, -1.0, expect, got))
+// << "Failed to format " << format << ", expected '" << expect
+// << "', got '" << got << "'";
+// }
+// }
// Each test case contains a raw uint64, a format string for a real value, and
// the expected resulting string from formatting the raw uint64. The double
diff --git a/flang/unittests/Runtime/Pointer.cpp b/flang/unittests/Runtime/Pointer.cpp
index 4ce13ebc50a56..30edf82fbcf13 100644
--- a/flang/unittests/Runtime/Pointer.cpp
+++ b/flang/unittests/Runtime/Pointer.cpp
@@ -64,25 +64,25 @@ TEST(Pointer, DeallocatePolymorphic) {
(*p, nullptr, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__);
}
-TEST(Pointer, AllocateFromScalarSource) {
- // REAL(4), POINTER :: p(:)
- auto p{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4}, 4,
- nullptr, 1, nullptr, CFI_attribute_pointer)};
- // ALLOCATE(p(2:11), SOURCE=3.4)
- float sourecStorage{3.4F};
- auto s{Descriptor::Create(Fortran::common::TypeCategory::Real, 4,
- reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
- CFI_attribute_pointer)};
- RTNAME(PointerSetBounds)(*p, 0, 2, 11);
- RTNAME(PointerAllocateSource)
- (*p, *s, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__);
- EXPECT_TRUE(RTNAME(PointerIsAssociated)(*p));
- EXPECT_EQ(p->Elements(), 10u);
- EXPECT_EQ(p->GetDimension(0).LowerBound(), 2);
- EXPECT_EQ(p->GetDimension(0).UpperBound(), 11);
- EXPECT_EQ(*p->OffsetElement<float>(), 3.4F);
- p->Destroy();
-}
+// TEST(Pointer, AllocateFromScalarSource) {
+// // REAL(4), POINTER :: p(:)
+// auto p{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4}, 4,
+// nullptr, 1, nullptr, CFI_attribute_pointer)};
+// // ALLOCATE(p(2:11), SOURCE=3.4)
+// float sourecStorage{3.4F};
+// auto s{Descriptor::Create(Fortran::common::TypeCategory::Real, 4,
+// reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
+// CFI_attribute_pointer)};
+// RTNAME(PointerSetBounds)(*p, 0, 2, 11);
+// RTNAME(PointerAllocateSource)
+// (*p, *s, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__);
+// EXPECT_TRUE(RTNAME(PointerIsAssociated)(*p));
+// EXPECT_EQ(p->Elements(), 10u);
+// EXPECT_EQ(p->GetDimension(0).LowerBound(), 2);
+// EXPECT_EQ(p->GetDimension(0).UpperBound(), 11);
+// EXPECT_EQ(*p->OffsetElement<float>(), 3.4F);
+// p->Destroy();
+// }
TEST(Pointer, AllocateSourceZeroSize) {
using Fortran::common::TypeCategory;
diff --git a/flang/unittests/Runtime/RuntimeCrashTest.cpp b/flang/unittests/Runtime/RuntimeCrashTest.cpp
index a649051fdca0c..0753f76f23cc3 100644
--- a/flang/unittests/Runtime/RuntimeCrashTest.cpp
+++ b/flang/unittests/Runtime/RuntimeCrashTest.cpp
@@ -53,15 +53,15 @@ TEST(TestTerminator, CheckFailedTest) {
//------------------------------------------------------------------------------
struct TestIOCrash : CrashHandlerFixture {};
-TEST(TestIOCrash, InvalidFormatCharacterTest) {
- static constexpr int bufferSize{1};
- static char buffer[bufferSize];
- static const char *format{"(C1)"};
- auto *cookie{IONAME(BeginInternalFormattedOutput)(
- buffer, bufferSize, format, std::strlen(format))};
- ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xfeedface),
- "Unknown 'C' edit descriptor in FORMAT");
-}
+// TEST(TestIOCrash, InvalidFormatCharacterTest) {
+// static constexpr int bufferSize{1};
+// static char buffer[bufferSize];
+// static const char *format{"(C1)"};
+// auto *cookie{IONAME(BeginInternalFormattedOutput)(
+// buffer, bufferSize, format, std::strlen(format))};
+// ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xfeedface),
+// "Unknown 'C' edit descriptor in FORMAT");
+// }
//------------------------------------------------------------------------------
/// Test buffer overwrites with Output* functions
diff --git a/flang/unittests/Runtime/Stop.cpp b/flang/unittests/Runtime/Stop.cpp
index b13602eaee5ea..24c78251ea697 100644
--- a/flang/unittests/Runtime/Stop.cpp
+++ b/flang/unittests/Runtime/Stop.cpp
@@ -32,24 +32,24 @@ TEST(TestProgramEnd, StopTestNoStopMessage) {
RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS), "");
}
-TEST(TestProgramEnd, StopMessageTest) {
- static const char *message{"bye bye"};
- EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
- /*isErrorStop=*/false, /*quiet=*/false),
- testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye");
-
- EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
- /*isErrorStop=*/false, /*quiet=*/true),
- testing::ExitedWithCode(EXIT_SUCCESS), "");
-
- EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
- /*isErrorStop=*/true, /*quiet=*/false),
- testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
-
- EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
- /*isErrorStop=*/true, /*quiet=*/true),
- testing::ExitedWithCode(EXIT_FAILURE), "");
-}
+// TEST(TestProgramEnd, StopMessageTest) {
+// static const char *message{"bye bye"};
+// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+// /*isErrorStop=*/false, /*quiet=*/false),
+// testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye");
+
+// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+// /*isErrorStop=*/false, /*quiet=*/true),
+// testing::ExitedWithCode(EXIT_SUCCESS), "");
+
+// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+// /*isErrorStop=*/true, /*quiet=*/false),
+// testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
+
+// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+// /*isErrorStop=*/true, /*quiet=*/true),
+// testing::ExitedWithCode(EXIT_FAILURE), "");
+// }
TEST(TestProgramEnd, NoStopMessageTest) {
putenv(const_cast<char *>("NO_STOP_MESSAGE=1"));
diff --git a/flang/unittests/Runtime/TemporaryStack.cpp b/flang/unittests/Runtime/TemporaryStack.cpp
index 0a9344969ca6b..8b9aac99309ad 100644
--- a/flang/unittests/Runtime/TemporaryStack.cpp
+++ b/flang/unittests/Runtime/TemporaryStack.cpp
@@ -87,86 +87,86 @@ static unsigned max(unsigned x, unsigned y) {
return y;
}
-TEST(TemporaryStack, ValueStackMultiSize) {
- constexpr unsigned numToTest = 42;
- const TypeCode code{CFI_type_int32_t};
- constexpr size_t elementBytes = 4;
- SubscriptValue extent[CFI_MAX_RANK];
-
- std::vector<OwningPtr<Descriptor>> inputDescriptors;
- inputDescriptors.reserve(numToTest);
-
- void *storage = RTNAME(CreateValueStack)(__FILE__, __LINE__);
- ASSERT_NE(storage, nullptr);
-
- // create descriptors with and without adendums
- auto getAdendum = [](unsigned i) { return i % 2; };
- // create descriptors with varying ranks
- auto getRank = [](unsigned i) { return max(i % 8, 1); };
-
- // push descriptors of varying sizes and contents
- for (unsigned i = 0; i < numToTest; ++i) {
- const bool adendum = getAdendum(i);
- const size_t rank = getRank(i);
- for (unsigned dim = 0; dim < rank; ++dim) {
- extent[dim] = ((i + dim) % 8) + 1;
- }
-
- const OwningPtr<Descriptor> &desc =
- inputDescriptors.emplace_back(Descriptor::Create(code, elementBytes,
- nullptr, rank, extent, CFI_attribute_allocatable, adendum));
-
- // Descriptor::Establish doesn't initialise the extents if baseaddr is null
- for (unsigned dim = 0; dim < rank; ++dim) {
- Fortran::ISO::CFI_dim_t &boxDims = desc->raw().dim[dim];
- boxDims.lower_bound = 1;
- boxDims.extent = extent[dim];
- boxDims.sm = elementBytes;
- }
- desc->Allocate();
-
- // fill the array with some data to test
- for (uint32_t i = 0; i < desc->Elements(); ++i) {
- uint32_t *data = static_cast<uint32_t *>(desc->raw().base_addr);
- ASSERT_NE(data, nullptr);
- data[i] = i;
- }
-
- RTNAME(PushValue)(storage, *desc.get());
- }
-
- const TypeCode boolCode{CFI_type_Bool};
- // peek and test each descriptor
- for (unsigned i = 0; i < numToTest; ++i) {
- const OwningPtr<Descriptor> &input = inputDescriptors[i];
- const bool adendum = getAdendum(i);
- const size_t rank = getRank(i);
-
- // buffer to return the descriptor into
- OwningPtr<Descriptor> out = Descriptor::Create(
- boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
-
- (void)input;
- RTNAME(ValueAt)(storage, i, *out.get());
- descriptorAlmostEqual(*input, *out);
- }
-
- // pop and test each descriptor
- for (unsigned i = numToTest; i > 0; --i) {
- const OwningPtr<Descriptor> &input = inputDescriptors[i - 1];
- const bool adendum = getAdendum(i - 1);
- const size_t rank = getRank(i - 1);
-
- // buffer to return the descriptor into
- OwningPtr<Descriptor> out = Descriptor::Create(
- boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
-
- RTNAME(PopValue)(storage, *out.get());
- descriptorAlmostEqual(*input, *out);
- }
-
- RTNAME(DestroyValueStack)(storage);
-}
+// TEST(TemporaryStack, ValueStackMultiSize) {
+// constexpr unsigned numToTest = 42;
+// const TypeCode code{CFI_type_int32_t};
+// constexpr size_t elementBytes = 4;
+// SubscriptValue extent[CFI_MAX_RANK];
+
+// std::vector<OwningPtr<Descriptor>> inputDescriptors;
+// inputDescriptors.reserve(numToTest);
+
+// void *storage = RTNAME(CreateValueStack)(__FILE__, __LINE__);
+// ASSERT_NE(storage, nullptr);
+
+// // create descriptors with and without adendums
+// auto getAdendum = [](unsigned i) { return i % 2; };
+// // create descriptors with varying ranks
+// auto getRank = [](unsigned i) { return max(i % 8, 1); };
+
+// // push descriptors of varying sizes and contents
+// for (unsigned i = 0; i < numToTest; ++i) {
+// const bool adendum = getAdendum(i);
+// const size_t rank = getRank(i);
+// for (unsigned dim = 0; dim < rank; ++dim) {
+// extent[dim] = ((i + dim) % 8) + 1;
+// }
+
+// const OwningPtr<Descriptor> &desc =
+// inputDescriptors.emplace_back(Descriptor::Create(code, elementBytes,
+// nullptr, rank, extent, CFI_attribute_allocatable, adendum));
+
+// // Descriptor::Establish doesn't initialise the extents if baseaddr is null
+// for (unsigned dim = 0; dim < rank; ++dim) {
+// Fortran::ISO::CFI_dim_t &boxDims = desc->raw().dim[dim];
+// boxDims.lower_bound = 1;
+// boxDims.extent = extent[dim];
+// boxDims.sm = elementBytes;
+// }
+// desc->Allocate();
+
+// // fill the array with some data to test
+// for (uint32_t i = 0; i < desc->Elements(); ++i) {
+// uint32_t *data = static_cast<uint32_t *>(desc->raw().base_addr);
+// ASSERT_NE(data, nullptr);
+// data[i] = i;
+// }
+
+// RTNAME(PushValue)(storage, *desc.get());
+// }
+
+// const TypeCode boolCode{CFI_type_Bool};
+// // peek and test each descriptor
+// for (unsigned i = 0; i < numToTest; ++i) {
+// const OwningPtr<Descriptor> &input = inputDescriptors[i];
+// const bool adendum = getAdendum(i);
+// const size_t rank = getRank(i);
+
+// // buffer to return the descriptor into
+// OwningPtr<Descriptor> out = Descriptor::Create(
+// boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
+
+// (void)input;
+// RTNAME(ValueAt)(storage, i, *out.get());
+// descriptorAlmostEqual(*input, *out);
+// }
+
+// // pop and test each descriptor
+// for (unsigned i = numToTest; i > 0; --i) {
+// const OwningPtr<Descriptor> &input = inputDescriptors[i - 1];
+// const bool adendum = getAdendum(i - 1);
+// const size_t rank = getRank(i - 1);
+
+// // buffer to return the descriptor into
+// OwningPtr<Descriptor> out = Descriptor::Create(
+// boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
+
+// RTNAME(PopValue)(storage, *out.get());
+// descriptorAlmostEqual(*input, *out);
+// }
+
+// RTNAME(DestroyValueStack)(storage);
+// }
TEST(TemporaryStack, DescriptorStackBasic) {
const TypeCode code{CFI_type_Bool};
>From f2f96df7d753138c47c34096603f7e10d9484cb4 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 22:24:32 +0300
Subject: [PATCH 09/30] Limit CI down to flang
---
.ci/generate-buildkite-pipeline-premerge | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge
index 78a9cb77ff7d9..e36b91e6bf066 100755
--- a/.ci/generate-buildkite-pipeline-premerge
+++ b/.ci/generate-buildkite-pipeline-premerge
@@ -147,6 +147,11 @@ function exclude-windows() {
libc) ;; # no Windows support
lldb) ;; # tests failing
bolt) ;; # tests are not supported yet
+ clang) ;;
+ llvm) ;;
+ clang-tools-extra) ;;
+ lld) ;;
+ polly) ;;
*)
echo "${project}"
;;
@@ -187,6 +192,9 @@ function check-targets() {
libclc)
echo "check-all"
;;
+ mlir);;
+ clang);;
+ llvm);;
*)
echo "check-${project}"
;;
>From 3110b74e1c8237a079139f6edb3038ac113889a3 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 22:36:48 +0300
Subject: [PATCH 10/30] Revert "Disable a bunch of flang tests"
This reverts commit 1c785a63d029dc55fc06ec236e55983729767e2f.
---
.../Optimizer/Builder/ComplexTest.cpp | 44 ++--
.../Optimizer/Builder/DoLoopHelperTest.cpp | 30 +--
.../Optimizer/Builder/FIRBuilderTest.cpp | 12 +-
.../Optimizer/Builder/HLFIRToolsTest.cpp | 64 +++---
.../Builder/Runtime/CharacterTest.cpp | 22 +-
.../Optimizer/Builder/Runtime/CommandTest.cpp | 12 +-
.../Builder/Runtime/ReductionTest.cpp | 42 ++--
flang/unittests/Optimizer/FIRTypesTest.cpp | 54 ++---
.../Optimizer/FortranVariableTest.cpp | 44 ++--
.../unittests/Optimizer/InternalNamesTest.cpp | 64 +++---
flang/unittests/Runtime/CharacterTest.cpp | 96 ++++-----
flang/unittests/Runtime/CommandTest.cpp | 74 +++----
flang/unittests/Runtime/Complex.cpp | 34 +--
flang/unittests/Runtime/ExternalIOTest.cpp | 194 +++++++++---------
flang/unittests/Runtime/Format.cpp | 24 +--
flang/unittests/Runtime/ListInputTest.cpp | 58 +++---
flang/unittests/Runtime/MiscIntrinsic.cpp | 36 ++--
flang/unittests/Runtime/Numeric.cpp | 120 +++++------
.../unittests/Runtime/NumericalFormatTest.cpp | 30 +--
flang/unittests/Runtime/Pointer.cpp | 38 ++--
flang/unittests/Runtime/RuntimeCrashTest.cpp | 18 +-
flang/unittests/Runtime/Stop.cpp | 36 ++--
flang/unittests/Runtime/TemporaryStack.cpp | 160 +++++++--------
23 files changed, 653 insertions(+), 653 deletions(-)
diff --git a/flang/unittests/Optimizer/Builder/ComplexTest.cpp b/flang/unittests/Optimizer/Builder/ComplexTest.cpp
index b17ef9ef2f348..17171512470ac 100644
--- a/flang/unittests/Optimizer/Builder/ComplexTest.cpp
+++ b/flang/unittests/Optimizer/Builder/ComplexTest.cpp
@@ -62,30 +62,30 @@ struct ComplexTest : public testing::Test {
mlir::Value rFour;
};
-// TEST_F(ComplexTest, verifyTypes) {
-// mlir::Value cVal1 = helper->createComplex(complexTy1, rOne, rTwo);
-// mlir::Value cVal2 = helper->createComplex(4, rOne, rTwo);
-// EXPECT_TRUE(fir::isa_complex(cVal1.getType()));
-// EXPECT_TRUE(fir::isa_complex(cVal2.getType()));
-// EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal1)));
-// EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal2)));
+TEST_F(ComplexTest, verifyTypes) {
+ mlir::Value cVal1 = helper->createComplex(complexTy1, rOne, rTwo);
+ mlir::Value cVal2 = helper->createComplex(4, rOne, rTwo);
+ EXPECT_TRUE(fir::isa_complex(cVal1.getType()));
+ EXPECT_TRUE(fir::isa_complex(cVal2.getType()));
+ EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal1)));
+ EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal2)));
-// mlir::Value real1 = helper->extractComplexPart(cVal1, /*isImagPart=*/false);
-// mlir::Value imag1 = helper->extractComplexPart(cVal1, /*isImagPart=*/true);
-// mlir::Value real2 = helper->extractComplexPart(cVal2, /*isImagPart=*/false);
-// mlir::Value imag2 = helper->extractComplexPart(cVal2, /*isImagPart=*/true);
-// EXPECT_EQ(realTy1, real1.getType());
-// EXPECT_EQ(realTy1, imag1.getType());
-// EXPECT_EQ(realTy1, real2.getType());
-// EXPECT_EQ(realTy1, imag2.getType());
+ mlir::Value real1 = helper->extractComplexPart(cVal1, /*isImagPart=*/false);
+ mlir::Value imag1 = helper->extractComplexPart(cVal1, /*isImagPart=*/true);
+ mlir::Value real2 = helper->extractComplexPart(cVal2, /*isImagPart=*/false);
+ mlir::Value imag2 = helper->extractComplexPart(cVal2, /*isImagPart=*/true);
+ EXPECT_EQ(realTy1, real1.getType());
+ EXPECT_EQ(realTy1, imag1.getType());
+ EXPECT_EQ(realTy1, real2.getType());
+ EXPECT_EQ(realTy1, imag2.getType());
-// mlir::Value cVal3 =
-// helper->insertComplexPart(cVal1, rThree, /*isImagPart=*/false);
-// mlir::Value cVal4 =
-// helper->insertComplexPart(cVal3, rFour, /*isImagPart=*/true);
-// EXPECT_TRUE(fir::isa_complex(cVal4.getType()));
-// EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal4)));
-// }
+ mlir::Value cVal3 =
+ helper->insertComplexPart(cVal1, rThree, /*isImagPart=*/false);
+ mlir::Value cVal4 =
+ helper->insertComplexPart(cVal3, rFour, /*isImagPart=*/true);
+ EXPECT_TRUE(fir::isa_complex(cVal4.getType()));
+ EXPECT_TRUE(fir::isa_real(helper->getComplexPartType(cVal4)));
+}
TEST_F(ComplexTest, verifyConvertWithSemantics) {
auto loc = firBuilder->getUnknownLoc();
diff --git a/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp b/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp
index 9da6cde3e1d1e..d0a9342914a39 100644
--- a/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp
+++ b/flang/unittests/Optimizer/Builder/DoLoopHelperTest.cpp
@@ -69,19 +69,19 @@ TEST_F(DoLoopHelperTest, createLoopWithLowerAndUpperBound) {
checkConstantValue(loop.getStep(), 1);
}
-// TEST_F(DoLoopHelperTest, createLoopWithStep) {
-// auto firBuilder = getBuilder();
-// fir::factory::DoLoopHelper helper(firBuilder, firBuilder.getUnknownLoc());
+TEST_F(DoLoopHelperTest, createLoopWithStep) {
+ auto firBuilder = getBuilder();
+ fir::factory::DoLoopHelper helper(firBuilder, firBuilder.getUnknownLoc());
-// auto lb = firBuilder.createIntegerConstant(
-// firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 1);
-// auto ub = firBuilder.createIntegerConstant(
-// firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 20);
-// auto step = firBuilder.createIntegerConstant(
-// firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 2);
-// auto loop = helper.createLoop(
-// lb, ub, step, [&](fir::FirOpBuilder &, mlir::Value index) {});
-// checkConstantValue(loop.getLowerBound(), 1);
-// checkConstantValue(loop.getUpperBound(), 20);
-// checkConstantValue(loop.getStep(), 2);
-// }
+ auto lb = firBuilder.createIntegerConstant(
+ firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 1);
+ auto ub = firBuilder.createIntegerConstant(
+ firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 20);
+ auto step = firBuilder.createIntegerConstant(
+ firBuilder.getUnknownLoc(), firBuilder.getIndexType(), 2);
+ auto loop = helper.createLoop(
+ lb, ub, step, [&](fir::FirOpBuilder &, mlir::Value index) {});
+ checkConstantValue(loop.getLowerBound(), 1);
+ checkConstantValue(loop.getUpperBound(), 20);
+ checkConstantValue(loop.getStep(), 2);
+}
diff --git a/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp b/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp
index 3f18ea073711f..e5e5454ee88ad 100644
--- a/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp
+++ b/flang/unittests/Optimizer/Builder/FIRBuilderTest.cpp
@@ -154,12 +154,12 @@ TEST_F(FIRBuilderTest, createRealZeroConstant) {
0u, mlir::cast<FloatAttr>(cstOp.getValue()).getValue().convertToDouble());
}
-// TEST_F(FIRBuilderTest, createBool) {
-// auto builder = getBuilder();
-// auto loc = builder.getUnknownLoc();
-// auto b = builder.createBool(loc, false);
-// checkIntegerConstant(b, builder.getIntegerType(1), 0);
-// }
+TEST_F(FIRBuilderTest, createBool) {
+ auto builder = getBuilder();
+ auto loc = builder.getUnknownLoc();
+ auto b = builder.createBool(loc, false);
+ checkIntegerConstant(b, builder.getIntegerType(1), 0);
+}
TEST_F(FIRBuilderTest, getVarLenSeqTy) {
auto builder = getBuilder();
diff --git a/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp b/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp
index 616045f275e16..1858b276f1fc3 100644
--- a/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp
+++ b/flang/unittests/Optimizer/Builder/HLFIRToolsTest.cpp
@@ -126,38 +126,38 @@ TEST_F(HLFIRToolsTest, testScalarCharRoundTrip) {
EXPECT_FALSE(scalarCharEntity.isValue());
}
-// TEST_F(HLFIRToolsTest, testArrayCharRoundTrip) {
-// auto &builder = getBuilder();
-// mlir::Location loc = getLoc();
-// llvm::SmallVector<mlir::Value> extents{
-// createConstant(20), createConstant(30)};
-// llvm::SmallVector<mlir::Value> lbounds{
-// createConstant(-1), createConstant(-2)};
-// mlir::Value len = createConstant(42);
-// mlir::Type charType = fir::CharacterType::getUnknownLen(&context, 1);
-// mlir::Type seqCharType = builder.getVarLenSeqTy(charType, 2);
-// mlir::Type arrayCharType = builder.getRefType(seqCharType);
-// mlir::Value arrayCharAddr = builder.create<fir::UndefOp>(loc, arrayCharType);
-// fir::CharArrayBoxValue arrayChar{arrayCharAddr, len, extents, lbounds};
-// hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar));
-// auto [arrayCharResult, cleanup] =
-// hlfir::translateToExtendedValue(loc, builder, arrayCharEntity);
-// auto *res = arrayCharResult.getBoxOf<fir::CharArrayBoxValue>();
-// EXPECT_FALSE(cleanup.has_value());
-// ASSERT_NE(res, nullptr);
-// // gtest has a terrible time printing mlir::Value in case of failing
-// // EXPECT_EQ(mlir::Value, mlir::Value). So use EXPECT_TRUE instead.
-// EXPECT_TRUE(fir::getBase(*res) == arrayCharEntity.getFirBase());
-// EXPECT_TRUE(res->getLen() == arrayChar.getLen());
-// ASSERT_EQ(res->getExtents().size(), arrayChar.getExtents().size());
-// for (unsigned i = 0; i < arrayChar.getExtents().size(); ++i)
-// EXPECT_TRUE(res->getExtents()[i] == arrayChar.getExtents()[i]);
-// ASSERT_EQ(res->getLBounds().size(), arrayChar.getLBounds().size());
-// for (unsigned i = 0; i < arrayChar.getLBounds().size(); ++i)
-// EXPECT_TRUE(res->getLBounds()[i] == arrayChar.getLBounds()[i]);
-// EXPECT_TRUE(arrayCharEntity.isVariable());
-// EXPECT_FALSE(arrayCharEntity.isValue());
-// }
+TEST_F(HLFIRToolsTest, testArrayCharRoundTrip) {
+ auto &builder = getBuilder();
+ mlir::Location loc = getLoc();
+ llvm::SmallVector<mlir::Value> extents{
+ createConstant(20), createConstant(30)};
+ llvm::SmallVector<mlir::Value> lbounds{
+ createConstant(-1), createConstant(-2)};
+ mlir::Value len = createConstant(42);
+ mlir::Type charType = fir::CharacterType::getUnknownLen(&context, 1);
+ mlir::Type seqCharType = builder.getVarLenSeqTy(charType, 2);
+ mlir::Type arrayCharType = builder.getRefType(seqCharType);
+ mlir::Value arrayCharAddr = builder.create<fir::UndefOp>(loc, arrayCharType);
+ fir::CharArrayBoxValue arrayChar{arrayCharAddr, len, extents, lbounds};
+ hlfir::EntityWithAttributes arrayCharEntity(createDeclare(arrayChar));
+ auto [arrayCharResult, cleanup] =
+ hlfir::translateToExtendedValue(loc, builder, arrayCharEntity);
+ auto *res = arrayCharResult.getBoxOf<fir::CharArrayBoxValue>();
+ EXPECT_FALSE(cleanup.has_value());
+ ASSERT_NE(res, nullptr);
+ // gtest has a terrible time printing mlir::Value in case of failing
+ // EXPECT_EQ(mlir::Value, mlir::Value). So use EXPECT_TRUE instead.
+ EXPECT_TRUE(fir::getBase(*res) == arrayCharEntity.getFirBase());
+ EXPECT_TRUE(res->getLen() == arrayChar.getLen());
+ ASSERT_EQ(res->getExtents().size(), arrayChar.getExtents().size());
+ for (unsigned i = 0; i < arrayChar.getExtents().size(); ++i)
+ EXPECT_TRUE(res->getExtents()[i] == arrayChar.getExtents()[i]);
+ ASSERT_EQ(res->getLBounds().size(), arrayChar.getLBounds().size());
+ for (unsigned i = 0; i < arrayChar.getLBounds().size(); ++i)
+ EXPECT_TRUE(res->getLBounds()[i] == arrayChar.getLBounds()[i]);
+ EXPECT_TRUE(arrayCharEntity.isVariable());
+ EXPECT_FALSE(arrayCharEntity.isValue());
+}
TEST_F(HLFIRToolsTest, testArrayCharBoxRoundTrip) {
auto &builder = getBuilder();
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp
index 18f7dd0743a73..315f8c80dc33f 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CharacterTest.cpp
@@ -113,17 +113,17 @@ TEST_F(RuntimeCallTest, genIndexTest) {
checkGenIndex(*firBuilder, "_FortranAIndex4", 4);
}
-// TEST_F(RuntimeCallTest, genIndexDescriptorTest) {
-// auto loc = firBuilder->getUnknownLoc();
-// mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
-// mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
-// mlir::Value substringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
-// mlir::Value backOpt = firBuilder->create<fir::UndefOp>(loc, boxTy);
-// mlir::Value kind = firBuilder->create<fir::UndefOp>(loc, i32Ty);
-// fir::runtime::genIndexDescriptor(
-// *firBuilder, loc, resultBox, stringBox, substringBox, backOpt, kind);
-// checkCallOpFromResultBox(resultBox, "_FortranAIndex", 5);
-// }
+TEST_F(RuntimeCallTest, genIndexDescriptorTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Value resultBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
+ mlir::Value stringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
+ mlir::Value substringBox = firBuilder->create<fir::UndefOp>(loc, boxTy);
+ mlir::Value backOpt = firBuilder->create<fir::UndefOp>(loc, boxTy);
+ mlir::Value kind = firBuilder->create<fir::UndefOp>(loc, i32Ty);
+ fir::runtime::genIndexDescriptor(
+ *firBuilder, loc, resultBox, stringBox, substringBox, backOpt, kind);
+ checkCallOpFromResultBox(resultBox, "_FortranAIndex", 5);
+}
TEST_F(RuntimeCallTest, genRepeatTest) {
auto loc = firBuilder->getUnknownLoc();
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
index 57347e56b4c61..58a151447d5b4 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
@@ -10,12 +10,12 @@
#include "RuntimeCallTestBase.h"
#include "gtest/gtest.h"
-// TEST_F(RuntimeCallTest, genCommandArgumentCountTest) {
-// mlir::Location loc = firBuilder->getUnknownLoc();
-// mlir::Value result = fir::runtime::genCommandArgumentCount(*firBuilder, loc);
-// checkCallOp(result.getDefiningOp(), "_FortranAArgumentCount", /*nbArgs=*/0,
-// /*addLocArgs=*/false);
-// }
+TEST_F(RuntimeCallTest, genCommandArgumentCountTest) {
+ mlir::Location loc = firBuilder->getUnknownLoc();
+ mlir::Value result = fir::runtime::genCommandArgumentCount(*firBuilder, loc);
+ checkCallOp(result.getDefiningOp(), "_FortranAArgumentCount", /*nbArgs=*/0,
+ /*addLocArgs=*/false);
+}
TEST_F(RuntimeCallTest, genGetCommandArgument) {
mlir::Location loc = firBuilder->getUnknownLoc();
diff --git a/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp
index 994e113da70e4..a4006c6b59c12 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/ReductionTest.cpp
@@ -52,15 +52,15 @@ TEST_F(RuntimeCallTest, genCountTest) {
checkCallOp(count.getDefiningOp(), "_FortranACount", 2);
}
-// TEST_F(RuntimeCallTest, genCountDimTest) {
-// mlir::Location loc = firBuilder->getUnknownLoc();
-// mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
-// mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
-// mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
-// mlir::Value kind = firBuilder->createIntegerConstant(loc, i32Ty, 1);
-// fir::runtime::genCountDim(*firBuilder, loc, result, mask, dim, kind);
-// checkCallOpFromResultBox(result, "_FortranACountDim", 4);
-// }
+TEST_F(RuntimeCallTest, genCountDimTest) {
+ mlir::Location loc = firBuilder->getUnknownLoc();
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+ mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+ mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
+ mlir::Value kind = firBuilder->createIntegerConstant(loc, i32Ty, 1);
+ fir::runtime::genCountDim(*firBuilder, loc, result, mask, dim, kind);
+ checkCallOpFromResultBox(result, "_FortranACountDim", 4);
+}
void testGenMaxVal(
fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {
@@ -120,14 +120,14 @@ TEST_F(RuntimeCallTest, genParityTest) {
checkCallOp(parity.getDefiningOp(), "_FortranAParity", 2);
}
-// TEST_F(RuntimeCallTest, genParityDescriptorTest) {
-// mlir::Location loc = firBuilder->getUnknownLoc();
-// mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
-// mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
-// mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
-// fir::runtime::genParityDescriptor(*firBuilder, loc, result, mask, dim);
-// checkCallOpFromResultBox(result, "_FortranAParityDim", 3);
-// }
+TEST_F(RuntimeCallTest, genParityDescriptorTest) {
+ mlir::Location loc = firBuilder->getUnknownLoc();
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+ mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy10);
+ mlir::Value dim = firBuilder->createIntegerConstant(loc, i32Ty, 1);
+ fir::runtime::genParityDescriptor(*firBuilder, loc, result, mask, dim);
+ checkCallOpFromResultBox(result, "_FortranAParityDim", 3);
+}
void testGenSum(
fir::FirOpBuilder &builder, mlir::Type eleTy, llvm::StringRef fctName) {
@@ -349,10 +349,10 @@ TEST_F(RuntimeCallTest, genMaxvalCharTest) {
*firBuilder, fir::runtime::genMaxvalChar, "_FortranAMaxvalCharacter", 3);
}
-// TEST_F(RuntimeCallTest, genMinvalCharTest) {
-// checkGenMxxvalChar(
-// *firBuilder, fir::runtime::genMinvalChar, "_FortranAMinvalCharacter", 3);
-// }
+TEST_F(RuntimeCallTest, genMinvalCharTest) {
+ checkGenMxxvalChar(
+ *firBuilder, fir::runtime::genMinvalChar, "_FortranAMinvalCharacter", 3);
+}
void checkGen4argsDim(fir::FirOpBuilder &builder,
void (*genFct)(fir::FirOpBuilder &, mlir::Location, mlir::Value,
diff --git a/flang/unittests/Optimizer/FIRTypesTest.cpp b/flang/unittests/Optimizer/FIRTypesTest.cpp
index 5ea621eebcdd4..238aa6939d5df 100644
--- a/flang/unittests/Optimizer/FIRTypesTest.cpp
+++ b/flang/unittests/Optimizer/FIRTypesTest.cpp
@@ -125,33 +125,33 @@ TEST_F(FIRTypesTest, isUnlimitedPolymorphicTypeTest) {
}
// Test fir::isBoxedRecordType from flang/Optimizer/Dialect/FIRType.h.
-// TEST_F(FIRTypesTest, isBoxedRecordType) {
-// mlir::Type recTy = fir::RecordType::get(&context, "dt");
-// mlir::Type seqRecTy =
-// fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);
-// mlir::Type ty = fir::BoxType::get(recTy);
-// EXPECT_TRUE(fir::isBoxedRecordType(ty));
-// EXPECT_TRUE(fir::isBoxedRecordType(fir::ReferenceType::get(ty)));
-
-// // TYPE(T), ALLOCATABLE
-// ty = fir::BoxType::get(fir::HeapType::get(recTy));
-// EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
-// // TYPE(T), POINTER
-// ty = fir::BoxType::get(fir::PointerType::get(recTy));
-// EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
-// // TYPE(T), DIMENSION(10)
-// ty = fir::BoxType::get(fir::SequenceType::get({10}, recTy));
-// EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
-// // TYPE(T), DIMENSION(:)
-// ty = fir::BoxType::get(seqRecTy);
-// EXPECT_TRUE(fir::isBoxedRecordType(ty));
-
-// EXPECT_FALSE(fir::isBoxedRecordType(fir::BoxType::get(
-// fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)))));
-// }
+TEST_F(FIRTypesTest, isBoxedRecordType) {
+ mlir::Type recTy = fir::RecordType::get(&context, "dt");
+ mlir::Type seqRecTy =
+ fir::SequenceType::get({fir::SequenceType::getUnknownExtent()}, recTy);
+ mlir::Type ty = fir::BoxType::get(recTy);
+ EXPECT_TRUE(fir::isBoxedRecordType(ty));
+ EXPECT_TRUE(fir::isBoxedRecordType(fir::ReferenceType::get(ty)));
+
+ // TYPE(T), ALLOCATABLE
+ ty = fir::BoxType::get(fir::HeapType::get(recTy));
+ EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+ // TYPE(T), POINTER
+ ty = fir::BoxType::get(fir::PointerType::get(recTy));
+ EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+ // TYPE(T), DIMENSION(10)
+ ty = fir::BoxType::get(fir::SequenceType::get({10}, recTy));
+ EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+ // TYPE(T), DIMENSION(:)
+ ty = fir::BoxType::get(seqRecTy);
+ EXPECT_TRUE(fir::isBoxedRecordType(ty));
+
+ EXPECT_FALSE(fir::isBoxedRecordType(fir::BoxType::get(
+ fir::ReferenceType::get(mlir::IntegerType::get(&context, 32)))));
+}
// Test fir::isScalarBoxedRecordType from flang/Optimizer/Dialect/FIRType.h.
TEST_F(FIRTypesTest, isScalarBoxedRecordType) {
diff --git a/flang/unittests/Optimizer/FortranVariableTest.cpp b/flang/unittests/Optimizer/FortranVariableTest.cpp
index ae48cdb18533e..87efb624735cf 100644
--- a/flang/unittests/Optimizer/FortranVariableTest.cpp
+++ b/flang/unittests/Optimizer/FortranVariableTest.cpp
@@ -42,29 +42,29 @@ struct FortranVariableTest : public testing::Test {
std::unique_ptr<mlir::OpBuilder> builder;
};
-// TEST_F(FortranVariableTest, SimpleScalar) {
-// mlir::Location loc = getLoc();
-// mlir::Type eleType = mlir::FloatType::getF32(&context);
-// mlir::Value addr = builder->create<fir::AllocaOp>(loc, eleType);
-// auto name = mlir::StringAttr::get(&context, "x");
-// auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
-// /*shape=*/mlir::Value{}, /*typeParams=*/std::nullopt,
-// /*dummy_scope=*/nullptr, name,
-// /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
-// /*data_attr=*/cuf::DataAttributeAttr{});
+TEST_F(FortranVariableTest, SimpleScalar) {
+ mlir::Location loc = getLoc();
+ mlir::Type eleType = mlir::FloatType::getF32(&context);
+ mlir::Value addr = builder->create<fir::AllocaOp>(loc, eleType);
+ auto name = mlir::StringAttr::get(&context, "x");
+ auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
+ /*shape=*/mlir::Value{}, /*typeParams=*/std::nullopt,
+ /*dummy_scope=*/nullptr, name,
+ /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
+ /*data_attr=*/cuf::DataAttributeAttr{});
-// fir::FortranVariableOpInterface fortranVariable = declare;
-// EXPECT_FALSE(fortranVariable.isArray());
-// EXPECT_FALSE(fortranVariable.isCharacter());
-// EXPECT_FALSE(fortranVariable.isPointer());
-// EXPECT_FALSE(fortranVariable.isAllocatable());
-// EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
-// EXPECT_EQ(fortranVariable.getElementType(), eleType);
-// EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
-// fortranVariable.getElementType());
-// EXPECT_NE(fortranVariable.getBase(), addr);
-// EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
-// }
+ fir::FortranVariableOpInterface fortranVariable = declare;
+ EXPECT_FALSE(fortranVariable.isArray());
+ EXPECT_FALSE(fortranVariable.isCharacter());
+ EXPECT_FALSE(fortranVariable.isPointer());
+ EXPECT_FALSE(fortranVariable.isAllocatable());
+ EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
+ EXPECT_EQ(fortranVariable.getElementType(), eleType);
+ EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
+ fortranVariable.getElementType());
+ EXPECT_NE(fortranVariable.getBase(), addr);
+ EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
+}
TEST_F(FortranVariableTest, CharacterScalar) {
mlir::Location loc = getLoc();
diff --git a/flang/unittests/Optimizer/InternalNamesTest.cpp b/flang/unittests/Optimizer/InternalNamesTest.cpp
index 470791d41541a..058bbeef9b007 100644
--- a/flang/unittests/Optimizer/InternalNamesTest.cpp
+++ b/flang/unittests/Optimizer/InternalNamesTest.cpp
@@ -88,38 +88,38 @@ TEST(InternalNamesTest, doTypeTest) {
ASSERT_EQ(actual, expectedMangledName);
}
-// TEST(InternalNamesTest, doIntrinsicTypeDescriptorTest) {
-// using IntrinsicType = fir::NameUniquer::IntrinsicType;
-// std::string actual = NameUniquer::doIntrinsicTypeDescriptor(
-// {}, {}, 0, IntrinsicType::REAL, 42);
-// std::string expectedMangledName = "_QYIrealK42";
-// ASSERT_EQ(actual, expectedMangledName);
-
-// actual = NameUniquer::doIntrinsicTypeDescriptor(
-// {}, {}, 0, IntrinsicType::REAL, {});
-// expectedMangledName = "_QYIrealK0";
-// ASSERT_EQ(actual, expectedMangledName);
-
-// actual = NameUniquer::doIntrinsicTypeDescriptor(
-// {}, {}, 0, IntrinsicType::INTEGER, 3);
-// expectedMangledName = "_QYIintegerK3";
-// ASSERT_EQ(actual, expectedMangledName);
-
-// actual = NameUniquer::doIntrinsicTypeDescriptor(
-// {}, {}, 0, IntrinsicType::LOGICAL, 2);
-// expectedMangledName = "_QYIlogicalK2";
-// ASSERT_EQ(actual, expectedMangledName);
-
-// actual = NameUniquer::doIntrinsicTypeDescriptor(
-// {}, {}, 0, IntrinsicType::CHARACTER, 4);
-// expectedMangledName = "_QYIcharacterK4";
-// ASSERT_EQ(actual, expectedMangledName);
-
-// actual = NameUniquer::doIntrinsicTypeDescriptor(
-// {}, {}, 0, IntrinsicType::COMPLEX, 4);
-// expectedMangledName = "_QYIcomplexK4";
-// ASSERT_EQ(actual, expectedMangledName);
-// }
+TEST(InternalNamesTest, doIntrinsicTypeDescriptorTest) {
+ using IntrinsicType = fir::NameUniquer::IntrinsicType;
+ std::string actual = NameUniquer::doIntrinsicTypeDescriptor(
+ {}, {}, 0, IntrinsicType::REAL, 42);
+ std::string expectedMangledName = "_QYIrealK42";
+ ASSERT_EQ(actual, expectedMangledName);
+
+ actual = NameUniquer::doIntrinsicTypeDescriptor(
+ {}, {}, 0, IntrinsicType::REAL, {});
+ expectedMangledName = "_QYIrealK0";
+ ASSERT_EQ(actual, expectedMangledName);
+
+ actual = NameUniquer::doIntrinsicTypeDescriptor(
+ {}, {}, 0, IntrinsicType::INTEGER, 3);
+ expectedMangledName = "_QYIintegerK3";
+ ASSERT_EQ(actual, expectedMangledName);
+
+ actual = NameUniquer::doIntrinsicTypeDescriptor(
+ {}, {}, 0, IntrinsicType::LOGICAL, 2);
+ expectedMangledName = "_QYIlogicalK2";
+ ASSERT_EQ(actual, expectedMangledName);
+
+ actual = NameUniquer::doIntrinsicTypeDescriptor(
+ {}, {}, 0, IntrinsicType::CHARACTER, 4);
+ expectedMangledName = "_QYIcharacterK4";
+ ASSERT_EQ(actual, expectedMangledName);
+
+ actual = NameUniquer::doIntrinsicTypeDescriptor(
+ {}, {}, 0, IntrinsicType::COMPLEX, 4);
+ expectedMangledName = "_QYIcomplexK4";
+ ASSERT_EQ(actual, expectedMangledName);
+}
TEST(InternalNamesTest, doDispatchTableTest) {
std::string actual =
diff --git a/flang/unittests/Runtime/CharacterTest.cpp b/flang/unittests/Runtime/CharacterTest.cpp
index e9522fae9a2c8..e54fd8a5075f6 100644
--- a/flang/unittests/Runtime/CharacterTest.cpp
+++ b/flang/unittests/Runtime/CharacterTest.cpp
@@ -199,32 +199,32 @@ struct CharacterComparisonTests : public ::testing::Test {
TYPED_TEST_SUITE(CharacterComparisonTests, CharacterTypes, );
-// TYPED_TEST(CharacterComparisonTests, CompareCharacters) {
-// for (auto &[x, y, xBytes, yBytes, expect] : this->parameters) {
-// int cmp{this->characterComparisonFunc(x, y, xBytes, yBytes)};
-// TypeParam buf[2][8];
-// std::memset(buf, 0, sizeof buf);
-// std::memcpy(buf[0], x, xBytes);
-// std::memcpy(buf[1], y, yBytes);
-// ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
-// << y << "'(" << yBytes << "), got " << cmp
-// << ", should be " << expect << '\n';
-
-// // Perform the same test with the parameters reversed and the difference
-// // negated
-// std::swap(x, y);
-// std::swap(xBytes, yBytes);
-// expect = -expect;
-
-// cmp = this->characterComparisonFunc(x, y, xBytes, yBytes);
-// std::memset(buf, 0, sizeof buf);
-// std::memcpy(buf[0], x, xBytes);
-// std::memcpy(buf[1], y, yBytes);
-// ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
-// << y << "'(" << yBytes << "'), got " << cmp
-// << ", should be " << expect << '\n';
-// }
-// }
+TYPED_TEST(CharacterComparisonTests, CompareCharacters) {
+ for (auto &[x, y, xBytes, yBytes, expect] : this->parameters) {
+ int cmp{this->characterComparisonFunc(x, y, xBytes, yBytes)};
+ TypeParam buf[2][8];
+ std::memset(buf, 0, sizeof buf);
+ std::memcpy(buf[0], x, xBytes);
+ std::memcpy(buf[1], y, yBytes);
+ ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
+ << y << "'(" << yBytes << "), got " << cmp
+ << ", should be " << expect << '\n';
+
+ // Perform the same test with the parameters reversed and the difference
+ // negated
+ std::swap(x, y);
+ std::swap(xBytes, yBytes);
+ expect = -expect;
+
+ cmp = this->characterComparisonFunc(x, y, xBytes, yBytes);
+ std::memset(buf, 0, sizeof buf);
+ std::memcpy(buf[0], x, xBytes);
+ std::memcpy(buf[1], y, yBytes);
+ ASSERT_EQ(cmp, expect) << "compare '" << x << "'(" << xBytes << ") to '"
+ << y << "'(" << yBytes << "'), got " << cmp
+ << ", should be " << expect << '\n';
+ }
+}
// Test MIN() and MAX()
struct ExtremumTestCase {
@@ -275,14 +275,14 @@ TYPED_TEST(ExtremumTests, MinTests) {
RunExtremumTests<TypeParam>("MIN", RTNAME(CharacterMin), tests);
}
-// TYPED_TEST(ExtremumTests, MaxTests) {
-// static std::vector<ExtremumTestCase> tests{
-// {{}, {"a"}, {"z"}, {"z"}},
-// {{1}, {"zaa"}, {"aaaaa"}, {"zaa "}},
-// {{1, 1, 1}, {"aaaaa"}, {"aazaa"}, {"aazaa"}},
-// };
-// RunExtremumTests<TypeParam>("MAX", RTNAME(CharacterMax), tests);
-// }
+TYPED_TEST(ExtremumTests, MaxTests) {
+ static std::vector<ExtremumTestCase> tests{
+ {{}, {"a"}, {"z"}, {"z"}},
+ {{1}, {"zaa"}, {"aaaaa"}, {"zaa "}},
+ {{1, 1, 1}, {"aaaaa"}, {"aazaa"}, {"aazaa"}},
+ };
+ RunExtremumTests<TypeParam>("MAX", RTNAME(CharacterMax), tests);
+}
template <typename CHAR>
void RunAllocationTest(const char *xRaw, const char *yRaw) {
@@ -373,20 +373,20 @@ TYPED_TEST(SearchTests, ScanTests) {
RunSearchTests("SCAN", tests, std::get<SearchFunction<TypeParam>>(functions));
}
-// TYPED_TEST(SearchTests, VerifyTests) {
-// static SearchFunctions functions{
-// RTNAME(Verify1), RTNAME(Verify2), RTNAME(Verify4)};
-// static std::vector<SearchTestCase> tests{
-// {"abc", "abc", false, 0},
-// {"abc", "abc", true, 0},
-// {"abc", "cde", false, 1},
-// {"abc", "cde", true, 2},
-// {"abc", "x", false, 1},
-// {"", "x", false, 0},
-// };
-// RunSearchTests(
-// "VERIFY", tests, std::get<SearchFunction<TypeParam>>(functions));
-// }
+TYPED_TEST(SearchTests, VerifyTests) {
+ static SearchFunctions functions{
+ RTNAME(Verify1), RTNAME(Verify2), RTNAME(Verify4)};
+ static std::vector<SearchTestCase> tests{
+ {"abc", "abc", false, 0},
+ {"abc", "abc", true, 0},
+ {"abc", "cde", false, 1},
+ {"abc", "cde", true, 2},
+ {"abc", "x", false, 1},
+ {"", "x", false, 0},
+ };
+ RunSearchTests(
+ "VERIFY", tests, std::get<SearchFunction<TypeParam>>(functions));
+}
// Test REPEAT()
template <typename CHAR> struct RepeatTests : public ::testing::Test {};
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index c67eb091d0b11..08daa4ba37f26 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -308,21 +308,21 @@ TEST_F(ZeroArguments, GetCommandArgument) {
TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }
-// TEST_F(ZeroArguments, ECLValidCommandAndPadSync) {
-// OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
-// bool wait{true};
-// OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
-// OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor()};
-// OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
-
-// RTNAME(ExecuteCommandLine)
-// (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
-
-// std::string spaces(cmdMsg->ElementBytes(), ' ');
-// CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 0);
-// CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 0);
-// CheckDescriptorEqStr(cmdMsg.get(), "No change");
-// }
+TEST_F(ZeroArguments, ECLValidCommandAndPadSync) {
+ OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
+ bool wait{true};
+ OwningPtr<Descriptor> exitStat{EmptyIntDescriptor()};
+ OwningPtr<Descriptor> cmdStat{EmptyIntDescriptor()};
+ OwningPtr<Descriptor> cmdMsg{CharDescriptor("No change")};
+
+ RTNAME(ExecuteCommandLine)
+ (*command.get(), wait, exitStat.get(), cmdStat.get(), cmdMsg.get());
+
+ std::string spaces(cmdMsg->ElementBytes(), ' ');
+ CheckDescriptorEqInt<std::int64_t>(exitStat.get(), 0);
+ CheckDescriptorEqInt<std::int64_t>(cmdStat.get(), 0);
+ CheckDescriptorEqStr(cmdMsg.get(), "No change");
+}
TEST_F(ZeroArguments, ECLValidCommandStatusSetSync) {
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
@@ -404,14 +404,14 @@ TEST_F(ZeroArguments, ECLInvalidCommandParentNotTerminatedAsync) {
CheckDescriptorEqStr(cmdMsg.get(), "No change");
}
-// TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectSync) {
-// OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
+TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectSync) {
+ OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
-// EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
-// *command.get(), false, nullptr, nullptr, nullptr));
-// EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
-// *command.get(), true, nullptr, nullptr, nullptr));
-// }
+ EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
+ *command.get(), false, nullptr, nullptr, nullptr));
+ EXPECT_NO_FATAL_FAILURE(RTNAME(ExecuteCommandLine)(
+ *command.get(), true, nullptr, nullptr, nullptr));
+}
TEST_F(ZeroArguments, ECLInvalidCommandAsyncDontAffectAsync) {
OwningPtr<Descriptor> command{CharDescriptor("echo hi")};
@@ -560,18 +560,18 @@ TEST_F(SeveralArguments, GetCommand) {
CheckMissingCommandValue("Missing argument");
}
-// TEST_F(SeveralArguments, CommandErrMsgTooShort) {
-// OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()};
-// OwningPtr<Descriptor> length{EmptyIntDescriptor()};
-// OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()};
+TEST_F(SeveralArguments, CommandErrMsgTooShort) {
+ OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()};
+ OwningPtr<Descriptor> length{EmptyIntDescriptor()};
+ OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()};
-// EXPECT_GT(RTNAME(GetCommand)(value.get(), length.get(), errMsg.get()), 0);
+ EXPECT_GT(RTNAME(GetCommand)(value.get(), length.get(), errMsg.get()), 0);
-// std::string spaces(value->ElementBytes(), ' ');
-// CheckDescriptorEqStr(value.get(), spaces);
-// CheckDescriptorEqInt<std::int64_t>(length.get(), 0);
-// CheckDescriptorEqStr(errMsg.get(), "Mis");
-// }
+ std::string spaces(value->ElementBytes(), ' ');
+ CheckDescriptorEqStr(value.get(), spaces);
+ CheckDescriptorEqInt<std::int64_t>(length.get(), 0);
+ CheckDescriptorEqStr(errMsg.get(), "Mis");
+}
TEST_F(SeveralArguments, GetCommandCanTakeNull) {
EXPECT_GT(RTNAME(GetCommand)(nullptr, nullptr, nullptr), 0);
@@ -700,11 +700,11 @@ TEST_F(EnvironmentVariables, NoTrim) {
}
}
-// TEST_F(EnvironmentVariables, Empty) {
-// if (EnableFineGrainedTests()) {
-// CheckEnvVarValue("", "EMPTY");
-// }
-// }
+TEST_F(EnvironmentVariables, Empty) {
+ if (EnableFineGrainedTests()) {
+ CheckEnvVarValue("", "EMPTY");
+ }
+}
TEST_F(EnvironmentVariables, NoValueOrErrmsg) {
ASSERT_EQ(std::getenv("DOESNT_EXIST"), nullptr)
diff --git a/flang/unittests/Runtime/Complex.cpp b/flang/unittests/Runtime/Complex.cpp
index f87b890c825d3..46f3ad2f2712b 100644
--- a/flang/unittests/Runtime/Complex.cpp
+++ b/flang/unittests/Runtime/Complex.cpp
@@ -133,23 +133,23 @@ TEST(Complex, cpowk) {
cpowk(0.f + 1if, std::numeric_limits<std::int64_t>::min()), 1.f + 0if);
}
-// TEST(Complex, zpowi) {
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 0), 1. + 0i);
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 1), 3. + 4i);
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 2), -7. + 24i);
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 3), -117. + 44i);
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 4), -527. - 336i);
-
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, -2), -0.0112 - 0.0384i);
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 10), -237. - 3116i);
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
-
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 5), -38. + 41i);
-// EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
-
-// EXPECT_COMPLEX_DOUBLE_EQ(
-// zpowi(0. + 1i, std::numeric_limits<std::int32_t>::min()), 1. + 0i);
-// }
+TEST(Complex, zpowi) {
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 0), 1. + 0i);
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 1), 3. + 4i);
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 2), -7. + 24i);
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 3), -117. + 44i);
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, 4), -527. - 336i);
+
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(3. + 4i, -2), -0.0112 - 0.0384i);
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 10), -237. - 3116i);
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -10), -9.32293628 - 7.29848564i);
+
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(2. + 1i, 5), -38. + 41i);
+ EXPECT_COMPLEX_DOUBLE_EQ(zpowi(0.5 + 0.6i, -5), -1.12183773 + 3.25291503i);
+
+ EXPECT_COMPLEX_DOUBLE_EQ(
+ zpowi(0. + 1i, std::numeric_limits<std::int32_t>::min()), 1. + 0i);
+}
TEST(Complex, zpowk) {
EXPECT_COMPLEX_DOUBLE_EQ(zpowk(3. + 4i, 0), 1. + 0i);
diff --git a/flang/unittests/Runtime/ExternalIOTest.cpp b/flang/unittests/Runtime/ExternalIOTest.cpp
index 0f3da0784f9d4..13327964e12a4 100644
--- a/flang/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang/unittests/Runtime/ExternalIOTest.cpp
@@ -585,103 +585,103 @@ TEST(ExternalIOTests, TestNonAvancingInput) {
<< "EndIoStatement() for Close";
}
-// TEST(ExternalIOTests, TestWriteAfterNonAvancingInput) {
-// // OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
-// // FORM='FORMATTED',STATUS='SCRATCH')
-// auto *io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
-// ASSERT_TRUE(IONAME(SetAccess)(io, "SEQUENTIAL", 10))
-// << "SetAccess(SEQUENTIAL)";
-// ASSERT_TRUE(IONAME(SetAction)(io, "READWRITE", 9)) << "SetAction(READWRITE)";
-// ASSERT_TRUE(IONAME(SetForm)(io, "FORMATTED", 9)) << "SetForm(FORMATTED)";
-// ASSERT_TRUE(IONAME(SetStatus)(io, "SCRATCH", 7)) << "SetStatus(SCRATCH)";
-
-// int unit{-1};
-// ASSERT_TRUE(IONAME(GetNewUnit)(io, unit)) << "GetNewUnit()";
-// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-// << "EndIoStatement() for OpenNewUnit";
-
-// // Write the file to be used for the input test.
-// static constexpr std::string_view records[] = {"ABCDEFGHIJKLMNOPQRST"};
-// static constexpr std::string_view fmt{"(A)"};
-// for (const auto &record : records) {
-// // WRITE(UNIT=unit,FMT=fmt) record
-// io = IONAME(BeginExternalFormattedOutput)(
-// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
-// ASSERT_TRUE(IONAME(OutputAscii)(io, record.data(), record.length()))
-// << "OutputAscii()";
-// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-// << "EndIoStatement() for OutputAscii";
-// }
-
-// // REWIND(UNIT=unit)
-// io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
-// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-// << "EndIoStatement() for Rewind";
-
-// struct TestItems {
-// std::string item;
-// int expectedIoStat;
-// std::string expectedItemValue;
-// };
-// // Actual non advancing input IO test
-// TestItems inputItems[]{
-// {std::string(4, '+'), IostatOk, "ABCD"},
-// {std::string(4, '+'), IostatOk, "EFGH"},
-// };
-
-// int j{0};
-// for (auto &inputItem : inputItems) {
-// // READ(UNIT=unit, FMT=fmt, ADVANCE='NO', IOSTAT=iostat) inputItem
-// io = IONAME(BeginExternalFormattedInput)(
-// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
-// IONAME(EnableHandlers)(io, true, false, false, false, false);
-// ASSERT_TRUE(IONAME(SetAdvance)(io, "NO", 2)) << "SetAdvance(NO)" << j;
-// ASSERT_TRUE(
-// IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length()))
-// << "InputAscii() " << j;
-// ASSERT_EQ(IONAME(EndIoStatement)(io), inputItem.expectedIoStat)
-// << "EndIoStatement() for Read " << j;
-// ASSERT_EQ(inputItem.item, inputItem.expectedItemValue)
-// << "Input-item value after non advancing read " << j;
-// j++;
-// }
-
-// // WRITE(UNIT=unit, FMT=fmt, IOSTAT=iostat) outputItem.
-// static constexpr std::string_view outputItem{"XYZ"};
-// // WRITE(UNIT=unit,FMT=fmt) record
-// io = IONAME(BeginExternalFormattedOutput)(
-// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
-// ASSERT_TRUE(IONAME(OutputAscii)(io, outputItem.data(), outputItem.length()))
-// << "OutputAscii()";
-// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-// << "EndIoStatement() for OutputAscii";
-
-// // Verify that the output was written in the record read in non advancing
-// // mode, after the read part, and that the end was truncated.
-
-// // REWIND(UNIT=unit)
-// io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
-// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-// << "EndIoStatement() for Rewind";
-
-// std::string resultRecord(20, '+');
-// std::string expectedRecord{"ABCDEFGHXYZ "};
-// // READ(UNIT=unit, FMT=fmt, IOSTAT=iostat) result
-// io = IONAME(BeginExternalFormattedInput)(
-// fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
-// IONAME(EnableHandlers)(io, true, false, false, false, false);
-// ASSERT_TRUE(
-// IONAME(InputAscii)(io, resultRecord.data(), resultRecord.length()))
-// << "InputAscii() ";
-// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-// << "EndIoStatement() for Read ";
-// ASSERT_EQ(resultRecord, expectedRecord)
-// << "Record after non advancing read followed by write";
-// // CLOSE(UNIT=unit)
-// io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
-// ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
-// << "EndIoStatement() for Close";
-// }
+TEST(ExternalIOTests, TestWriteAfterNonAvancingInput) {
+ // OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
+ // FORM='FORMATTED',STATUS='SCRATCH')
+ auto *io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
+ ASSERT_TRUE(IONAME(SetAccess)(io, "SEQUENTIAL", 10))
+ << "SetAccess(SEQUENTIAL)";
+ ASSERT_TRUE(IONAME(SetAction)(io, "READWRITE", 9)) << "SetAction(READWRITE)";
+ ASSERT_TRUE(IONAME(SetForm)(io, "FORMATTED", 9)) << "SetForm(FORMATTED)";
+ ASSERT_TRUE(IONAME(SetStatus)(io, "SCRATCH", 7)) << "SetStatus(SCRATCH)";
+
+ int unit{-1};
+ ASSERT_TRUE(IONAME(GetNewUnit)(io, unit)) << "GetNewUnit()";
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for OpenNewUnit";
+
+ // Write the file to be used for the input test.
+ static constexpr std::string_view records[] = {"ABCDEFGHIJKLMNOPQRST"};
+ static constexpr std::string_view fmt{"(A)"};
+ for (const auto &record : records) {
+ // WRITE(UNIT=unit,FMT=fmt) record
+ io = IONAME(BeginExternalFormattedOutput)(
+ fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+ ASSERT_TRUE(IONAME(OutputAscii)(io, record.data(), record.length()))
+ << "OutputAscii()";
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for OutputAscii";
+ }
+
+ // REWIND(UNIT=unit)
+ io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Rewind";
+
+ struct TestItems {
+ std::string item;
+ int expectedIoStat;
+ std::string expectedItemValue;
+ };
+ // Actual non advancing input IO test
+ TestItems inputItems[]{
+ {std::string(4, '+'), IostatOk, "ABCD"},
+ {std::string(4, '+'), IostatOk, "EFGH"},
+ };
+
+ int j{0};
+ for (auto &inputItem : inputItems) {
+ // READ(UNIT=unit, FMT=fmt, ADVANCE='NO', IOSTAT=iostat) inputItem
+ io = IONAME(BeginExternalFormattedInput)(
+ fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+ IONAME(EnableHandlers)(io, true, false, false, false, false);
+ ASSERT_TRUE(IONAME(SetAdvance)(io, "NO", 2)) << "SetAdvance(NO)" << j;
+ ASSERT_TRUE(
+ IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length()))
+ << "InputAscii() " << j;
+ ASSERT_EQ(IONAME(EndIoStatement)(io), inputItem.expectedIoStat)
+ << "EndIoStatement() for Read " << j;
+ ASSERT_EQ(inputItem.item, inputItem.expectedItemValue)
+ << "Input-item value after non advancing read " << j;
+ j++;
+ }
+
+ // WRITE(UNIT=unit, FMT=fmt, IOSTAT=iostat) outputItem.
+ static constexpr std::string_view outputItem{"XYZ"};
+ // WRITE(UNIT=unit,FMT=fmt) record
+ io = IONAME(BeginExternalFormattedOutput)(
+ fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+ ASSERT_TRUE(IONAME(OutputAscii)(io, outputItem.data(), outputItem.length()))
+ << "OutputAscii()";
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for OutputAscii";
+
+ // Verify that the output was written in the record read in non advancing
+ // mode, after the read part, and that the end was truncated.
+
+ // REWIND(UNIT=unit)
+ io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Rewind";
+
+ std::string resultRecord(20, '+');
+ std::string expectedRecord{"ABCDEFGHXYZ "};
+ // READ(UNIT=unit, FMT=fmt, IOSTAT=iostat) result
+ io = IONAME(BeginExternalFormattedInput)(
+ fmt.data(), fmt.length(), nullptr, unit, __FILE__, __LINE__);
+ IONAME(EnableHandlers)(io, true, false, false, false, false);
+ ASSERT_TRUE(
+ IONAME(InputAscii)(io, resultRecord.data(), resultRecord.length()))
+ << "InputAscii() ";
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Read ";
+ ASSERT_EQ(resultRecord, expectedRecord)
+ << "Record after non advancing read followed by write";
+ // CLOSE(UNIT=unit)
+ io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
+ ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk)
+ << "EndIoStatement() for Close";
+}
TEST(ExternalIOTests, TestWriteAfterEndfile) {
// OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
diff --git a/flang/unittests/Runtime/Format.cpp b/flang/unittests/Runtime/Format.cpp
index cdcdc19aff54a..01803c628de26 100644
--- a/flang/unittests/Runtime/Format.cpp
+++ b/flang/unittests/Runtime/Format.cpp
@@ -145,18 +145,18 @@ TEST(FormatTests, FormatStringTraversal) {
struct InvalidFormatFailure : CrashHandlerFixture {};
-// TEST(InvalidFormatFailure, ParenMismatch) {
-// static constexpr const char *format{"("};
-// static constexpr int repeat{1};
-
-// TestFormatContext context;
-// FormatControl<decltype(context)> control{
-// context, format, std::strlen(format)};
-
-// ASSERT_DEATH(
-// context.Report(/*edit=*/control.GetNextDataEdit(context, repeat)),
-// R"(FORMAT missing at least one '\)')");
-// }
+TEST(InvalidFormatFailure, ParenMismatch) {
+ static constexpr const char *format{"("};
+ static constexpr int repeat{1};
+
+ TestFormatContext context;
+ FormatControl<decltype(context)> control{
+ context, format, std::strlen(format)};
+
+ ASSERT_DEATH(
+ context.Report(/*edit=*/control.GetNextDataEdit(context, repeat)),
+ R"(FORMAT missing at least one '\)')");
+}
TEST(InvalidFormatFailure, MissingPrecision) {
static constexpr const char *format{"(F9.)"};
diff --git a/flang/unittests/Runtime/ListInputTest.cpp b/flang/unittests/Runtime/ListInputTest.cpp
index c53a10a0af640..a4eba5283add6 100644
--- a/flang/unittests/Runtime/ListInputTest.cpp
+++ b/flang/unittests/Runtime/ListInputTest.cpp
@@ -155,35 +155,35 @@ using ParamTy = std::tuple<std::string, std::vector<int>>;
struct SimpleListInputTest : testing::TestWithParam<ParamTy> {};
-// TEST_P(SimpleListInputTest, TestListInput) {
-// auto [formatBuffer, expectedOutput] = GetParam();
-// constexpr int numBuffers{1};
-
-// StaticDescriptor<1> staticDescriptor;
-// Descriptor &whole{staticDescriptor.descriptor()};
-// SubscriptValue extent[]{numBuffers};
-// whole.Establish(TypeCode{CFI_type_char}, formatBuffer.size(),
-// formatBuffer.data(), 1, extent, CFI_attribute_pointer);
-// whole.Check();
-// auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
-
-// const auto listInputLength{expectedOutput.size()};
-// std::vector<std::int64_t> actualOutput(listInputLength);
-// for (std::size_t j = 0; j < listInputLength; ++j) {
-// IONAME(InputInteger)(cookie, actualOutput[j]);
-// }
-
-// const auto status{IONAME(EndIoStatement)(cookie)};
-// ASSERT_EQ(status, 0) << "list-directed input failed, status "
-// << static_cast<int>(status) << '\n';
-
-// // Verify the calls to _InputInteger_ resulted in _expectedOutput_
-// for (std::size_t j = 0; j < listInputLength; ++j) {
-// ASSERT_EQ(actualOutput[j], expectedOutput[j])
-// << "wanted actualOutput[" << j << "]==" << expectedOutput[j] << ", got "
-// << actualOutput[j] << '\n';
-// }
-// }
+TEST_P(SimpleListInputTest, TestListInput) {
+ auto [formatBuffer, expectedOutput] = GetParam();
+ constexpr int numBuffers{1};
+
+ StaticDescriptor<1> staticDescriptor;
+ Descriptor &whole{staticDescriptor.descriptor()};
+ SubscriptValue extent[]{numBuffers};
+ whole.Establish(TypeCode{CFI_type_char}, formatBuffer.size(),
+ formatBuffer.data(), 1, extent, CFI_attribute_pointer);
+ whole.Check();
+ auto *cookie{IONAME(BeginInternalArrayListInput)(whole)};
+
+ const auto listInputLength{expectedOutput.size()};
+ std::vector<std::int64_t> actualOutput(listInputLength);
+ for (std::size_t j = 0; j < listInputLength; ++j) {
+ IONAME(InputInteger)(cookie, actualOutput[j]);
+ }
+
+ const auto status{IONAME(EndIoStatement)(cookie)};
+ ASSERT_EQ(status, 0) << "list-directed input failed, status "
+ << static_cast<int>(status) << '\n';
+
+ // Verify the calls to _InputInteger_ resulted in _expectedOutput_
+ for (std::size_t j = 0; j < listInputLength; ++j) {
+ ASSERT_EQ(actualOutput[j], expectedOutput[j])
+ << "wanted actualOutput[" << j << "]==" << expectedOutput[j] << ", got "
+ << actualOutput[j] << '\n';
+ }
+}
INSTANTIATE_TEST_SUITE_P(SimpleListInputTestInstantiation, SimpleListInputTest,
testing::Values(std::make_tuple("", std::vector<int>{}),
diff --git a/flang/unittests/Runtime/MiscIntrinsic.cpp b/flang/unittests/Runtime/MiscIntrinsic.cpp
index 6dff30a5c1efc..7e19ed250bdc0 100644
--- a/flang/unittests/Runtime/MiscIntrinsic.cpp
+++ b/flang/unittests/Runtime/MiscIntrinsic.cpp
@@ -68,21 +68,21 @@ TEST(MiscIntrinsic, TransferSize) {
EXPECT_EQ(result.OffsetElement<float>()[1], 2.2F);
result.Destroy();
}
-// TEST(MiscIntrinsic, TransferSizeScalarMold) {
-// StaticDescriptor<2, true, 2> staticDesc[2];
-// auto &result{staticDesc[0].descriptor()};
-// std::complex<float> sourecStorage{1.1F, -2.2F};
-// auto source{Descriptor::Create(TypeCategory::Complex, 4,
-// reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
-// CFI_attribute_pointer)};
-// auto &mold{staticDesc[1].descriptor()};
-// mold.Establish(TypeCategory::Real, 4, nullptr, 0, nullptr);
-// RTNAME(TransferSize)(result, *source, mold, __FILE__, __LINE__, 2);
-// EXPECT_EQ(result.rank(), 1);
-// EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
-// EXPECT_EQ(result.GetDimension(0).Extent(), 2);
-// EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Real, 4}.raw()));
-// EXPECT_EQ(result.OffsetElement<float>()[0], 1.1F);
-// EXPECT_EQ(result.OffsetElement<float>()[1], -2.2F);
-// result.Destroy();
-// }
+TEST(MiscIntrinsic, TransferSizeScalarMold) {
+ StaticDescriptor<2, true, 2> staticDesc[2];
+ auto &result{staticDesc[0].descriptor()};
+ std::complex<float> sourecStorage{1.1F, -2.2F};
+ auto source{Descriptor::Create(TypeCategory::Complex, 4,
+ reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
+ CFI_attribute_pointer)};
+ auto &mold{staticDesc[1].descriptor()};
+ mold.Establish(TypeCategory::Real, 4, nullptr, 0, nullptr);
+ RTNAME(TransferSize)(result, *source, mold, __FILE__, __LINE__, 2);
+ EXPECT_EQ(result.rank(), 1);
+ EXPECT_EQ(result.GetDimension(0).LowerBound(), 1);
+ EXPECT_EQ(result.GetDimension(0).Extent(), 2);
+ EXPECT_EQ(result.type().raw(), (TypeCode{TypeCategory::Real, 4}.raw()));
+ EXPECT_EQ(result.OffsetElement<float>()[0], 1.1F);
+ EXPECT_EQ(result.OffsetElement<float>()[1], -2.2F);
+ result.Destroy();
+}
diff --git a/flang/unittests/Runtime/Numeric.cpp b/flang/unittests/Runtime/Numeric.cpp
index 98ec88abf9a93..b69ff21ea79fb 100644
--- a/flang/unittests/Runtime/Numeric.cpp
+++ b/flang/unittests/Runtime/Numeric.cpp
@@ -31,15 +31,15 @@ TEST(Numeric, Floor) {
EXPECT_EQ(RTNAME(Floor4_1)(Real<4>{0}), 0);
}
-// TEST(Numeric, Exponent) {
-// EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
-// EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
-// EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3);
-// EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()),
-// std::numeric_limits<Int<8>>::max());
-// EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()),
-// std::numeric_limits<Int<8>>::max());
-// }
+TEST(Numeric, Exponent) {
+ EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
+ EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
+ EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3);
+ EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()),
+ std::numeric_limits<Int<8>>::max());
+ EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()),
+ std::numeric_limits<Int<8>>::max());
+}
TEST(Numeric, Fraction) {
EXPECT_EQ(RTNAME(Fraction4)(Real<4>{0}), 0);
@@ -192,57 +192,57 @@ TEST(Numeric, SelectedIntKind) {
EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r5, 4), -1);
}
-// TEST(Numeric, SelectedRealKind) {
-// std::int8_t p_s = 1;
-// std::int16_t p[11] = {-10, 1, 1, 4, 50, 1, 1, 4, 1, 1, 50};
-// std::int32_t r[11] = {-1, 1, 1, 1, 2, 1, 20, 20, 100, 5000, 5000};
-// std::int64_t d[11] = {2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2};
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[0], 2, &r[0], 4, &d[0], 8),
-// 2);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[1], 2, &r[1], 4, &d[1], 8),
-// -5);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[2], 2, &r[2], 4, &d[2], 8),
-// 2);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[3], 2, &r[3], 4, &d[3], 8),
-// 4);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[4], 2, &r[4], 4, &d[4], 8),
-// -1);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[5], 2, &r[5], 4, &d[5], 8),
-// 2);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[6], 2, &r[6], 4, &d[6], 8),
-// 3);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[7], 2, &r[7], 4, &d[7], 8),
-// 4);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[8], 2, &r[8], 4, &d[8], 8),
-// 8);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[9], 2, &r[9], 4, &d[9], 8),
-// -2);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[10], 2, &r[10], 4, &d[10], 8),
-// -3);
-// EXPECT_EQ(
-// RTNAME(SelectedRealKind)(__FILE__, __LINE__, &p_s, 1, &r[0], 4, &d[0], 8),
-// 2);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, nullptr, 0, &r[0], 4, &d[0], 8),
-// 2);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[0], 2, nullptr, 0, &d[0], 8),
-// 2);
-// EXPECT_EQ(RTNAME(SelectedRealKind)(
-// __FILE__, __LINE__, &p[0], 2, &r[0], 4, nullptr, 0),
-// 2);
-// }
+TEST(Numeric, SelectedRealKind) {
+ std::int8_t p_s = 1;
+ std::int16_t p[11] = {-10, 1, 1, 4, 50, 1, 1, 4, 1, 1, 50};
+ std::int32_t r[11] = {-1, 1, 1, 1, 2, 1, 20, 20, 100, 5000, 5000};
+ std::int64_t d[11] = {2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2};
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[0], 2, &r[0], 4, &d[0], 8),
+ 2);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[1], 2, &r[1], 4, &d[1], 8),
+ -5);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[2], 2, &r[2], 4, &d[2], 8),
+ 2);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[3], 2, &r[3], 4, &d[3], 8),
+ 4);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[4], 2, &r[4], 4, &d[4], 8),
+ -1);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[5], 2, &r[5], 4, &d[5], 8),
+ 2);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[6], 2, &r[6], 4, &d[6], 8),
+ 3);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[7], 2, &r[7], 4, &d[7], 8),
+ 4);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[8], 2, &r[8], 4, &d[8], 8),
+ 8);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[9], 2, &r[9], 4, &d[9], 8),
+ -2);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[10], 2, &r[10], 4, &d[10], 8),
+ -3);
+ EXPECT_EQ(
+ RTNAME(SelectedRealKind)(__FILE__, __LINE__, &p_s, 1, &r[0], 4, &d[0], 8),
+ 2);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, nullptr, 0, &r[0], 4, &d[0], 8),
+ 2);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[0], 2, nullptr, 0, &d[0], 8),
+ 2);
+ EXPECT_EQ(RTNAME(SelectedRealKind)(
+ __FILE__, __LINE__, &p[0], 2, &r[0], 4, nullptr, 0),
+ 2);
+}
TEST(Numeric, Spacing) {
EXPECT_EQ(RTNAME(Spacing8)(Real<8>{0}), std::numeric_limits<Real<8>>::min());
diff --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp
index d480e41268b6b..2a9f8f8d1dc4f 100644
--- a/flang/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang/unittests/Runtime/NumericalFormatTest.cpp
@@ -336,21 +336,21 @@ TEST(IOApiTests, FormatOnes) {
}
}
-// TEST(IOApiTests, FormatNegativeOnes) {
-// static constexpr std::tuple<const char *, const char *> negOnes[]{
-// {"(E32.17,';')", " -0.10000000000000000E+01;"},
-// {"(F32.17,';')", " -1.00000000000000000;"},
-// {"(G32.17,';')", " -1.0000000000000000 ;"},
-// {"(EX32.17,';')", " -0X8.00000000000000000P-3;"},
-// {"(G0,';')", "-1.;"},
-// };
-// for (auto const &[format, expect] : negOnes) {
-// std::string got;
-// ASSERT_TRUE(CompareFormatReal(format, -1.0, expect, got))
-// << "Failed to format " << format << ", expected '" << expect
-// << "', got '" << got << "'";
-// }
-// }
+TEST(IOApiTests, FormatNegativeOnes) {
+ static constexpr std::tuple<const char *, const char *> negOnes[]{
+ {"(E32.17,';')", " -0.10000000000000000E+01;"},
+ {"(F32.17,';')", " -1.00000000000000000;"},
+ {"(G32.17,';')", " -1.0000000000000000 ;"},
+ {"(EX32.17,';')", " -0X8.00000000000000000P-3;"},
+ {"(G0,';')", "-1.;"},
+ };
+ for (auto const &[format, expect] : negOnes) {
+ std::string got;
+ ASSERT_TRUE(CompareFormatReal(format, -1.0, expect, got))
+ << "Failed to format " << format << ", expected '" << expect
+ << "', got '" << got << "'";
+ }
+}
// Each test case contains a raw uint64, a format string for a real value, and
// the expected resulting string from formatting the raw uint64. The double
diff --git a/flang/unittests/Runtime/Pointer.cpp b/flang/unittests/Runtime/Pointer.cpp
index 30edf82fbcf13..4ce13ebc50a56 100644
--- a/flang/unittests/Runtime/Pointer.cpp
+++ b/flang/unittests/Runtime/Pointer.cpp
@@ -64,25 +64,25 @@ TEST(Pointer, DeallocatePolymorphic) {
(*p, nullptr, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__);
}
-// TEST(Pointer, AllocateFromScalarSource) {
-// // REAL(4), POINTER :: p(:)
-// auto p{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4}, 4,
-// nullptr, 1, nullptr, CFI_attribute_pointer)};
-// // ALLOCATE(p(2:11), SOURCE=3.4)
-// float sourecStorage{3.4F};
-// auto s{Descriptor::Create(Fortran::common::TypeCategory::Real, 4,
-// reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
-// CFI_attribute_pointer)};
-// RTNAME(PointerSetBounds)(*p, 0, 2, 11);
-// RTNAME(PointerAllocateSource)
-// (*p, *s, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__);
-// EXPECT_TRUE(RTNAME(PointerIsAssociated)(*p));
-// EXPECT_EQ(p->Elements(), 10u);
-// EXPECT_EQ(p->GetDimension(0).LowerBound(), 2);
-// EXPECT_EQ(p->GetDimension(0).UpperBound(), 11);
-// EXPECT_EQ(*p->OffsetElement<float>(), 3.4F);
-// p->Destroy();
-// }
+TEST(Pointer, AllocateFromScalarSource) {
+ // REAL(4), POINTER :: p(:)
+ auto p{Descriptor::Create(TypeCode{Fortran::common::TypeCategory::Real, 4}, 4,
+ nullptr, 1, nullptr, CFI_attribute_pointer)};
+ // ALLOCATE(p(2:11), SOURCE=3.4)
+ float sourecStorage{3.4F};
+ auto s{Descriptor::Create(Fortran::common::TypeCategory::Real, 4,
+ reinterpret_cast<void *>(&sourecStorage), 0, nullptr,
+ CFI_attribute_pointer)};
+ RTNAME(PointerSetBounds)(*p, 0, 2, 11);
+ RTNAME(PointerAllocateSource)
+ (*p, *s, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__);
+ EXPECT_TRUE(RTNAME(PointerIsAssociated)(*p));
+ EXPECT_EQ(p->Elements(), 10u);
+ EXPECT_EQ(p->GetDimension(0).LowerBound(), 2);
+ EXPECT_EQ(p->GetDimension(0).UpperBound(), 11);
+ EXPECT_EQ(*p->OffsetElement<float>(), 3.4F);
+ p->Destroy();
+}
TEST(Pointer, AllocateSourceZeroSize) {
using Fortran::common::TypeCategory;
diff --git a/flang/unittests/Runtime/RuntimeCrashTest.cpp b/flang/unittests/Runtime/RuntimeCrashTest.cpp
index 0753f76f23cc3..a649051fdca0c 100644
--- a/flang/unittests/Runtime/RuntimeCrashTest.cpp
+++ b/flang/unittests/Runtime/RuntimeCrashTest.cpp
@@ -53,15 +53,15 @@ TEST(TestTerminator, CheckFailedTest) {
//------------------------------------------------------------------------------
struct TestIOCrash : CrashHandlerFixture {};
-// TEST(TestIOCrash, InvalidFormatCharacterTest) {
-// static constexpr int bufferSize{1};
-// static char buffer[bufferSize];
-// static const char *format{"(C1)"};
-// auto *cookie{IONAME(BeginInternalFormattedOutput)(
-// buffer, bufferSize, format, std::strlen(format))};
-// ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xfeedface),
-// "Unknown 'C' edit descriptor in FORMAT");
-// }
+TEST(TestIOCrash, InvalidFormatCharacterTest) {
+ static constexpr int bufferSize{1};
+ static char buffer[bufferSize];
+ static const char *format{"(C1)"};
+ auto *cookie{IONAME(BeginInternalFormattedOutput)(
+ buffer, bufferSize, format, std::strlen(format))};
+ ASSERT_DEATH(IONAME(OutputInteger64)(cookie, 0xfeedface),
+ "Unknown 'C' edit descriptor in FORMAT");
+}
//------------------------------------------------------------------------------
/// Test buffer overwrites with Output* functions
diff --git a/flang/unittests/Runtime/Stop.cpp b/flang/unittests/Runtime/Stop.cpp
index 24c78251ea697..b13602eaee5ea 100644
--- a/flang/unittests/Runtime/Stop.cpp
+++ b/flang/unittests/Runtime/Stop.cpp
@@ -32,24 +32,24 @@ TEST(TestProgramEnd, StopTestNoStopMessage) {
RTNAME(StopStatement)(), testing::ExitedWithCode(EXIT_SUCCESS), "");
}
-// TEST(TestProgramEnd, StopMessageTest) {
-// static const char *message{"bye bye"};
-// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
-// /*isErrorStop=*/false, /*quiet=*/false),
-// testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye");
-
-// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
-// /*isErrorStop=*/false, /*quiet=*/true),
-// testing::ExitedWithCode(EXIT_SUCCESS), "");
-
-// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
-// /*isErrorStop=*/true, /*quiet=*/false),
-// testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
-
-// EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
-// /*isErrorStop=*/true, /*quiet=*/true),
-// testing::ExitedWithCode(EXIT_FAILURE), "");
-// }
+TEST(TestProgramEnd, StopMessageTest) {
+ static const char *message{"bye bye"};
+ EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+ /*isErrorStop=*/false, /*quiet=*/false),
+ testing::ExitedWithCode(EXIT_SUCCESS), "Fortran STOP: bye bye");
+
+ EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+ /*isErrorStop=*/false, /*quiet=*/true),
+ testing::ExitedWithCode(EXIT_SUCCESS), "");
+
+ EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+ /*isErrorStop=*/true, /*quiet=*/false),
+ testing::ExitedWithCode(EXIT_FAILURE), "Fortran ERROR STOP: bye bye");
+
+ EXPECT_EXIT(RTNAME(StopStatementText)(message, std::strlen(message),
+ /*isErrorStop=*/true, /*quiet=*/true),
+ testing::ExitedWithCode(EXIT_FAILURE), "");
+}
TEST(TestProgramEnd, NoStopMessageTest) {
putenv(const_cast<char *>("NO_STOP_MESSAGE=1"));
diff --git a/flang/unittests/Runtime/TemporaryStack.cpp b/flang/unittests/Runtime/TemporaryStack.cpp
index 8b9aac99309ad..0a9344969ca6b 100644
--- a/flang/unittests/Runtime/TemporaryStack.cpp
+++ b/flang/unittests/Runtime/TemporaryStack.cpp
@@ -87,86 +87,86 @@ static unsigned max(unsigned x, unsigned y) {
return y;
}
-// TEST(TemporaryStack, ValueStackMultiSize) {
-// constexpr unsigned numToTest = 42;
-// const TypeCode code{CFI_type_int32_t};
-// constexpr size_t elementBytes = 4;
-// SubscriptValue extent[CFI_MAX_RANK];
-
-// std::vector<OwningPtr<Descriptor>> inputDescriptors;
-// inputDescriptors.reserve(numToTest);
-
-// void *storage = RTNAME(CreateValueStack)(__FILE__, __LINE__);
-// ASSERT_NE(storage, nullptr);
-
-// // create descriptors with and without adendums
-// auto getAdendum = [](unsigned i) { return i % 2; };
-// // create descriptors with varying ranks
-// auto getRank = [](unsigned i) { return max(i % 8, 1); };
-
-// // push descriptors of varying sizes and contents
-// for (unsigned i = 0; i < numToTest; ++i) {
-// const bool adendum = getAdendum(i);
-// const size_t rank = getRank(i);
-// for (unsigned dim = 0; dim < rank; ++dim) {
-// extent[dim] = ((i + dim) % 8) + 1;
-// }
-
-// const OwningPtr<Descriptor> &desc =
-// inputDescriptors.emplace_back(Descriptor::Create(code, elementBytes,
-// nullptr, rank, extent, CFI_attribute_allocatable, adendum));
-
-// // Descriptor::Establish doesn't initialise the extents if baseaddr is null
-// for (unsigned dim = 0; dim < rank; ++dim) {
-// Fortran::ISO::CFI_dim_t &boxDims = desc->raw().dim[dim];
-// boxDims.lower_bound = 1;
-// boxDims.extent = extent[dim];
-// boxDims.sm = elementBytes;
-// }
-// desc->Allocate();
-
-// // fill the array with some data to test
-// for (uint32_t i = 0; i < desc->Elements(); ++i) {
-// uint32_t *data = static_cast<uint32_t *>(desc->raw().base_addr);
-// ASSERT_NE(data, nullptr);
-// data[i] = i;
-// }
-
-// RTNAME(PushValue)(storage, *desc.get());
-// }
-
-// const TypeCode boolCode{CFI_type_Bool};
-// // peek and test each descriptor
-// for (unsigned i = 0; i < numToTest; ++i) {
-// const OwningPtr<Descriptor> &input = inputDescriptors[i];
-// const bool adendum = getAdendum(i);
-// const size_t rank = getRank(i);
-
-// // buffer to return the descriptor into
-// OwningPtr<Descriptor> out = Descriptor::Create(
-// boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
-
-// (void)input;
-// RTNAME(ValueAt)(storage, i, *out.get());
-// descriptorAlmostEqual(*input, *out);
-// }
-
-// // pop and test each descriptor
-// for (unsigned i = numToTest; i > 0; --i) {
-// const OwningPtr<Descriptor> &input = inputDescriptors[i - 1];
-// const bool adendum = getAdendum(i - 1);
-// const size_t rank = getRank(i - 1);
-
-// // buffer to return the descriptor into
-// OwningPtr<Descriptor> out = Descriptor::Create(
-// boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
-
-// RTNAME(PopValue)(storage, *out.get());
-// descriptorAlmostEqual(*input, *out);
-// }
-
-// RTNAME(DestroyValueStack)(storage);
-// }
+TEST(TemporaryStack, ValueStackMultiSize) {
+ constexpr unsigned numToTest = 42;
+ const TypeCode code{CFI_type_int32_t};
+ constexpr size_t elementBytes = 4;
+ SubscriptValue extent[CFI_MAX_RANK];
+
+ std::vector<OwningPtr<Descriptor>> inputDescriptors;
+ inputDescriptors.reserve(numToTest);
+
+ void *storage = RTNAME(CreateValueStack)(__FILE__, __LINE__);
+ ASSERT_NE(storage, nullptr);
+
+ // create descriptors with and without adendums
+ auto getAdendum = [](unsigned i) { return i % 2; };
+ // create descriptors with varying ranks
+ auto getRank = [](unsigned i) { return max(i % 8, 1); };
+
+ // push descriptors of varying sizes and contents
+ for (unsigned i = 0; i < numToTest; ++i) {
+ const bool adendum = getAdendum(i);
+ const size_t rank = getRank(i);
+ for (unsigned dim = 0; dim < rank; ++dim) {
+ extent[dim] = ((i + dim) % 8) + 1;
+ }
+
+ const OwningPtr<Descriptor> &desc =
+ inputDescriptors.emplace_back(Descriptor::Create(code, elementBytes,
+ nullptr, rank, extent, CFI_attribute_allocatable, adendum));
+
+ // Descriptor::Establish doesn't initialise the extents if baseaddr is null
+ for (unsigned dim = 0; dim < rank; ++dim) {
+ Fortran::ISO::CFI_dim_t &boxDims = desc->raw().dim[dim];
+ boxDims.lower_bound = 1;
+ boxDims.extent = extent[dim];
+ boxDims.sm = elementBytes;
+ }
+ desc->Allocate();
+
+ // fill the array with some data to test
+ for (uint32_t i = 0; i < desc->Elements(); ++i) {
+ uint32_t *data = static_cast<uint32_t *>(desc->raw().base_addr);
+ ASSERT_NE(data, nullptr);
+ data[i] = i;
+ }
+
+ RTNAME(PushValue)(storage, *desc.get());
+ }
+
+ const TypeCode boolCode{CFI_type_Bool};
+ // peek and test each descriptor
+ for (unsigned i = 0; i < numToTest; ++i) {
+ const OwningPtr<Descriptor> &input = inputDescriptors[i];
+ const bool adendum = getAdendum(i);
+ const size_t rank = getRank(i);
+
+ // buffer to return the descriptor into
+ OwningPtr<Descriptor> out = Descriptor::Create(
+ boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
+
+ (void)input;
+ RTNAME(ValueAt)(storage, i, *out.get());
+ descriptorAlmostEqual(*input, *out);
+ }
+
+ // pop and test each descriptor
+ for (unsigned i = numToTest; i > 0; --i) {
+ const OwningPtr<Descriptor> &input = inputDescriptors[i - 1];
+ const bool adendum = getAdendum(i - 1);
+ const size_t rank = getRank(i - 1);
+
+ // buffer to return the descriptor into
+ OwningPtr<Descriptor> out = Descriptor::Create(
+ boolCode, 1, nullptr, rank, extent, CFI_attribute_other, adendum);
+
+ RTNAME(PopValue)(storage, *out.get());
+ descriptorAlmostEqual(*input, *out);
+ }
+
+ RTNAME(DestroyValueStack)(storage);
+}
TEST(TemporaryStack, DescriptorStackBasic) {
const TypeCode code{CFI_type_Bool};
>From e278a9d5100149068754a20abb931b79bb78e923 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 22:40:05 +0300
Subject: [PATCH 11/30] Comment out all flang tests
---
flang/unittests/CMakeLists.txt | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/flang/unittests/CMakeLists.txt b/flang/unittests/CMakeLists.txt
index 72d37ebeb853c..f04b91497b172 100644
--- a/flang/unittests/CMakeLists.txt
+++ b/flang/unittests/CMakeLists.txt
@@ -70,9 +70,9 @@ function(add_flang_nongtest_unittest test_name)
add_flang_unittest_offload_properties(${test_name}${suffix})
endfunction()
-add_subdirectory(Optimizer)
-add_subdirectory(Common)
-add_subdirectory(Decimal)
-add_subdirectory(Evaluate)
-add_subdirectory(Runtime)
-add_subdirectory(Frontend)
+# add_subdirectory(Optimizer)
+# add_subdirectory(Common)
+# add_subdirectory(Decimal)
+# add_subdirectory(Evaluate)
+# add_subdirectory(Runtime)
+# add_subdirectory(Frontend)
>From 2d65aef22fb869b9e3b8c0fd9f7e685029f4537b Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 23:11:27 +0300
Subject: [PATCH 12/30] Disable stack-arrays.f90 test
---
.../Transforms/{stack-arrays.f90 => stack-arrays.f90.disabled} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename flang/test/Transforms/{stack-arrays.f90 => stack-arrays.f90.disabled} (100%)
diff --git a/flang/test/Transforms/stack-arrays.f90 b/flang/test/Transforms/stack-arrays.f90.disabled
similarity index 100%
rename from flang/test/Transforms/stack-arrays.f90
rename to flang/test/Transforms/stack-arrays.f90.disabled
>From 7a42c1108843f1ec6a620db676a8fc95baf8494d Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 23:32:26 +0300
Subject: [PATCH 13/30] More debug printing
---
llvm/utils/lit/lit/main.py | 1 +
llvm/utils/lit/lit/run.py | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py
index 09354b3092d8a..9c9c1aae304af 100755
--- a/llvm/utils/lit/lit/main.py
+++ b/llvm/utils/lit/lit/main.py
@@ -271,6 +271,7 @@ def run_tests(tests, lit_config, opts, discovered_tests):
print("Endill 320")
display = lit.display.create_display(opts, tests, discovered_tests, workers)
print("Endill 330")
+ print("Endill opts.timeout: {}".format(opts.timeout))
run = lit.run.Run(
tests, lit_config, workers, display.update, opts.max_failures, opts.timeout
)
diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py
index 54482071a67b2..e1354d54fc346 100644
--- a/llvm/utils/lit/lit/run.py
+++ b/llvm/utils/lit/lit/run.py
@@ -86,6 +86,11 @@ def _execute(self, deadline):
)
print("Endill 365130")
+ def debug_callback(arg):
+ print("Endill: debug_callback test.file_path: {}".format(arg.file_path))
+ print("Endill: debug_callback test.path_in_suite: {}".format(arg.path_in_suite))
+ self.progress_callback(arg)
+
async_results = [
pool.apply_async(
lit.worker.execute, args=[test], callback=self.progress_callback
@@ -117,6 +122,9 @@ def _wait_for(self, async_results, deadline):
print("Endill 3651610")
try:
print("Endill 3651620")
+ print("Endill: idx: {}".format(idx))
+ print("Endill: tests[idx].file_path: {}".format(self.tests[idx].file_path))
+ print("Endill: tests[idx].path_in_suite: {}".format(self.tests[idx].path_in_suite))
test = ar.get(timeout)
print("Endill 3651630")
print("Endill: test.file_path: {}".format(test.file_path))
>From 35e8acdc5015e60ad19a2ef30aa6de2c6a86543c Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Sun, 19 May 2024 23:58:30 +0300
Subject: [PATCH 14/30] Add prints to worker
---
llvm/utils/lit/lit/run.py | 2 +-
llvm/utils/lit/lit/worker.py | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py
index e1354d54fc346..61b14abe124f5 100644
--- a/llvm/utils/lit/lit/run.py
+++ b/llvm/utils/lit/lit/run.py
@@ -93,7 +93,7 @@ def debug_callback(arg):
async_results = [
pool.apply_async(
- lit.worker.execute, args=[test], callback=self.progress_callback
+ lit.worker.execute, args=[test], callback=debug_callback
)
for test in self.tests
]
diff --git a/llvm/utils/lit/lit/worker.py b/llvm/utils/lit/lit/worker.py
index 8e78bfd45d38b..5de0e83d4da82 100644
--- a/llvm/utils/lit/lit/worker.py
+++ b/llvm/utils/lit/lit/worker.py
@@ -41,10 +41,14 @@ def execute(test):
Arguments and results of this function are pickled, so they should be cheap
to copy.
"""
+ print("Endill: worker 1")
with _get_parallelism_semaphore(test):
+ print("Endill: worker 2")
result = _execute(test, _lit_config)
+ print("Endill: worker 3")
test.setResult(result)
+ print("Endill: worker 4")
return test
@@ -55,40 +59,60 @@ def NopSemaphore():
def _get_parallelism_semaphore(test):
+ print("Endill: worker 1-1")
pg = test.config.parallelism_group
if callable(pg):
+ print("Endill: worker 1-2")
pg = pg(test)
+ print("Endill: worker 1-3")
+ print("Endill: pg in _parallelism_semaphores: {}".format(pg in _parallelism_semaphores))
return _parallelism_semaphores.get(pg, NopSemaphore())
# Do not inline! Directly used by LitTestCase.py
def _execute(test, lit_config):
+ print("Endill: worker 2-1")
start = time.time()
+ print("Endill: worker 2-2")
result = _execute_test_handle_errors(test, lit_config)
+ print("Endill: worker 2-3")
result.elapsed = time.time() - start
+ print("Endill: worker 2-4")
result.start = start
+ print("Endill: worker 2-5")
result.pid = os.getpid()
+ print("Endill: worker 2-6")
return result
def _execute_test_handle_errors(test, lit_config):
+ print("Endill: worker 2-2-1")
try:
+ print("Endill: worker 2-2-2")
result = test.config.test_format.execute(test, lit_config)
+ print("Endill: worker 2-2-3")
return _adapt_result(result)
except:
+ print("Endill: worker 2-2-4")
if lit_config.debug:
+ print("Endill: worker 2-2-5")
raise
output = "Exception during script execution:\n"
output += traceback.format_exc()
output += "\n"
+ print("Endill: worker 2-2-5")
return lit.Test.Result(lit.Test.UNRESOLVED, output)
+
# Support deprecated result from execute() which returned the result
# code and additional output as a tuple.
def _adapt_result(result):
+ print("Endill: worker 2-2-3-1")
if isinstance(result, lit.Test.Result):
+ print("Endill: worker 2-2-3-2")
return result
assert isinstance(result, tuple)
code, output = result
+ print("Endill: worker 2-2-3-3")
return lit.Test.Result(code, output)
>From 7708f095c88f5ca3f1c5f34143e7ee8856711e21 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 00:18:24 +0300
Subject: [PATCH 15/30] Disable flang typeinfo tests
---
flang/test/Semantics/{typeinfo01.f90 => typeinfo01.f90.disable} | 0
flang/test/Semantics/{typeinfo02.f90 => typeinfo02.f90.disable} | 0
flang/test/Semantics/{typeinfo03.f90 => typeinfo03.f90.disable} | 0
flang/test/Semantics/{typeinfo04.f90 => typeinfo04.f90.disable} | 0
flang/test/Semantics/{typeinfo05.f90 => typeinfo05.f90.disable} | 0
flang/test/Semantics/{typeinfo06.f90 => typeinfo06.f90.disable} | 0
flang/test/Semantics/{typeinfo07.f90 => typeinfo07.f90.disable} | 0
flang/test/Semantics/{typeinfo08.f90 => typeinfo08.f90.disable} | 0
flang/test/Semantics/{typeinfo09.f90 => typeinfo09.f90.disable} | 0
flang/test/Semantics/{typeinfo10.f90 => typeinfo10.f90.disable} | 0
10 files changed, 0 insertions(+), 0 deletions(-)
rename flang/test/Semantics/{typeinfo01.f90 => typeinfo01.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo02.f90 => typeinfo02.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo03.f90 => typeinfo03.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo04.f90 => typeinfo04.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo05.f90 => typeinfo05.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo06.f90 => typeinfo06.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo07.f90 => typeinfo07.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo08.f90 => typeinfo08.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo09.f90 => typeinfo09.f90.disable} (100%)
rename flang/test/Semantics/{typeinfo10.f90 => typeinfo10.f90.disable} (100%)
diff --git a/flang/test/Semantics/typeinfo01.f90 b/flang/test/Semantics/typeinfo01.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo01.f90
rename to flang/test/Semantics/typeinfo01.f90.disable
diff --git a/flang/test/Semantics/typeinfo02.f90 b/flang/test/Semantics/typeinfo02.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo02.f90
rename to flang/test/Semantics/typeinfo02.f90.disable
diff --git a/flang/test/Semantics/typeinfo03.f90 b/flang/test/Semantics/typeinfo03.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo03.f90
rename to flang/test/Semantics/typeinfo03.f90.disable
diff --git a/flang/test/Semantics/typeinfo04.f90 b/flang/test/Semantics/typeinfo04.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo04.f90
rename to flang/test/Semantics/typeinfo04.f90.disable
diff --git a/flang/test/Semantics/typeinfo05.f90 b/flang/test/Semantics/typeinfo05.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo05.f90
rename to flang/test/Semantics/typeinfo05.f90.disable
diff --git a/flang/test/Semantics/typeinfo06.f90 b/flang/test/Semantics/typeinfo06.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo06.f90
rename to flang/test/Semantics/typeinfo06.f90.disable
diff --git a/flang/test/Semantics/typeinfo07.f90 b/flang/test/Semantics/typeinfo07.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo07.f90
rename to flang/test/Semantics/typeinfo07.f90.disable
diff --git a/flang/test/Semantics/typeinfo08.f90 b/flang/test/Semantics/typeinfo08.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo08.f90
rename to flang/test/Semantics/typeinfo08.f90.disable
diff --git a/flang/test/Semantics/typeinfo09.f90 b/flang/test/Semantics/typeinfo09.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo09.f90
rename to flang/test/Semantics/typeinfo09.f90.disable
diff --git a/flang/test/Semantics/typeinfo10.f90 b/flang/test/Semantics/typeinfo10.f90.disable
similarity index 100%
rename from flang/test/Semantics/typeinfo10.f90
rename to flang/test/Semantics/typeinfo10.f90.disable
>From 950a2d8a8e3c58ea46d16bd6c02c4e9fc0bc1b48 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 01:07:45 +0300
Subject: [PATCH 16/30] Print test path in worker
---
llvm/utils/lit/lit/worker.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/utils/lit/lit/worker.py b/llvm/utils/lit/lit/worker.py
index 5de0e83d4da82..fe34a24e89699 100644
--- a/llvm/utils/lit/lit/worker.py
+++ b/llvm/utils/lit/lit/worker.py
@@ -44,6 +44,8 @@ def execute(test):
print("Endill: worker 1")
with _get_parallelism_semaphore(test):
print("Endill: worker 2")
+ print("Endill: worker test.file_path: {}".format(test.file_path))
+ print("Endill: worker test.path_in_suite: {}".format(test.path_in_suite))
result = _execute(test, _lit_config)
print("Endill: worker 3")
>From 55ba3195073e5cda0c735eb36870f5ab35727a49 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 01:45:46 +0300
Subject: [PATCH 17/30] Break modfile56.f90 test
---
flang/test/Semantics/modfile56.f90 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/Semantics/modfile56.f90 b/flang/test/Semantics/modfile56.f90
index 9f15e64f9a6e9..36a1c3f07a64e 100644
--- a/flang/test/Semantics/modfile56.f90
+++ b/flang/test/Semantics/modfile56.f90
@@ -4,7 +4,7 @@ module m
real, parameter :: x(0:0) = [0.]
end
-!Expect: m.mod
+!Expect: m.mod2
!module m
!real(4),parameter::x(0_8:0_8)=[REAL(4)::0._4]
!end
>From f77f7b458f5c516b4c58b144c092e1f8faa369d5 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 02:32:52 +0300
Subject: [PATCH 18/30] Add test name to worker 2-5 log
---
llvm/utils/lit/lit/worker.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/utils/lit/lit/worker.py b/llvm/utils/lit/lit/worker.py
index fe34a24e89699..8107da9cc79ad 100644
--- a/llvm/utils/lit/lit/worker.py
+++ b/llvm/utils/lit/lit/worker.py
@@ -81,7 +81,7 @@ def _execute(test, lit_config):
result.elapsed = time.time() - start
print("Endill: worker 2-4")
result.start = start
- print("Endill: worker 2-5")
+ print("Endill: worker 2-5 {}".format(test.path_in_suite))
result.pid = os.getpid()
print("Endill: worker 2-6")
return result
>From 31123032565d2b43f1a32b2947acdf2c2de6e94f Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 03:20:46 +0300
Subject: [PATCH 19/30] Add prints to shell tests
---
llvm/utils/lit/lit/TestRunner.py | 30 ++++++++++++++++++++--
llvm/utils/lit/lit/formats/shtest.py | 1 +
llvm/utils/lit/lit/worker.py | 38 +++++++++++++---------------
3 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py
index da7fa86fd3917..eb26607e8f2ae 100644
--- a/llvm/utils/lit/lit/TestRunner.py
+++ b/llvm/utils/lit/lit/TestRunner.py
@@ -2161,10 +2161,12 @@ def parseIntegratedTestScript(test, additional_parsers=[], require_script=True):
def _runShTest(test, litConfig, useExternalSh, script, tmpBase) -> lit.Test.Result:
+ print("Endill _runShTest 1 {}".format(test.path_in_suite))
# Always returns the tuple (out, err, exitCode, timeoutInfo, status).
def runOnce(
execdir,
) -> Tuple[str, str, int, Optional[str], Test.ResultCode]:
+ print("Endill runOnce 1 {}".format(test.path_in_suite))
# script is modified below (for litConfig.per_test_coverage, and for
# %dbg expansions). runOnce can be called multiple times, but applying
# the modifications multiple times can corrupt script, so always modify
@@ -2172,12 +2174,15 @@ def runOnce(
scriptCopy = script[:]
# Set unique LLVM_PROFILE_FILE for each run command
if litConfig.per_test_coverage:
+ print("Endill runOnce 2 {}".format(test.path_in_suite))
# Extract the test case name from the test object, and remove the
# file extension.
test_case_name = test.path_in_suite[-1]
test_case_name = test_case_name.rsplit(".", 1)[0]
coverage_index = 0 # Counter for coverage file index
+ print("Endill runOnce 3 {}".format(test.path_in_suite))
for i, ln in enumerate(scriptCopy):
+ print("Endill runOnce 4 i={} {}".format(i, test.path_in_suite))
match = re.fullmatch(kPdbgRegex, ln)
if match:
dbg = match.group(1)
@@ -2188,16 +2193,22 @@ def runOnce(
coverage_index += 1
command = f"export LLVM_PROFILE_FILE={profile}; {command}"
if match:
+ print("Endill runOnce 5 i={} {}".format(i, test.path_in_suite))
command = buildPdbgCommand(dbg, command)
scriptCopy[i] = command
+ print("Endill runOnce 6 i={} {}".format(i, test.path_in_suite))
try:
if useExternalSh:
+ print("Endill runOnce 7 {}".format(test.path_in_suite))
res = executeScript(test, litConfig, tmpBase, scriptCopy, execdir)
+ print("Endill runOnce 8 {}".format(test.path_in_suite))
else:
+ print("Endill runOnce 9 {}".format(test.path_in_suite))
res = executeScriptInternal(
test, litConfig, tmpBase, scriptCopy, execdir
)
+ print("Endill runOnce 10 {}".format(test.path_in_suite))
except ScriptFatal as e:
out = f"# " + "\n# ".join(str(e).splitlines()) + "\n"
return out, "", 1, None, Test.UNRESOLVED
@@ -2214,14 +2225,18 @@ def runOnce(
# Create the output directory if it does not already exist.
lit.util.mkdir_p(os.path.dirname(tmpBase))
-
+ print("Endill _runShTest 2 {}".format(test.path_in_suite))
# Re-run failed tests up to test.allowed_retries times.
execdir = os.path.dirname(test.getExecPath())
+ print("Endill _runShTest 3 {}".format(test.path_in_suite))
attempts = test.allowed_retries + 1
for i in range(attempts):
+ print("Endill _runShTest 4 try {} {}".format(i, test.path_in_suite))
res = runOnce(execdir)
+ print("Endill _runShTest 5 {}".format(test.path_in_suite))
out, err, exitCode, timeoutInfo, status = res
if status != Test.FAIL:
+ print("Endill _runShTest 6 {}".format(test.path_in_suite))
break
# If we had to run the test more than once, count it as a flaky pass. These
@@ -2248,31 +2263,42 @@ def runOnce(
def executeShTest(
test, litConfig, useExternalSh, extra_substitutions=[], preamble_commands=[]
):
+ print("Endill executeShTest 1 {}".format(test.path_in_suite))
if test.config.unsupported:
return lit.Test.Result(Test.UNSUPPORTED, "Test is unsupported")
+ print("Endill executeShTest 2 {}".format(test.path_in_suite))
script = list(preamble_commands)
script = [buildPdbgCommand(f"preamble command line", ln) for ln in script]
+ print("Endill executeShTest 3 {}".format(test.path_in_suite))
parsed = parseIntegratedTestScript(test, require_script=not script)
+ print("Endill executeShTest 4 {}".format(test.path_in_suite))
if isinstance(parsed, lit.Test.Result):
return parsed
script += parsed
+ print("Endill executeShTest 5 {}".format(test.path_in_suite))
if litConfig.noExecute:
return lit.Test.Result(Test.PASS)
+ print("Endill executeShTest 6 {}".format(test.path_in_suite))
tmpDir, tmpBase = getTempPaths(test)
+ print("Endill executeShTest 7 {}".format(test.path_in_suite))
substitutions = list(extra_substitutions)
substitutions += getDefaultSubstitutions(
test, tmpDir, tmpBase, normalize_slashes=useExternalSh
)
conditions = {feature: True for feature in test.config.available_features}
+ print("Endill executeShTest 8 {}".format(test.path_in_suite))
script = applySubstitutions(
script,
substitutions,
conditions,
recursion_limit=test.config.recursiveExpansionLimit,
)
+ print("Endill executeShTest 9 {}".format(test.path_in_suite))
+ r = _runShTest(test, litConfig, useExternalSh, script, tmpBase)
+ print("Endill executeShTest 10 {}".format(test.path_in_suite))
- return _runShTest(test, litConfig, useExternalSh, script, tmpBase)
+ return r
diff --git a/llvm/utils/lit/lit/formats/shtest.py b/llvm/utils/lit/lit/formats/shtest.py
index b4dc6f9ed32e2..92e9aad583313 100644
--- a/llvm/utils/lit/lit/formats/shtest.py
+++ b/llvm/utils/lit/lit/formats/shtest.py
@@ -26,6 +26,7 @@ def __init__(
self.preamble_commands = preamble_commands
def execute(self, test, litConfig):
+ print("Endill shtest 1")
return lit.TestRunner.executeShTest(
test,
litConfig,
diff --git a/llvm/utils/lit/lit/worker.py b/llvm/utils/lit/lit/worker.py
index 8107da9cc79ad..98c39e3e51337 100644
--- a/llvm/utils/lit/lit/worker.py
+++ b/llvm/utils/lit/lit/worker.py
@@ -41,16 +41,14 @@ def execute(test):
Arguments and results of this function are pickled, so they should be cheap
to copy.
"""
- print("Endill: worker 1")
+ print("Endill: worker 1 {}".format(test.path_in_suite))
with _get_parallelism_semaphore(test):
- print("Endill: worker 2")
- print("Endill: worker test.file_path: {}".format(test.file_path))
- print("Endill: worker test.path_in_suite: {}".format(test.path_in_suite))
+ print("Endill: worker 2 {}".format(test.path_in_suite))
result = _execute(test, _lit_config)
- print("Endill: worker 3")
+ print("Endill: worker 3 {}".format(test.path_in_suite))
test.setResult(result)
- print("Endill: worker 4")
+ print("Endill: worker 4 {}".format(test.path_in_suite))
return test
@@ -61,48 +59,48 @@ def NopSemaphore():
def _get_parallelism_semaphore(test):
- print("Endill: worker 1-1")
+ print("Endill: worker 1-1 {}".format(test.path_in_suite))
pg = test.config.parallelism_group
if callable(pg):
- print("Endill: worker 1-2")
+ print("Endill: worker 1-2 {}".format(test.path_in_suite))
pg = pg(test)
- print("Endill: worker 1-3")
+ print("Endill: worker 1-3 {}".format(test.path_in_suite))
print("Endill: pg in _parallelism_semaphores: {}".format(pg in _parallelism_semaphores))
return _parallelism_semaphores.get(pg, NopSemaphore())
# Do not inline! Directly used by LitTestCase.py
def _execute(test, lit_config):
- print("Endill: worker 2-1")
+ print("Endill: worker 2-1 {}".format(test.path_in_suite))
start = time.time()
- print("Endill: worker 2-2")
+ print("Endill: worker 2-2 {}".format(test.path_in_suite))
result = _execute_test_handle_errors(test, lit_config)
- print("Endill: worker 2-3")
+ print("Endill: worker 2-3 {}".format(test.path_in_suite))
result.elapsed = time.time() - start
- print("Endill: worker 2-4")
+ print("Endill: worker 2-4 {}".format(test.path_in_suite))
result.start = start
print("Endill: worker 2-5 {}".format(test.path_in_suite))
result.pid = os.getpid()
- print("Endill: worker 2-6")
+ print("Endill: worker 2-6 {}".format(test.path_in_suite))
return result
def _execute_test_handle_errors(test, lit_config):
- print("Endill: worker 2-2-1")
+ print("Endill: worker 2-2-1 {}".format(test.path_in_suite))
try:
- print("Endill: worker 2-2-2")
+ print("Endill: worker 2-2-2 {}".format(test.path_in_suite))
result = test.config.test_format.execute(test, lit_config)
- print("Endill: worker 2-2-3")
+ print("Endill: worker 2-2-3 {}".format(test.path_in_suite))
return _adapt_result(result)
except:
- print("Endill: worker 2-2-4")
+ print("Endill: worker 2-2-4 {}".format(test.path_in_suite))
if lit_config.debug:
- print("Endill: worker 2-2-5")
+ print("Endill: worker 2-2-5 {}".format(test.path_in_suite))
raise
output = "Exception during script execution:\n"
output += traceback.format_exc()
output += "\n"
- print("Endill: worker 2-2-5")
+ print("Endill: worker 2-2-5 {}".format(test.path_in_suite))
return lit.Test.Result(lit.Test.UNRESOLVED, output)
>From a138cbbf2e2be0d087222801b2ba28093ab52cdc Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:02:02 +0300
Subject: [PATCH 20/30] Disable almost all flang test suites
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index 37869e7e2ecd7..e70233341def3 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Analysis", "Driver", "Evaluate", "Fir", "HLFIR", "Integration", "Intrinsic", "lib", "Lower", "NonGtestUnit", "Parser", "Preprocessing", "Runtime", "Semantics", "Transforms", "Unit"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From 247bcb4b816a3c9c2d5e66d8652f69906012cc43 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:08:31 +0300
Subject: [PATCH 21/30] Enable "Analysis", "Driver", "Evaluate"
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index e70233341def3..6a44a9d326f3a 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Analysis", "Driver", "Evaluate", "Fir", "HLFIR", "Integration", "Intrinsic", "lib", "Lower", "NonGtestUnit", "Parser", "Preprocessing", "Runtime", "Semantics", "Transforms", "Unit"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Fir", "HLFIR", "Integration", "Intrinsic", "lib", "Lower", "NonGtestUnit", "Parser", "Preprocessing", "Runtime", "Semantics", "Transforms", "Unit"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From 64c3e6cf4031586c2553fa77efebed1e299b0ef6 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:17:49 +0300
Subject: [PATCH 22/30] Unbreak modfile56.f90 test
---
flang/test/Semantics/modfile56.f90 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/Semantics/modfile56.f90 b/flang/test/Semantics/modfile56.f90
index 36a1c3f07a64e..9f15e64f9a6e9 100644
--- a/flang/test/Semantics/modfile56.f90
+++ b/flang/test/Semantics/modfile56.f90
@@ -4,7 +4,7 @@ module m
real, parameter :: x(0:0) = [0.]
end
-!Expect: m.mod2
+!Expect: m.mod
!module m
!real(4),parameter::x(0_8:0_8)=[REAL(4)::0._4]
!end
>From 2a30096dd143da016d929943808f525658afb6d9 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:18:25 +0300
Subject: [PATCH 23/30] Enable "Fir", "HLFIR", "Integration", "Intrinsic" tests
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index 6a44a9d326f3a..957d783d652f1 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Fir", "HLFIR", "Integration", "Intrinsic", "lib", "Lower", "NonGtestUnit", "Parser", "Preprocessing", "Runtime", "Semantics", "Transforms", "Unit"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "lib", "Lower", "NonGtestUnit", "Parser", "Preprocessing", "Runtime", "Semantics", "Transforms", "Unit"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From 0c74d482d4467f80fba0c9613f4236b84548da04 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:25:08 +0300
Subject: [PATCH 24/30] Enable "lib", "Lower", "NonGtestUnit", "Parser",
"Preprocessing"
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index 957d783d652f1..fef7d052c6e33 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "lib", "Lower", "NonGtestUnit", "Parser", "Preprocessing", "Runtime", "Semantics", "Transforms", "Unit"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Semantics", "Transforms", "Unit"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From 5b7ca66864c93ddd51b4cc53bc5954851a668d60 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:32:47 +0300
Subject: [PATCH 25/30] Enable "Unit" and "Semantics"
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index fef7d052c6e33..dcf4d17675b95 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Semantics", "Transforms", "Unit"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Transforms"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From 534b6cfa15f5dd5148b681f8e885604aacb1436d Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:41:45 +0300
Subject: [PATCH 26/30] Disable semantic tests again
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index dcf4d17675b95..a611a48d95eb2 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Transforms"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Semantics", "Transforms"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From 63e6f8d5f40cddfc23a2c0df4907641ecd988858 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:50:17 +0300
Subject: [PATCH 27/30] Enable "Transforms" tests
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index a611a48d95eb2..ff391c622a749 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Semantics", "Transforms"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Semantics"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From e40e87bcc358849f2ce754302235abd440d6091b Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 04:58:28 +0300
Subject: [PATCH 28/30] Enable "Runtime" tests
---
flang/test/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py
index ff391c622a749..b8aa00398bb53 100644
--- a/flang/test/lit.cfg.py
+++ b/flang/test/lit.cfg.py
@@ -77,7 +77,7 @@
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
-config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Runtime", "Semantics"]
+config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt", "Semantics"]
# If the flang examples are built, add examples to the config
if config.flang_examples:
>From 478953f88c1ac62f0df04762632f299d18c1934c Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 05:18:35 +0300
Subject: [PATCH 29/30] Enable Semantics tests for OpenMP, OpenACC, and PowerPC
---
.../Inputs/dir1/modfile63a.mod | 6 +
.../Inputs/dir1/modfile63b.mod | 8 +
.../Inputs/dir2/modfile63a.mod | 6 +
.../Inputs/dir2/modfile63b.mod | 8 +
.../Inputs/getdefinition03-b.f90 | 3 +
.../Inputs/getsymbols02-a.f90 | 10 +
.../Inputs/getsymbols02-b.f90 | 12 +
.../Inputs/getsymbols03-b.f90 | 3 +
.../Inputs/mod-file-changed.f90 | 5 +
.../Inputs/mod-file-unchanged.f90 | 5 +
.../SemanticsChecked/Inputs/modfile09-a.f90 | 16 +
.../SemanticsChecked/Inputs/modfile09-b.f90 | 8 +
.../SemanticsChecked/Inputs/modfile09-c.f90 | 8 +
.../SemanticsChecked/Inputs/modfile09-d.f90 | 8 +
.../OpenACC/acc-atomic-validity.f90 | 49 ++
.../SemanticsChecked/OpenACC/acc-branch.f90 | 199 ++++++
.../OpenACC/acc-cache-validity.f90 | 46 ++
.../OpenACC/acc-canonicalization-validity.f90 | 103 +++
.../OpenACC/acc-combined-loop.f90 | 33 +
.../SemanticsChecked/OpenACC/acc-data.f90 | 232 +++++++
.../OpenACC/acc-declare-validity.f90 | 74 +++
.../SemanticsChecked/OpenACC/acc-error.f90 | 29 +
.../OpenACC/acc-host-data.f90 | 41 ++
.../OpenACC/acc-init-validity.f90 | 102 +++
.../OpenACC/acc-kernels-loop.f90 | 298 +++++++++
.../SemanticsChecked/OpenACC/acc-kernels.f90 | 160 +++++
.../OpenACC/acc-loop-validity.f90 | 19 +
.../SemanticsChecked/OpenACC/acc-loop.f90 | 358 ++++++++++
.../SemanticsChecked/OpenACC/acc-module.f90 | 123 ++++
.../OpenACC/acc-parallel-loop-validity.f90 | 144 ++++
.../SemanticsChecked/OpenACC/acc-parallel.f90 | 191 ++++++
.../OpenACC/acc-reduction-validity.f90 | 172 +++++
.../OpenACC/acc-resolve01.f90 | 22 +
.../OpenACC/acc-resolve02.f90 | 17 +
.../OpenACC/acc-resolve03.f90 | 21 +
.../OpenACC/acc-resolve04.f90 | 34 +
.../OpenACC/acc-routine-validity.f90 | 75 +++
.../OpenACC/acc-routine-validity02.f90 | 17 +
.../SemanticsChecked/OpenACC/acc-routine.f90 | 136 ++++
.../OpenACC/acc-serial-loop.f90 | 114 ++++
.../SemanticsChecked/OpenACC/acc-serial.f90 | 182 +++++
.../OpenACC/acc-set-validity.f90 | 108 +++
.../OpenACC/acc-shutdown-validity.f90 | 96 +++
.../OpenACC/acc-symbols01.f90 | 26 +
.../OpenACC/acc-symbols02.f90 | 21 +
.../OpenACC/acc-update-validity.f90 | 67 ++
.../OpenACC/acc-wait-validity.f90 | 42 ++
.../OpenMP/allocate-clause01.f90 | 24 +
.../OpenMP/allocate-directive.f90 | 27 +
.../SemanticsChecked/OpenMP/allocate01.f90 | 27 +
.../SemanticsChecked/OpenMP/allocate02.f90 | 26 +
.../SemanticsChecked/OpenMP/allocate03.f90 | 25 +
.../SemanticsChecked/OpenMP/allocate04.f90 | 16 +
.../SemanticsChecked/OpenMP/allocate05.f90 | 26 +
.../SemanticsChecked/OpenMP/allocate06.f90 | 20 +
.../SemanticsChecked/OpenMP/allocate07.f90 | 37 ++
.../SemanticsChecked/OpenMP/allocate08.f90 | 44 ++
.../SemanticsChecked/OpenMP/allocate09.f90 | 35 +
.../SemanticsChecked/OpenMP/allocators01.f90 | 23 +
.../SemanticsChecked/OpenMP/allocators02.f90 | 22 +
.../SemanticsChecked/OpenMP/allocators03.f90 | 17 +
.../SemanticsChecked/OpenMP/allocators04.f90 | 31 +
.../SemanticsChecked/OpenMP/allocators05.f90 | 26 +
.../SemanticsChecked/OpenMP/allocators06.f90 | 18 +
.../OpenMP/atomic-hint-clause.f90 | 108 +++
.../OpenMP/atomic-update-overloaded-ops.f90 | 31 +
flang/test/SemanticsChecked/OpenMP/atomic.f90 | 58 ++
.../test/SemanticsChecked/OpenMP/atomic01.f90 | 404 ++++++++++++
.../test/SemanticsChecked/OpenMP/atomic02.f90 | 111 ++++
.../test/SemanticsChecked/OpenMP/atomic03.f90 | 144 ++++
.../test/SemanticsChecked/OpenMP/atomic04.f90 | 265 ++++++++
.../test/SemanticsChecked/OpenMP/atomic05.f90 | 29 +
.../test/SemanticsChecked/OpenMP/barrier.f90 | 4 +
.../OpenMP/clause-validity01.f90 | 576 ++++++++++++++++
.../OpenMP/combined-constructs.f90 | 511 ++++++++++++++
.../SemanticsChecked/OpenMP/common-block.f90 | 18 +
.../OpenMP/compiler-directive.f90 | 8 +
.../test/SemanticsChecked/OpenMP/copyin01.f90 | 34 +
.../test/SemanticsChecked/OpenMP/copyin02.f90 | 23 +
.../test/SemanticsChecked/OpenMP/copyin03.f90 | 33 +
.../test/SemanticsChecked/OpenMP/copyin04.f90 | 26 +
.../test/SemanticsChecked/OpenMP/copyin05.f90 | 23 +
.../test/SemanticsChecked/OpenMP/copying.f90 | 52 ++
.../SemanticsChecked/OpenMP/copyprivate01.f90 | 27 +
.../SemanticsChecked/OpenMP/copyprivate02.f90 | 23 +
.../SemanticsChecked/OpenMP/copyprivate03.f90 | 46 ++
.../OpenMP/critical-empty.f90 | 6 +
.../OpenMP/critical-hint-clause.f90 | 120 ++++
.../test/SemanticsChecked/OpenMP/dealloc.f90 | 13 +
.../OpenMP/declarative-directive.f90 | 101 +++
.../OpenMP/declare-target-common-block.f90 | 10 +
.../OpenMP/declare-target01.f90 | 169 +++++
.../OpenMP/declare-target02.f90 | 206 ++++++
.../OpenMP/declare-target03.f90 | 22 +
.../OpenMP/declare-target04.f90 | 16 +
.../OpenMP/declare-target05.f90 | 44 ++
.../OpenMP/declare-target06.f90 | 28 +
.../OpenMP/declare-target07.f90 | 49 ++
.../OpenMP/default-clause.f90 | 45 ++
.../SemanticsChecked/OpenMP/default-none.f90 | 49 ++
.../test/SemanticsChecked/OpenMP/default.f90 | 34 +
.../SemanticsChecked/OpenMP/default02.f90 | 57 ++
.../test/SemanticsChecked/OpenMP/depend01.f90 | 28 +
.../test/SemanticsChecked/OpenMP/depend02.f90 | 49 ++
.../test/SemanticsChecked/OpenMP/depend03.f90 | 24 +
.../OpenMP/device-clause01.f90 | 31 +
.../OpenMP/device-constructs.f90 | 271 ++++++++
.../OpenMP/do-collapse-positivecases.f90 | 36 +
.../SemanticsChecked/OpenMP/do-collapse.f90 | 33 +
.../test/SemanticsChecked/OpenMP/do-cycle.f90 | 44 ++
.../OpenMP/do-ordered-positivecases.f90 | 67 ++
.../SemanticsChecked/OpenMP/do-ordered.f90 | 60 ++
.../SemanticsChecked/OpenMP/do-schedule01.f90 | 13 +
.../SemanticsChecked/OpenMP/do-schedule02.f90 | 15 +
.../SemanticsChecked/OpenMP/do-schedule03.f90 | 28 +
.../SemanticsChecked/OpenMP/do-schedule04.f90 | 32 +
.../OpenMP/do01-positivecase.f90 | 19 +
flang/test/SemanticsChecked/OpenMP/do01.f90 | 18 +
flang/test/SemanticsChecked/OpenMP/do02.f90 | 21 +
flang/test/SemanticsChecked/OpenMP/do03.f90 | 25 +
.../OpenMP/do04-positivecase.f90 | 22 +
flang/test/SemanticsChecked/OpenMP/do04.f90 | 104 +++
.../OpenMP/do05-positivecase.f90 | 45 ++
flang/test/SemanticsChecked/OpenMP/do05.f90 | 214 ++++++
.../OpenMP/do06-positivecases.f90 | 23 +
flang/test/SemanticsChecked/OpenMP/do06.f90 | 33 +
flang/test/SemanticsChecked/OpenMP/do07.f90 | 24 +
flang/test/SemanticsChecked/OpenMP/do08.f90 | 169 +++++
flang/test/SemanticsChecked/OpenMP/do09.f90 | 26 +
flang/test/SemanticsChecked/OpenMP/do10.f90 | 39 ++
flang/test/SemanticsChecked/OpenMP/do11.f90 | 36 +
flang/test/SemanticsChecked/OpenMP/do12.f90 | 96 +++
flang/test/SemanticsChecked/OpenMP/do13.f90 | 185 ++++++
flang/test/SemanticsChecked/OpenMP/do14.f90 | 91 +++
flang/test/SemanticsChecked/OpenMP/do15.f90 | 94 +++
flang/test/SemanticsChecked/OpenMP/do16.f90 | 77 +++
flang/test/SemanticsChecked/OpenMP/do17.f90 | 57 ++
flang/test/SemanticsChecked/OpenMP/do18.f90 | 40 ++
flang/test/SemanticsChecked/OpenMP/do19.f90 | 25 +
flang/test/SemanticsChecked/OpenMP/do20.f90 | 18 +
.../OpenMP/firstprivate01.f90 | 124 ++++
.../OpenMP/firstprivate02.f90 | 20 +
.../test/SemanticsChecked/OpenMP/flush01.f90 | 36 +
.../test/SemanticsChecked/OpenMP/flush02.f90 | 88 +++
.../SemanticsChecked/OpenMP/if-clause.f90 | 624 ++++++++++++++++++
.../SemanticsChecked/OpenMP/implicit-dsa.f90 | 158 +++++
.../OpenMP/invalid-branch.f90 | 108 +++
.../SemanticsChecked/OpenMP/lastprivate01.f90 | 57 ++
.../SemanticsChecked/OpenMP/lastprivate02.f90 | 35 +
.../SemanticsChecked/OpenMP/lastprivate03.f90 | 24 +
.../SemanticsChecked/OpenMP/linear-iter.f90 | 85 +++
.../OpenMP/loop-association.f90 | 134 ++++
.../SemanticsChecked/OpenMP/loop-simd01.f90 | 23 +
.../SemanticsChecked/OpenMP/map-clause.f90 | 35 +
.../OpenMP/modfile-threadprivate.f90 | 35 +
.../OpenMP/nested-barrier.f90 | 166 +++++
.../SemanticsChecked/OpenMP/nested-cancel.f90 | 249 +++++++
.../OpenMP/nested-cancellation-point.f90 | 249 +++++++
.../OpenMP/nested-distribute.f90 | 111 ++++
.../SemanticsChecked/OpenMP/nested-master.f90 | 153 +++++
.../SemanticsChecked/OpenMP/nested-simd.f90 | 191 ++++++
.../SemanticsChecked/OpenMP/nested-target.f90 | 53 ++
.../SemanticsChecked/OpenMP/nested-teams.f90 | 112 ++++
.../test/SemanticsChecked/OpenMP/nested01.f90 | 40 ++
.../OpenMP/no-dowhile-in-parallel.f90 | 28 +
.../SemanticsChecked/OpenMP/nontemporal.f90 | 95 +++
.../OpenMP/omp-atomic-assignment-stmt.f90 | 87 +++
.../OpenMP/omp-do-collapse1.f90 | 14 +
.../OpenMP/order-clause01.f90 | 10 +
.../SemanticsChecked/OpenMP/ordered-simd.f90 | 148 +++++
.../SemanticsChecked/OpenMP/ordered01.f90 | 80 +++
.../SemanticsChecked/OpenMP/ordered02.f90 | 146 ++++
.../SemanticsChecked/OpenMP/ordered03.f90 | 122 ++++
.../OpenMP/parallel-critical-do.f90 | 18 +
.../OpenMP/parallel-private01.f90 | 20 +
.../OpenMP/parallel-private02.f90 | 20 +
.../OpenMP/parallel-private03.f90 | 28 +
.../OpenMP/parallel-private04.f90 | 28 +
.../OpenMP/parallel-sections-do.f90 | 19 +
.../OpenMP/parallel-sections01.f90 | 155 +++++
.../OpenMP/parallel-shared01.f90 | 20 +
.../OpenMP/parallel-shared02.f90 | 20 +
.../OpenMP/parallel-shared03.f90 | 28 +
.../OpenMP/parallel-shared04.f90 | 28 +
.../SemanticsChecked/OpenMP/parallel01.f90 | 23 +
.../SemanticsChecked/OpenMP/parallel02.f90 | 23 +
.../private-is-pointer-allocatable-check.f90 | 18 +
.../SemanticsChecked/OpenMP/private01.f90 | 20 +
.../SemanticsChecked/OpenMP/private02.f90 | 46 ++
.../OpenMP/reduction-subtract.f90 | 13 +
.../SemanticsChecked/OpenMP/reduction01.f90 | 14 +
.../SemanticsChecked/OpenMP/reduction02.f90 | 43 ++
.../SemanticsChecked/OpenMP/reduction03.f90 | 18 +
.../SemanticsChecked/OpenMP/reduction04.f90 | 24 +
.../SemanticsChecked/OpenMP/reduction05.f90 | 38 ++
.../SemanticsChecked/OpenMP/reduction06.f90 | 31 +
.../SemanticsChecked/OpenMP/reduction07.f90 | 101 +++
.../SemanticsChecked/OpenMP/reduction08.f90 | 63 ++
.../SemanticsChecked/OpenMP/reduction09.f90 | 86 +++
.../SemanticsChecked/OpenMP/reduction10.f90 | 15 +
.../SemanticsChecked/OpenMP/reduction11.f90 | 22 +
.../SemanticsChecked/OpenMP/reduction12.f90 | 16 +
.../OpenMP/requires-atomic01.f90 | 109 +++
.../OpenMP/requires-atomic02.f90 | 109 +++
.../SemanticsChecked/OpenMP/requires01.f90 | 7 +
.../SemanticsChecked/OpenMP/requires02.f90 | 17 +
.../SemanticsChecked/OpenMP/requires03.f90 | 21 +
.../SemanticsChecked/OpenMP/requires04.f90 | 23 +
.../SemanticsChecked/OpenMP/requires05.f90 | 22 +
.../SemanticsChecked/OpenMP/requires06.f90 | 20 +
.../SemanticsChecked/OpenMP/requires07.f90 | 21 +
.../SemanticsChecked/OpenMP/requires08.f90 | 23 +
.../SemanticsChecked/OpenMP/requires09.f90 | 14 +
.../SemanticsChecked/OpenMP/resolve01.f90 | 15 +
.../SemanticsChecked/OpenMP/resolve02.f90 | 18 +
.../SemanticsChecked/OpenMP/resolve03.f90 | 47 ++
.../SemanticsChecked/OpenMP/resolve04.f90 | 19 +
.../SemanticsChecked/OpenMP/resolve05.f90 | 36 +
.../SemanticsChecked/OpenMP/resolve06.f90 | 56 ++
.../SemanticsChecked/OpenMP/sections01.f90 | 15 +
.../SemanticsChecked/OpenMP/sections02.f90 | 139 ++++
.../SemanticsChecked/OpenMP/sections03.f90 | 27 +
.../SemanticsChecked/OpenMP/simd-aligned.f90 | 68 ++
.../OpenMP/simd-nontemporal.f90 | 63 ++
flang/test/SemanticsChecked/OpenMP/simd01.f90 | 40 ++
flang/test/SemanticsChecked/OpenMP/simd02.f90 | 21 +
flang/test/SemanticsChecked/OpenMP/simd03.f90 | 26 +
.../test/SemanticsChecked/OpenMP/single01.f90 | 15 +
.../test/SemanticsChecked/OpenMP/single02.f90 | 17 +
flang/test/SemanticsChecked/OpenMP/struct.f90 | 7 +
.../test/SemanticsChecked/OpenMP/symbol01.f90 | 68 ++
.../test/SemanticsChecked/OpenMP/symbol02.f90 | 25 +
.../test/SemanticsChecked/OpenMP/symbol03.f90 | 24 +
.../test/SemanticsChecked/OpenMP/symbol04.f90 | 23 +
.../test/SemanticsChecked/OpenMP/symbol05.f90 | 40 ++
.../test/SemanticsChecked/OpenMP/symbol06.f90 | 16 +
.../test/SemanticsChecked/OpenMP/symbol07.f90 | 37 ++
.../test/SemanticsChecked/OpenMP/symbol08.f90 | 251 +++++++
.../test/SemanticsChecked/OpenMP/symbol09.f90 | 37 ++
.../OpenMP/sync-critical01.f90 | 41 ++
.../OpenMP/sync-critical02.f90 | 55 ++
.../OpenMP/target-update01.f90 | 21 +
flang/test/SemanticsChecked/OpenMP/target.f90 | 11 +
.../test/SemanticsChecked/OpenMP/target01.f90 | 58 ++
.../test/SemanticsChecked/OpenMP/target02.f90 | 17 +
flang/test/SemanticsChecked/OpenMP/task01.f90 | 31 +
.../SemanticsChecked/OpenMP/taskgroup01.f90 | 50 ++
.../OpenMP/taskloop-simd01.f90 | 17 +
.../SemanticsChecked/OpenMP/taskloop01.f90 | 23 +
.../SemanticsChecked/OpenMP/taskloop02.f90 | 21 +
.../SemanticsChecked/OpenMP/taskloop03.f90 | 25 +
.../test/SemanticsChecked/OpenMP/taskwait.f90 | 4 +
.../OpenMP/threadprivate01.f90 | 53 ++
.../OpenMP/threadprivate02.f90 | 81 +++
.../OpenMP/threadprivate03.f90 | 28 +
.../OpenMP/threadprivate04.f90 | 53 ++
.../OpenMP/threadprivate05.f90 | 44 ++
.../OpenMP/threadprivate06.f90 | 30 +
.../OpenMP/threadprivate07.f90 | 15 +
.../OpenMP/use_device_addr.f90 | 17 +
.../OpenMP/use_device_addr1.f90 | 33 +
.../OpenMP/use_device_ptr.f90 | 21 +
.../OpenMP/use_device_ptr1.f90 | 64 ++
.../SemanticsChecked/OpenMP/workshare01.f90 | 33 +
.../SemanticsChecked/OpenMP/workshare02.f90 | 65 ++
.../SemanticsChecked/OpenMP/workshare03.f90 | 32 +
.../SemanticsChecked/OpenMP/workshare04.f90 | 50 ++
.../SemanticsChecked/OpenMP/workshare05.f90 | 61 ++
.../PowerPC/ppc-vector-intrinsics.f90 | 53 ++
.../PowerPC/ppc-vector-types01.f90 | 69 ++
.../PowerPC/ppc-vector-types02.f90 | 60 ++
.../PowerPC/ppc-vector-types03.f90 | 21 +
.../PowerPC/ppc-vector-types04.f90 | 47 ++
273 files changed, 17134 insertions(+)
create mode 100644 flang/test/SemanticsChecked/Inputs/dir1/modfile63a.mod
create mode 100644 flang/test/SemanticsChecked/Inputs/dir1/modfile63b.mod
create mode 100644 flang/test/SemanticsChecked/Inputs/dir2/modfile63a.mod
create mode 100644 flang/test/SemanticsChecked/Inputs/dir2/modfile63b.mod
create mode 100644 flang/test/SemanticsChecked/Inputs/getdefinition03-b.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/getsymbols02-a.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/getsymbols02-b.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/getsymbols03-b.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/mod-file-changed.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/mod-file-unchanged.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/modfile09-a.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/modfile09-b.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/modfile09-c.f90
create mode 100644 flang/test/SemanticsChecked/Inputs/modfile09-d.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-atomic-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-branch.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-cache-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-canonicalization-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-combined-loop.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-data.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-declare-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-error.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-host-data.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-init-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-kernels-loop.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-kernels.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-loop-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-loop.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-module.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-parallel-loop-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-parallel.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-reduction-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-resolve01.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-resolve02.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-resolve03.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-resolve04.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-routine-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-routine-validity02.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-routine.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-serial-loop.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-serial.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-set-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-shutdown-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-symbols01.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-symbols02.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-update-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenACC/acc-wait-validity.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate-clause01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate-directive.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate07.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate08.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocate09.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocators01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocators02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocators03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocators04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocators05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/allocators06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic-hint-clause.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic-update-overloaded-ops.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/atomic05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/barrier.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/clause-validity01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/combined-constructs.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/common-block.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/compiler-directive.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyin01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyin02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyin03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyin04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyin05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copying.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyprivate01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyprivate02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/copyprivate03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/critical-empty.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/critical-hint-clause.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/dealloc.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declarative-directive.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target-common-block.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/declare-target07.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/default-clause.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/default-none.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/default.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/default02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/depend01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/depend02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/depend03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/device-clause01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/device-constructs.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-collapse-positivecases.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-collapse.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-cycle.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-ordered-positivecases.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-ordered.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-schedule01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-schedule02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-schedule03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do-schedule04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do01-positivecase.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do04-positivecase.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do05-positivecase.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do06-positivecases.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do07.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do08.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do09.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do10.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do11.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do12.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do13.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do14.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do15.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do16.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do17.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do18.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do19.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/do20.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/firstprivate01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/firstprivate02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/flush01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/flush02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/if-clause.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/implicit-dsa.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/invalid-branch.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/lastprivate01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/lastprivate02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/lastprivate03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/linear-iter.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/loop-association.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/loop-simd01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/map-clause.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/modfile-threadprivate.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-barrier.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-cancel.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-cancellation-point.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-distribute.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-master.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-simd.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-target.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested-teams.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nested01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/no-dowhile-in-parallel.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/nontemporal.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/omp-atomic-assignment-stmt.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/omp-do-collapse1.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/order-clause01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/ordered-simd.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/ordered01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/ordered02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/ordered03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-critical-do.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-private01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-private02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-private03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-private04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-sections-do.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-sections01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-shared01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-shared02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-shared03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel-shared04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/parallel02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/private-is-pointer-allocatable-check.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/private01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/private02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction-subtract.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction07.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction08.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction09.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction10.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction11.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/reduction12.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires-atomic01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires-atomic02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires07.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires08.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/requires09.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/resolve01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/resolve02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/resolve03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/resolve04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/resolve05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/resolve06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/sections01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/sections02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/sections03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/simd-aligned.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/simd-nontemporal.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/simd01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/simd02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/simd03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/single01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/single02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/struct.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol07.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol08.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/symbol09.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/sync-critical01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/sync-critical02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/target-update01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/target.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/target01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/target02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/task01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/taskgroup01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/taskloop-simd01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/taskloop01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/taskloop02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/taskloop03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/taskwait.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/threadprivate01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/threadprivate02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/threadprivate03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/threadprivate04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/threadprivate05.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/threadprivate06.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/threadprivate07.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/use_device_addr.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/use_device_addr1.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/use_device_ptr.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/use_device_ptr1.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/workshare01.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/workshare02.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/workshare03.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/workshare04.f90
create mode 100644 flang/test/SemanticsChecked/OpenMP/workshare05.f90
create mode 100644 flang/test/SemanticsChecked/PowerPC/ppc-vector-intrinsics.f90
create mode 100644 flang/test/SemanticsChecked/PowerPC/ppc-vector-types01.f90
create mode 100644 flang/test/SemanticsChecked/PowerPC/ppc-vector-types02.f90
create mode 100644 flang/test/SemanticsChecked/PowerPC/ppc-vector-types03.f90
create mode 100644 flang/test/SemanticsChecked/PowerPC/ppc-vector-types04.f90
diff --git a/flang/test/SemanticsChecked/Inputs/dir1/modfile63a.mod b/flang/test/SemanticsChecked/Inputs/dir1/modfile63a.mod
new file mode 100644
index 0000000000000..acaa125819b39
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/dir1/modfile63a.mod
@@ -0,0 +1,6 @@
+!mod$ v1 sum:cbe36d213d935559
+module modfile63a
+contains
+subroutine s1()
+end
+end
diff --git a/flang/test/SemanticsChecked/Inputs/dir1/modfile63b.mod b/flang/test/SemanticsChecked/Inputs/dir1/modfile63b.mod
new file mode 100644
index 0000000000000..af5fec9e69bf6
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/dir1/modfile63b.mod
@@ -0,0 +1,8 @@
+!mod$ v1 sum:ddea620dc2aa0520
+!need$ cbe36d213d935559 n modfile63a
+module modfile63b
+use modfile63a,only:s1
+contains
+subroutine s2()
+end
+end
diff --git a/flang/test/SemanticsChecked/Inputs/dir2/modfile63a.mod b/flang/test/SemanticsChecked/Inputs/dir2/modfile63a.mod
new file mode 100644
index 0000000000000..8236d36c57588
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/dir2/modfile63a.mod
@@ -0,0 +1,6 @@
+!mod$ v1 sum:00761f8b3a4c5780
+module modfile63a
+contains
+subroutine s1a()
+end
+end
diff --git a/flang/test/SemanticsChecked/Inputs/dir2/modfile63b.mod b/flang/test/SemanticsChecked/Inputs/dir2/modfile63b.mod
new file mode 100644
index 0000000000000..af5fec9e69bf6
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/dir2/modfile63b.mod
@@ -0,0 +1,8 @@
+!mod$ v1 sum:ddea620dc2aa0520
+!need$ cbe36d213d935559 n modfile63a
+module modfile63b
+use modfile63a,only:s1
+contains
+subroutine s2()
+end
+end
diff --git a/flang/test/SemanticsChecked/Inputs/getdefinition03-b.f90 b/flang/test/SemanticsChecked/Inputs/getdefinition03-b.f90
new file mode 100644
index 0000000000000..7c1b3ff01903a
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/getdefinition03-b.f90
@@ -0,0 +1,3 @@
+module m3
+ public :: f
+end module
diff --git a/flang/test/SemanticsChecked/Inputs/getsymbols02-a.f90 b/flang/test/SemanticsChecked/Inputs/getsymbols02-a.f90
new file mode 100644
index 0000000000000..d4fd43cbd3b58
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/getsymbols02-a.f90
@@ -0,0 +1,10 @@
+module mm2a
+implicit none
+private
+ public :: get5
+contains
+ function get5() result(ret)
+ integer :: ret
+ ret = 5
+ end function get5
+end module mm2a
diff --git a/flang/test/SemanticsChecked/Inputs/getsymbols02-b.f90 b/flang/test/SemanticsChecked/Inputs/getsymbols02-b.f90
new file mode 100644
index 0000000000000..390a0c7482bfc
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/getsymbols02-b.f90
@@ -0,0 +1,12 @@
+module mm2b
+use mm2a
+implicit none
+private
+ public :: callget5
+contains
+ function callget5() result(ret)
+ implicit none
+ INTEGER :: ret
+ ret = get5()
+ end function callget5
+end module mm2b
diff --git a/flang/test/SemanticsChecked/Inputs/getsymbols03-b.f90 b/flang/test/SemanticsChecked/Inputs/getsymbols03-b.f90
new file mode 100644
index 0000000000000..030ae31fc3f37
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/getsymbols03-b.f90
@@ -0,0 +1,3 @@
+module mm3
+ public :: f
+end module
diff --git a/flang/test/SemanticsChecked/Inputs/mod-file-changed.f90 b/flang/test/SemanticsChecked/Inputs/mod-file-changed.f90
new file mode 100644
index 0000000000000..028203853fdc8
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/mod-file-changed.f90
@@ -0,0 +1,5 @@
+module m
+ dimension :: x(10)
+ private :: x
+ real :: x
+end module m
diff --git a/flang/test/SemanticsChecked/Inputs/mod-file-unchanged.f90 b/flang/test/SemanticsChecked/Inputs/mod-file-unchanged.f90
new file mode 100644
index 0000000000000..46c208aeb67a6
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/mod-file-unchanged.f90
@@ -0,0 +1,5 @@
+module m
+ dimension :: x(10)
+ public :: x
+ real :: x
+end module m
diff --git a/flang/test/SemanticsChecked/Inputs/modfile09-a.f90 b/flang/test/SemanticsChecked/Inputs/modfile09-a.f90
new file mode 100644
index 0000000000000..1e614ea3cf323
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/modfile09-a.f90
@@ -0,0 +1,16 @@
+module m
+ integer :: m1_x
+ interface
+ module subroutine s()
+ end subroutine
+ end interface
+end
+
+!Expect: m.mod
+!module m
+!integer(4)::m1_x
+!interface
+!module subroutine s()
+!end
+!end interface
+!end
diff --git a/flang/test/SemanticsChecked/Inputs/modfile09-b.f90 b/flang/test/SemanticsChecked/Inputs/modfile09-b.f90
new file mode 100644
index 0000000000000..69c88064f6677
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/modfile09-b.f90
@@ -0,0 +1,8 @@
+submodule(m) s1
+ integer s1_x
+end
+
+!Expect: m-s1.mod
+!submodule(m) s1
+!integer(4)::s1_x
+!end
diff --git a/flang/test/SemanticsChecked/Inputs/modfile09-c.f90 b/flang/test/SemanticsChecked/Inputs/modfile09-c.f90
new file mode 100644
index 0000000000000..3edb997f5679f
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/modfile09-c.f90
@@ -0,0 +1,8 @@
+submodule(m:s1) s2
+ integer s2_x
+end
+
+!Expect: m-s2.mod
+!submodule(m:s1) s2
+!integer(4)::s2_x
+!end
diff --git a/flang/test/SemanticsChecked/Inputs/modfile09-d.f90 b/flang/test/SemanticsChecked/Inputs/modfile09-d.f90
new file mode 100644
index 0000000000000..6e8b7caac4c0f
--- /dev/null
+++ b/flang/test/SemanticsChecked/Inputs/modfile09-d.f90
@@ -0,0 +1,8 @@
+submodule(m:s2) s3
+ integer s3_x
+end
+
+!Expect: m-s3.mod
+!submodule(m:s2) s3
+!integer(4)::s3_x
+!end
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-atomic-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-atomic-validity.f90
new file mode 100644
index 0000000000000..ba68031b0f18b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-atomic-validity.f90
@@ -0,0 +1,49 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.12 Atomic
+
+program openacc_atomic_validity
+
+ implicit none
+
+ integer :: i
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+
+
+ !$acc parallel
+ !$acc atomic update
+ c(i) = c(i) + 1
+
+ !$acc atomic update
+ c(i) = c(i) + 1
+ !$acc end atomic
+
+ !$acc atomic write
+ c(i) = 10
+
+ !$acc atomic write
+ c(i) = 10
+ !$acc end atomic
+
+ !$acc atomic read
+ i = c(i)
+
+ !$acc atomic read
+ i = c(i)
+ !$acc end atomic
+
+ !$acc atomic capture
+ c(i) = i
+ i = i + 1
+ !$acc end atomic
+
+ !$acc atomic update
+ !ERROR: RHS of atomic update statement must be scalar
+ !ERROR: LHS of atomic update statement must be scalar
+ c = c + 1
+
+ !$acc end parallel
+
+end program openacc_atomic_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-branch.f90 b/flang/test/SemanticsChecked/OpenACC/acc-branch.f90
new file mode 100644
index 0000000000000..b3692d0165890
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-branch.f90
@@ -0,0 +1,199 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc -pedantic
+
+! Check OpenACC restruction in branch in and out of some construct
+!
+subroutine openacc_clause_validity
+
+ implicit none
+
+ integer :: i, j, k
+ integer :: N = 256
+ real(8) :: a(256)
+
+ !$acc parallel
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ !ERROR: RETURN statement is not allowed in a PARALLEL construct
+ return
+ end do
+ !$acc end parallel
+
+ !$acc parallel loop
+ do i = 1, N
+ a(i) = 3.14
+ !ERROR: RETURN statement is not allowed in a PARALLEL LOOP construct
+ return
+ end do
+
+ !$acc serial loop
+ do i = 1, N
+ a(i) = 3.14
+ !ERROR: RETURN statement is not allowed in a SERIAL LOOP construct
+ return
+ end do
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ !ERROR: RETURN statement is not allowed in a KERNELS LOOP construct
+ return
+ end do
+
+ !$acc parallel
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ if(i == N-1) THEN
+ exit
+ end if
+ end do
+ !$acc end parallel
+
+ ! Exit branches out of parallel construct, not attached to an OpenACC parallel construct.
+ name1: do k=1, N
+ !$acc parallel
+ !$acc loop
+ outer: do i=1, N
+ inner: do j=1, N
+ ifname: if (j == 2) then
+ ! These are allowed.
+ exit
+ exit inner
+ exit outer
+ !ERROR: EXIT to construct 'name1' outside of PARALLEL construct is not allowed
+ exit name1
+ ! Exit to construct other than loops.
+ exit ifname
+ end if ifname
+ end do inner
+ end do outer
+ !$acc end parallel
+ end do name1
+
+ ! Exit branches out of parallel construct, attached to an OpenACC parallel construct.
+ thisblk: BLOCK
+ fortname: if (.true.) then
+ !PORTABILITY: The construct name 'name1' should be distinct at the subprogram level
+ name1: do k = 1, N
+ !$acc parallel
+ !ERROR: EXIT to construct 'fortname' outside of PARALLEL construct is not allowed
+ exit fortname
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ if(i == N-1) THEN
+ !ERROR: EXIT to construct 'name1' outside of PARALLEL construct is not allowed
+ exit name1
+ end if
+ end do
+
+ loop2: do i = 1, N
+ a(i) = 3.33
+ !ERROR: EXIT to construct 'thisblk' outside of PARALLEL construct is not allowed
+ exit thisblk
+ end do loop2
+ !$acc end parallel
+ end do name1
+ end if fortname
+ end BLOCK thisblk
+
+ !Exit branches inside OpenACC construct.
+ !$acc parallel
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ ifname: if (i == 2) then
+ ! This is allowed.
+ exit ifname
+ end if ifname
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ if(i == N-1) THEN
+ stop 999 ! no error
+ end if
+ end do
+ !$acc end parallel
+
+ !$acc kernels
+ do i = 1, N
+ a(i) = 3.14
+ !ERROR: RETURN statement is not allowed in a KERNELS construct
+ return
+ end do
+ !$acc end kernels
+
+ !$acc kernels
+ do i = 1, N
+ a(i) = 3.14
+ if(i == N-1) THEN
+ exit
+ end if
+ end do
+ !$acc end kernels
+
+ !$acc kernels
+ do i = 1, N
+ a(i) = 3.14
+ if(i == N-1) THEN
+ stop 999 ! no error
+ end if
+ end do
+ !$acc end kernels
+
+ !$acc serial
+ do i = 1, N
+ a(i) = 3.14
+ !ERROR: RETURN statement is not allowed in a SERIAL construct
+ return
+ end do
+ !$acc end serial
+
+ !$acc serial
+ do i = 1, N
+ a(i) = 3.14
+ if(i == N-1) THEN
+ exit
+ end if
+ end do
+ !$acc end serial
+
+ name2: do k=1, N
+ !$acc serial
+ do i = 1, N
+ ifname: if (.true.) then
+ print *, "LGTM"
+ a(i) = 3.14
+ if(i == N-1) THEN
+ !ERROR: EXIT to construct 'name2' outside of SERIAL construct is not allowed
+ exit name2
+ exit ifname
+ end if
+ end if ifname
+ end do
+ !$acc end serial
+ end do name2
+
+ !$acc serial
+ do i = 1, N
+ a(i) = 3.14
+ if(i == N-1) THEN
+ stop 999 ! no error
+ end if
+ end do
+ !$acc end serial
+
+
+ !$acc data create(a)
+
+ !ERROR: RETURN statement is not allowed in a DATA construct
+ if (size(a) == 10) return
+
+ !$acc end data
+
+end subroutine openacc_clause_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-cache-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-cache-validity.f90
new file mode 100644
index 0000000000000..49f400e763bfb
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-cache-validity.f90
@@ -0,0 +1,46 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.10 Cache
+
+program openacc_cache_validity
+
+ implicit none
+
+ type atype
+ real(8), dimension(10) :: arr
+ real(8) :: s
+ end type atype
+
+ integer :: i
+ integer, parameter :: N = 256
+ real(8), dimension(N, N) :: aa
+ type(atype) :: t
+ type(atype), dimension(10) :: ta
+ real(8), dimension(N) :: a
+
+ do i = 1, N
+
+ !$acc cache(a(i))
+ !$acc cache(a(1:2,3:4))
+ !$acc cache(a)
+ !$acc cache(readonly: a, aa)
+ !$acc cache(readonly: a(i), aa(i, i))
+ !$acc cache(t%arr)
+ !$acc cache(ta(1:2)%arr)
+ !$acc cache(ta(1:2)%arr(1:4))
+ !$acc cache(i)
+ !$acc cache(t%s)
+
+ !ERROR: Only array element or subarray are allowed in CACHE directive
+ !$acc cache(t)
+
+ !ERROR: Only array element or subarray are allowed in CACHE directive
+ !$acc cache(/i/)
+
+ end do
+
+ !ERROR: The CACHE directive must be inside a loop
+ !$acc cache(a)
+
+end program openacc_cache_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-canonicalization-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-canonicalization-validity.f90
new file mode 100644
index 0000000000000..ced7dd46803ee
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-canonicalization-validity.f90
@@ -0,0 +1,103 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC canonalization validity for the construct defined below:
+! 2.9 Loop
+! 2.11 Parallel Loop
+! 2.11 Kernels Loop
+! 2.11 Serial Loop
+
+program openacc_clause_validity
+
+ implicit none
+
+ integer :: i, j
+ integer :: N = 256
+ real(8) :: a(256)
+ real(8) :: aa(256, 256)
+
+ i = 0
+
+ !ERROR: DO loop after the LOOP directive must have loop control
+ !$acc loop
+ do
+ end do
+
+ !$acc parallel loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc serial loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel loop
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end kernels loop
+
+ !$acc serial loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end serial loop
+
+ !ERROR: DO loop after the PARALLEL LOOP directive must have loop control
+ !$acc parallel loop
+ do
+ end do
+
+ !ERROR: DO loop after the KERNELS LOOP directive must have loop control
+ !$acc kernels loop
+ do
+ end do
+
+ !ERROR: DO loop after the SERIAL LOOP directive must have loop control
+ !$acc serial loop
+ do
+ end do
+
+ !$acc parallel
+ !ERROR: The loop construct with the TILE clause must be followed by 2 tightly-nested loops
+ !$acc loop tile(2, 2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !ERROR: The loop construct with the TILE clause must be followed by 2 tightly-nested loops
+ !$acc parallel loop tile(2, 2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel
+ !ERROR: TILE and COLLAPSE clause may not appear on loop construct associated with DO CONCURRENT
+ !$acc loop collapse(2)
+ do concurrent (i = 1:N, j = 1:N)
+ aa(i, j) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: TILE and COLLAPSE clause may not appear on loop construct associated with DO CONCURRENT
+ !$acc loop tile(2, 2)
+ do concurrent (i = 1:N, j = 1:N)
+ aa(i, j) = 3.14
+ end do
+ !$acc end parallel
+
+end program openacc_clause_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-combined-loop.f90 b/flang/test/SemanticsChecked/OpenACC/acc-combined-loop.f90
new file mode 100644
index 0000000000000..77ff8e1cc603c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-combined-loop.f90
@@ -0,0 +1,33 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+program openacc_combined_loop
+ implicit none
+ integer :: i
+
+ i = 1
+
+ !ERROR: A DO loop must follow the PARALLEL LOOP directive
+ !$acc parallel loop
+ i = 1
+
+ !ERROR: A DO loop must follow the KERNELS LOOP directive
+ !$acc kernels loop
+ i = 1
+
+ !ERROR: A DO loop must follow the SERIAL LOOP directive
+ !$acc serial loop
+ i = 1
+
+ !$acc parallel loop
+ do 10 i=0, n
+ 10 continue
+
+ !$acc kernels loop
+ do 20 i=0, n
+ 20 continue
+
+ !$acc serial loop
+ do 30 i=0, n
+ 30 continue
+
+end
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-data.f90 b/flang/test/SemanticsChecked/OpenACC/acc-data.f90
new file mode 100644
index 0000000000000..84eb72825b34c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-data.f90
@@ -0,0 +1,232 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc -pedantic
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.6.5 Data
+! 2.14.6 Enter Data
+! 2.14.7 Exit Data
+
+program openacc_data_validity
+
+ implicit none
+
+ type atype
+ real(8), dimension(10) :: arr
+ real(8) :: s
+ end type atype
+
+ integer :: i, j, b, gang_size, vector_size, worker_size
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ integer :: async1
+ integer :: wait1, wait2
+ real :: reduction_r
+ logical :: reduction_l
+ real(8), dimension(N, N) :: aa, bb, cc
+ real(8), dimension(:), allocatable :: dd
+ real(8), pointer :: p
+ logical :: ifCondition = .TRUE.
+ type(atype) :: t
+ type(atype), dimension(10) :: ta
+
+ real(8), dimension(N) :: a, f, g, h
+
+ !ERROR: At least one of ATTACH, COPYIN, CREATE clause must appear on the ENTER DATA directive
+ !$acc enter data
+
+ !ERROR: Modifier is not allowed for the COPYIN clause on the ENTER DATA directive
+ !$acc enter data copyin(zero: i)
+
+ !ERROR: Only the ZERO modifier is allowed for the CREATE clause on the ENTER DATA directive
+ !$acc enter data create(readonly: i)
+
+ !ERROR: COPYOUT clause is not allowed on the ENTER DATA directive
+ !$acc enter data copyin(i) copyout(i)
+
+ !$acc enter data create(aa) if(.TRUE.)
+
+ !$acc enter data create(a(1:10))
+
+ !$acc enter data create(t%arr)
+
+ !$acc enter data create(t%arr(2:4))
+
+ !ERROR: At most one IF clause can appear on the ENTER DATA directive
+ !$acc enter data create(aa) if(.TRUE.) if(ifCondition)
+
+ !$acc enter data create(aa) if(ifCondition)
+
+ !$acc enter data create(aa) async
+
+ !ERROR: At most one ASYNC clause can appear on the ENTER DATA directive
+ !$acc enter data create(aa) async async
+
+ !$acc enter data create(aa) async(async1)
+
+ !$acc enter data create(aa) async(1)
+
+ !$acc enter data create(aa) wait(1)
+
+ !$acc enter data create(aa) wait(wait1)
+
+ !$acc enter data create(aa) wait(wait1, wait2)
+
+ !$acc enter data create(aa) wait(wait1) wait(wait2)
+
+ !ERROR: Argument `bb` on the ATTACH clause must be a variable or array with the POINTER or ALLOCATABLE attribute
+ !$acc enter data attach(bb)
+
+ !ERROR: At least one of COPYOUT, DELETE, DETACH clause must appear on the EXIT DATA directive
+ !$acc exit data
+
+ !ERROR: Modifier is not allowed for the COPYOUT clause on the EXIT DATA directive
+ !$acc exit data copyout(zero: i)
+
+ !$acc exit data delete(aa)
+
+ !$acc exit data delete(aa) finalize
+
+ !ERROR: At most one FINALIZE clause can appear on the EXIT DATA directive
+ !$acc exit data delete(aa) finalize finalize
+
+ !ERROR: Argument `cc` on the DETACH clause must be a variable or array with the POINTER or ALLOCATABLE attribute
+ !$acc exit data detach(cc)
+
+ !ERROR: Argument on the DETACH clause must be a variable or array with the POINTER or ALLOCATABLE attribute
+ !$acc exit data detach(/i/)
+
+ !$acc exit data copyout(bb)
+
+ !$acc exit data delete(aa) if(.TRUE.)
+
+ !$acc exit data delete(aa) if(ifCondition)
+
+ !ERROR: At most one IF clause can appear on the EXIT DATA directive
+ !$acc exit data delete(aa) if(ifCondition) if(.TRUE.)
+
+ !$acc exit data delete(aa) async
+
+ !ERROR: At most one ASYNC clause can appear on the EXIT DATA directive
+ !$acc exit data delete(aa) async async
+
+ !$acc exit data delete(aa) async(async1)
+
+ !$acc exit data delete(aa) async(1)
+
+ !$acc exit data delete(aa) wait(1)
+
+ !$acc exit data delete(aa) wait(wait1)
+
+ !$acc exit data delete(aa) wait(wait1, wait2)
+
+ !$acc exit data delete(aa) wait(wait1) wait(wait2)
+
+ !ERROR: Only the ZERO modifier is allowed for the COPYOUT clause on the DATA directive
+ !$acc data copyout(readonly: i)
+ !$acc end data
+
+ !ERROR: At most one IF clause can appear on the DATA directive
+ !$acc data copy(i) if(.true.) if(.true.)
+ !$acc end data
+
+ !ERROR: At least one of COPYOUT, DELETE, DETACH clause must appear on the EXIT DATA directive
+ !$acc exit data
+
+ !PORTABILITY: At least one of ATTACH, COPY, COPYIN, COPYOUT, CREATE, DEFAULT, DEVICEPTR, NO_CREATE, PRESENT clause should appear on the DATA directive
+ !$acc data
+ !$acc end data
+
+ !$acc data copy(aa) if(.true.)
+ !$acc end data
+
+ !$acc data copy(aa) if(ifCondition)
+ !$acc end data
+
+ !$acc data copy(aa, bb, cc)
+ !$acc end data
+
+ !$acc data copyin(aa) copyin(readonly: bb) copyout(cc)
+ !$acc end data
+
+ !$acc data copyin(readonly: aa, bb) copyout(zero: cc)
+ !$acc end data
+
+ !$acc data create(aa, bb(:,:)) create(zero: cc(:,:))
+ !$acc end data
+
+ !$acc data no_create(aa) present(bb, cc)
+ !$acc end data
+
+ !$acc data deviceptr(aa) attach(dd, p)
+ !$acc end data
+
+ !$acc data copy(aa, bb) default(none)
+ !$acc end data
+
+ !$acc data copy(aa, bb) default(present)
+ !$acc end data
+
+ !ERROR: At most one DEFAULT clause can appear on the DATA directive
+ !$acc data copy(aa, bb) default(none) default(present)
+ !$acc end data
+
+ !ERROR: At most one IF clause can appear on the DATA directive
+ !$acc data copy(aa) if(.true.) if(ifCondition)
+ !$acc end data
+
+ !$acc data copyin(i)
+ !ERROR: Unmatched PARALLEL directive
+ !$acc end parallel
+
+ !$acc data copy(aa) async
+ !$acc end data
+
+ !$acc data copy(aa) wait
+ !$acc end data
+
+ !$acc data copy(aa) device_type(default) wait
+ !$acc end data
+
+ do i = 1, 100
+ !$acc data copy(aa)
+ !ERROR: CYCLE to construct outside of DATA construct is not allowed
+ if (i == 10) cycle
+ !$acc end data
+ end do
+
+ !$acc data copy(aa)
+ do i = 1, 100
+ if (i == 10) cycle
+ end do
+ !$acc end data
+
+end program openacc_data_validity
+
+module mod1
+ type :: t1
+ integer :: a
+ contains
+ procedure :: t1_proc
+ end type
+
+contains
+
+
+ subroutine t1_proc(this)
+ class(t1) :: this
+ end subroutine
+
+ subroutine sub4(t)
+ type(t1) :: t
+
+ !ERROR: Only variables are allowed in data clauses on the DATA directive
+ !$acc data copy(t%t1_proc)
+ !$acc end data
+ end subroutine
+
+ subroutine sub5()
+ integer, parameter :: iparam = 1024
+ !$acc data copyin(iparam)
+ !$acc end data
+ end subroutine
+end module
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-declare-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-declare-validity.f90
new file mode 100644
index 0000000000000..2e7e651815d4a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-declare-validity.f90
@@ -0,0 +1,74 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.13 Declare
+
+module openacc_declare_validity
+
+ implicit none
+
+ real(8), dimension(10) :: aa, bb, ab, ac, ad, ae, af, cc, dd
+
+ !ERROR: At least one clause is required on the DECLARE directive
+ !$acc declare
+
+ !$acc declare create(aa, bb)
+
+ !WARNING: 'aa' in the CREATE clause is already present in the same clause in this module
+ !$acc declare create(aa)
+
+ !$acc declare link(ab)
+
+ !$acc declare device_resident(cc)
+
+ !ERROR: COPYOUT clause is not allowed on the DECLARE directive in module declaration section
+ !$acc declare copyout(ac)
+
+ !ERROR: COPY clause is not allowed on the DECLARE directive in module declaration section
+ !$acc declare copy(af)
+
+ !ERROR: PRESENT clause is not allowed on the DECLARE directive in module declaration section
+ !$acc declare present(ad)
+
+ !ERROR: DEVICEPTR clause is not allowed on the DECLARE directive in module declaration section
+ !$acc declare deviceptr(ae)
+
+ !ERROR: The ZERO modifier is not allowed for the CREATE clause on the DECLARE directive
+ !$acc declare create(zero: dd)
+
+ !ERROR: 'bb' in the COPYIN clause is already present in another CREATE clause in this module
+ !$acc declare copyin(bb)
+
+contains
+
+ subroutine sub1(cc, dd)
+ real(8) :: cc(:)
+ real(8) :: dd(:)
+ !$acc declare present(cc, dd)
+ !ERROR: 'cc' in the CREATE clause is already present in another PRESENT clause in this module
+ !$acc declare create(cc)
+ end subroutine sub1
+
+ function fct1(ee, ff, gg, hh, ii)
+ integer :: fct1
+ real(8), intent(in) :: ee(:)
+ !$acc declare copyin(readonly: ee)
+ real(8) :: ff(:), hh(:), ii(:,:)
+ !$acc declare link(hh) device_resident(ii)
+ real(8), intent(out) :: gg(:)
+ !$acc declare copy(ff) copyout(gg)
+ end function fct1
+
+ subroutine sub2(cc)
+ real(8), dimension(*) :: cc
+ !ERROR: Assumed-size dummy arrays may not appear on the DECLARE directive
+ !$acc declare present(cc)
+ end subroutine sub2
+
+ subroutine sub3()
+ real :: aa(100)
+ !ERROR: The ZERO modifier is not allowed for the COPYOUT clause on the DECLARE directive
+ !$acc declare copyout(zero: aa)
+ end subroutine
+
+end module openacc_declare_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-error.f90 b/flang/test/SemanticsChecked/OpenACC/acc-error.f90
new file mode 100644
index 0000000000000..69ee59f97ec6b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-error.f90
@@ -0,0 +1,29 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check parser specific error for OpenACC
+
+
+subroutine test(a, n)
+ integer :: a(n)
+ !ERROR: expected OpenACC directive
+ !$acc p
+ integer :: i,j
+
+ i = 0
+ !ERROR: expected OpenACC directive
+ !$acc p
+ end subroutine
+
+subroutine test2(a, n)
+ integer :: a(n)
+ integer :: i
+
+ !$acc parallel
+ !$acc loop
+ DO i = 1, n
+ END DO
+ !$acc end parallel
+ !WARN: Misplaced OpenACC end directive
+ !$acc end loop
+
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-host-data.f90 b/flang/test/SemanticsChecked/OpenACC/acc-host-data.f90
new file mode 100644
index 0000000000000..4e9167722a228
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-host-data.f90
@@ -0,0 +1,41 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.8 host_data
+
+program openacc_host_data_validity
+
+ implicit none
+
+ integer, parameter :: N = 256
+ real(8), dimension(N, N) :: aa, bb
+ logical :: ifCondition = .TRUE.
+
+ !ERROR: At least one of USE_DEVICE clause must appear on the HOST_DATA directive
+ !$acc host_data
+ !$acc end host_data
+
+ !$acc host_data use_device(aa)
+ !$acc end host_data
+
+ !$acc host_data use_device(aa) if(.true.)
+ !$acc end host_data
+
+ !$acc host_data use_device(aa) if(ifCondition)
+ !$acc end host_data
+
+ !$acc host_data use_device(aa, bb) if_present
+ !$acc end host_data
+
+ !ERROR: At most one IF_PRESENT clause can appear on the HOST_DATA directive
+ !$acc host_data use_device(aa, bb) if_present if_present
+ !$acc end host_data
+
+ !$acc host_data use_device(aa, bb) if(.true.) if_present
+ !$acc end host_data
+
+ !ERROR: At most one IF clause can appear on the HOST_DATA directive
+ !$acc host_data use_device(aa, bb) if(.true.) if(ifCondition)
+ !$acc end host_data
+
+end program openacc_host_data_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-init-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-init-validity.f90
new file mode 100644
index 0000000000000..3b594a25217c0
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-init-validity.f90
@@ -0,0 +1,102 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.14.1 Init
+
+program openacc_init_validity
+
+ implicit none
+
+ integer :: i, j
+ integer, parameter :: N = 256
+ logical :: ifCondition = .TRUE.
+ integer :: ifInt
+ real :: ifReal
+ real(8), dimension(N) :: a
+
+ !$acc init
+ !$acc init if(.TRUE.)
+ !$acc init if(ifCondition)
+ !$acc init if(ifInt)
+ !$acc init device_num(1)
+ !$acc init device_num(i)
+ !$acc init device_type(default)
+ !$acc init device_type(nvidia, radeon)
+ !$acc init device_num(i) device_type(host, multicore) if(ifCondition)
+
+ !$acc parallel
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ !$acc end parallel
+
+ !$acc serial
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ !$acc end serial
+
+ !$acc kernels
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ !$acc end kernels
+
+ !$acc parallel
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc serial
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ a(i) = 3.14
+ end do
+ !$acc end serial
+
+ !$acc kernels
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ a(i) = 3.14
+ end do
+ !$acc end kernels
+
+ !$acc parallel loop
+ do i = 1, N
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ a(i) = 3.14
+ end do
+
+ !$acc serial loop
+ do i = 1, N
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop
+ do i = 1, N
+ !ERROR: Directive INIT may not be called within a compute region
+ !$acc init
+ a(i) = 3.14
+ end do
+
+ !ERROR: At most one IF clause can appear on the INIT directive
+ !$acc init if(.TRUE.) if(ifCondition)
+
+ !ERROR: At most one DEVICE_NUM clause can appear on the INIT directive
+ !$acc init device_num(1) device_num(i)
+
+ !ERROR: At most one DEVICE_TYPE clause can appear on the INIT directive
+ !$acc init device_type(nvidia) device_type(default, *)
+
+ !ERROR: Must have LOGICAL or INTEGER type
+ !$acc init if(ifReal)
+
+end program openacc_init_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-kernels-loop.f90 b/flang/test/SemanticsChecked/OpenACC/acc-kernels-loop.f90
new file mode 100644
index 0000000000000..8653978fb6249
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-kernels-loop.f90
@@ -0,0 +1,298 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.11 Kernels Loop
+
+program openacc_kernels_loop_validity
+
+ implicit none
+
+ type atype
+ real(8), dimension(10) :: arr
+ real(8) :: s
+ end type atype
+
+ integer :: i, j, b, gang_size, vector_size, worker_size
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ integer :: async1
+ integer :: wait1, wait2
+ real :: reduction_r
+ logical :: reduction_l
+ real(8), dimension(N, N) :: aa, bb, cc
+ real(8), dimension(:), allocatable :: dd
+ real(8), pointer :: p
+ logical :: ifCondition = .TRUE.
+ type(atype) :: t
+ type(atype), dimension(10) :: ta
+
+ real(8), dimension(N) :: a, f, g, h
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end kernels loop
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end kernels loop
+
+ !$acc kernels loop num_gangs(8)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop num_gangs(gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop num_gangs(8)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop num_workers(worker_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop num_workers(8)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop vector_length(vector_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop vector_length(128)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop num_gangs(gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+
+ !$acc kernels loop if(.TRUE.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop if(ifCondition)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !ERROR: Unmatched END SERIAL LOOP directive
+ !$acc end serial loop
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the KERNELS LOOP directive
+ !$acc kernels loop device_type(*) if(.TRUE.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end kernels loop
+
+ !$acc kernels loop async
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop async(1)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop async(async1)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop wait(wait1)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop wait(wait1, wait2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop wait(wait1) wait(wait2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop wait(1, 2) async(3)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop wait(queues: 1, 2) async(3)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop wait(devnum: 1: 1, 2) async(3)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop wait(devnum: 1: queues: 1, 2) async(3)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop num_gangs(8)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop num_workers(8)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop vector_length(128)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop if(.true.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop if(ifCondition)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !ERROR: At most one IF clause can appear on the KERNELS LOOP directive
+ !$acc kernels loop if(.true.) if(ifCondition)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop self
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop self(.true.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop self(ifCondition)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop copy(aa) copyin(bb) copyout(cc)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop copy(aa, bb) copyout(zero: cc)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop present(aa, bb) create(cc)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop copyin(readonly: aa, bb) create(zero: cc)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop deviceptr(aa, bb) no_create(cc)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !ERROR: Argument `aa` on the ATTACH clause must be a variable or array with the POINTER or ALLOCATABLE attribute
+ !$acc kernels loop attach(aa, dd, p)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop private(aa, bb, cc)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop default(none)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop default(present)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !ERROR: At most one DEFAULT clause can appear on the KERNELS LOOP directive
+ !$acc kernels loop default(none) default(present)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop device_type(*)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop device_type(multicore)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop device_type(host, multicore)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop device_type(*) async wait num_gangs(8) num_workers(8) vector_length(128)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop device_type(*) async
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the KERNELS LOOP directive
+ !$acc kernels loop device_type(*) if(.TRUE.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop
+ do i = 1, N
+ if(i == 10) cycle
+ end do
+
+end program openacc_kernels_loop_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-kernels.f90 b/flang/test/SemanticsChecked/OpenACC/acc-kernels.f90
new file mode 100644
index 0000000000000..8a209040a7793
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-kernels.f90
@@ -0,0 +1,160 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.5.3 Kernels
+
+program openacc_kernels_validity
+
+ implicit none
+
+ type atype
+ real(8), dimension(10) :: arr
+ real(8) :: s
+ end type atype
+
+ integer :: i, j, b, gang_size, vector_size, worker_size
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ integer :: async1
+ integer :: wait1, wait2
+ real :: reduction_r
+ logical :: reduction_l
+ real(8), dimension(N, N) :: aa, bb, cc
+ real(8), dimension(:), allocatable :: dd
+ real(8), pointer :: p
+ logical :: ifCondition = .TRUE.
+ type(atype) :: t
+ type(atype), dimension(10) :: ta
+ real(8), dimension(N) :: a, f, g, h
+
+ !$acc kernels async
+ !$acc end kernels
+
+ !$acc kernels async(1)
+ !$acc end kernels
+
+ !$acc kernels async(async1)
+ !$acc end kernels
+
+ !$acc kernels wait(wait1)
+ !$acc end kernels
+
+ !$acc kernels wait(wait1, wait2)
+ !$acc end kernels
+
+ !$acc kernels wait(1, 2) async(3)
+ !$acc end kernels
+
+ !$acc kernels wait(queues: 1, 2) async(3)
+ !$acc end kernels
+
+ !$acc kernels wait(1) wait(2) async(3)
+ !$acc end kernels
+
+ !$acc kernels wait(devnum: 1: 1, 2) async(3)
+ !$acc end kernels
+
+ !$acc kernels wait(devnum: 1: queues: 1, 2) async(3)
+ !$acc end kernels
+
+ !$acc kernels num_gangs(8)
+ !$acc end kernels
+
+ !$acc kernels num_workers(8)
+ !$acc end kernels
+
+ !$acc kernels vector_length(128)
+ !$acc end kernels
+
+ !$acc kernels if(.true.)
+ !$acc end kernels
+
+ !$acc kernels if(ifCondition)
+ !$acc end kernels
+
+ !ERROR: At most one IF clause can appear on the KERNELS directive
+ !$acc kernels if(.true.) if(ifCondition)
+ !$acc end kernels
+
+ !$acc kernels self
+ !$acc end kernels
+
+ !$acc kernels self(.true.)
+ !$acc end kernels
+
+ !$acc kernels self(ifCondition)
+ !$acc end kernels
+
+ !$acc kernels copy(aa) copyin(bb) copyout(cc)
+ !$acc end kernels
+
+ !$acc kernels copy(aa, bb) copyout(zero: cc)
+ !$acc end kernels
+
+ !$acc kernels present(aa, bb) create(cc)
+ !$acc end kernels
+
+ !$acc kernels copyin(readonly: aa, bb) create(zero: cc)
+ !$acc end kernels
+
+ !$acc kernels deviceptr(aa, bb) no_create(cc)
+ !$acc end kernels
+
+ !ERROR: Argument `aa` on the ATTACH clause must be a variable or array with the POINTER or ALLOCATABLE attribute
+ !$acc kernels attach(dd, p, aa)
+ !$acc end kernels
+
+ !ERROR: PRIVATE clause is not allowed on the KERNELS directive
+ !$acc kernels private(aa, bb, cc)
+ !$acc end kernels
+
+ !$acc kernels default(none)
+ !$acc end kernels
+
+ !$acc kernels default(present)
+ !$acc end kernels
+
+ !ERROR: At most one DEFAULT clause can appear on the KERNELS directive
+ !$acc kernels default(none) default(present)
+ !$acc end kernels
+
+ !$acc kernels device_type(*)
+ !$acc end kernels
+
+ !$acc kernels device_type(default)
+ !$acc end kernels
+
+ !$acc kernels device_type(default, host)
+ !$acc end kernels
+
+ !$acc kernels device_type(*) async wait num_gangs(8) num_workers(8) vector_length(128)
+ !$acc end kernels
+
+ !$acc kernels device_type(*) async
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end kernels
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the KERNELS directive
+ !$acc kernels device_type(*) if(.TRUE.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end kernels
+
+ do i = 1, 100
+ !$acc kernels
+ !ERROR: CYCLE to construct outside of KERNELS construct is not allowed
+ if (i == 10) cycle
+ !$acc end kernels
+ end do
+
+ !$acc kernels
+ do i = 1, 100
+ if (i == 10) cycle
+ end do
+ !$acc end kernels
+
+end program openacc_kernels_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-loop-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-loop-validity.f90
new file mode 100644
index 0000000000000..205e67a4728fc
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-loop-validity.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+program openacc_clause_validity
+
+ implicit none
+
+ integer :: i, n
+
+ i = 0
+
+ !ERROR: A DO loop must follow the LOOP directive
+ !$acc loop
+ i = 1
+
+ !$acc loop
+ do 100 i=0, n
+ 100 continue
+
+end
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-loop.f90 b/flang/test/SemanticsChecked/OpenACC/acc-loop.f90
new file mode 100644
index 0000000000000..859cf3feec0d6
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-loop.f90
@@ -0,0 +1,358 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.9 Loop
+
+program openacc_loop_validity
+
+ implicit none
+
+ type atype
+ real(8), dimension(10) :: arr
+ real(8) :: s
+ integer :: n
+ end type atype
+
+ integer :: i, j, k, b, gang_size, vector_size, worker_size
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ integer :: async1
+ integer :: wait1, wait2
+ real :: reduction_r
+ logical :: reduction_l
+ real(8), dimension(N, N) :: aa, bb, cc
+ logical :: ifCondition = .TRUE.
+ type(atype) :: t
+ type(atype), dimension(10) :: ta
+
+ real(8), dimension(N) :: a, f, g, h
+
+ !$acc parallel
+ !$acc loop tile(2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel device_type(*) num_gangs(2)
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop seq
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop independent
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop auto
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: At most one VECTOR clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause
+ !$acc loop vector vector(128)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop vector
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop vector(10)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop vector(vector_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop vector(length: vector_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: At most one WORKER clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause
+ !$acc loop worker worker(10)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop worker
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop worker(10)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop worker(worker_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop worker(num: worker_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: At most one GANG clause can appear on the LOOP directive or in group separated by the DEVICE_TYPE clause
+ !$acc loop gang gang(gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc loop gang device_type(default) gang(gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !ERROR: At most one GANG clause can appear on the PARALLEL LOOP directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel loop gang gang(gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop gang device_type(default) gang(gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel
+ !$acc loop gang(gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop gang(num: gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop gang(gang_size, static:*)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop gang(num: gang_size, static:*)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop gang(num: gang_size, static: gang_size)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop private(b, a(:))
+ do i = 1, N
+ a(i) = b
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop tile(*)
+ do i = 1, N
+ a(i) = b
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !$acc loop tile(2, 2)
+ do i = 1, N
+ do j = 1, N
+ a(i) = b
+ end do
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: The parameter of the COLLAPSE clause must be a constant positive integer expression
+ !$acc loop collapse(-1)
+ do i = 1, N
+ do j = 1, N
+ a(i) = 3.14 + j
+ end do
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: Clause PRIVATE is not allowed after clause DEVICE_TYPE on the LOOP directive
+ !$acc loop device_type(*) private(i)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: Clause GANG is not allowed if clause SEQ appears on the LOOP directive
+ !$acc loop gang seq
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: Clause WORKER is not allowed if clause SEQ appears on the LOOP directive
+ !$acc loop worker seq
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel
+ !ERROR: Clause VECTOR is not allowed if clause SEQ appears on the LOOP directive
+ !$acc loop vector seq
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the PARALLEL directive
+ !$acc parallel device_type(*) if(.TRUE.)
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc loop collapse(2)
+ do i = 1, N
+ !ERROR: Loop control is not present in the DO LOOP
+ do
+ a(i) = 3.14
+ end do
+ end do
+
+ !ERROR: The num argument is not allowed when dim is specified
+ !$acc loop gang(1, dim: 2)
+ do i = 1, N
+ end do
+
+ !$acc loop
+ do i = 1, N
+ end do
+ !$acc end loop
+
+ !$acc loop collapse(2)
+ do i = 1, 10
+ !ERROR: LOOP directive not expected in COLLAPSE loop nest
+ !$acc loop
+ do j = 1, 10
+ end do
+ end do
+
+ !$acc parallel
+ !$acc loop
+ do i = 1, n
+ if(i == 10) cycle
+ end do
+ !$acc end parallel
+
+ !$acc loop gang device_type(nvidia) gang(num: 8)
+ DO i = 1, n
+ END DO
+
+ !$acc loop vector device_type(default) vector(16)
+ DO i = 1, n
+ END DO
+
+ !$acc loop worker device_type(*) worker(8)
+ DO i = 1, n
+ END DO
+
+ !$acc loop device_type(multicore) collapse(2)
+ DO i = 1, n
+ DO j = 1, n
+ END DO
+ END DO
+
+ !ERROR: Trip count must be computable and invariant
+ !$acc loop collapse(2)
+ DO i = 1, n
+ DO j = 1, c(i)
+ END DO
+ END DO
+
+ !ERROR: Trip count must be computable and invariant
+ !$acc loop collapse(2)
+ DO i = 1, n
+ DO j = 1, i
+ END DO
+ END DO
+
+ !ERROR: Trip count must be computable and invariant
+ !$acc loop collapse(2)
+ DO i = 1, n
+ DO j = 1, ta(i)%n
+ END DO
+ END DO
+
+ !ERROR: Trip count must be computable and invariant
+ !$acc parallel loop collapse(2)
+ DO i = 1, n
+ DO j = 1, ta(i)%n
+ END DO
+ END DO
+
+ !ERROR: Trip count must be computable and invariant
+ !$acc loop collapse(3)
+ DO i = 1, n
+ DO j = 1, n
+ DO k = 1, i
+ END DO
+ END DO
+ END DO
+
+end program openacc_loop_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-module.f90 b/flang/test/SemanticsChecked/OpenACC/acc-module.f90
new file mode 100644
index 0000000000000..7f034d8ae54f0
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-module.f90
@@ -0,0 +1,123 @@
+! RUN: %python %S/../test_modfile.py %s %flang_fc1 -fopenacc
+
+module acc_mod
+ real :: data_create(100)
+ !$acc declare create(data_create)
+
+ real :: data_copyin(10)
+ !$acc declare copyin(data_copyin)
+
+ real :: data_copyinro(10)
+ !$acc declare copyin(readonly: data_copyinro)
+
+ real :: data_device_resident(20)
+ !$acc declare device_resident(data_device_resident)
+
+ integer :: data_link(50)
+ !$acc declare link(data_link)
+
+ !$acc routine(sub10) seq
+
+contains
+ subroutine sub1()
+ !$acc routine
+ end subroutine
+
+ subroutine sub2()
+ !$acc routine seq
+ end subroutine
+
+ subroutine sub3()
+ !$acc routine gang
+ end subroutine
+
+ subroutine sub4()
+ !$acc routine vector
+ end subroutine
+
+ subroutine sub5()
+ !$acc routine worker
+ end subroutine
+
+ subroutine sub6()
+ !$acc routine gang(dim:2)
+ end subroutine
+
+ subroutine sub7()
+ !$acc routine bind("sub7_")
+ end subroutine
+
+ subroutine sub8()
+ !$acc routine bind(sub7)
+ end subroutine
+
+ subroutine sub9()
+ !$acc routine vector
+ !$acc routine seq bind(sub7)
+ !$acc routine gang bind(sub8)
+ end subroutine
+
+ subroutine sub10()
+ end subroutine
+
+ subroutine sub11()
+ !$acc routine device_type(nvidia) gang device_type(*) seq
+ end subroutine
+
+ subroutine sub12()
+ !$acc routine device_type(host) bind(sub7) device_type(multicore) bind(sub8)
+ end subroutine
+end module
+
+!Expect: acc_mod.mod
+! module acc_mod
+! real(4)::data_create(1_8:100_8)
+! !$acc declare create(data_create)
+! real(4)::data_copyin(1_8:10_8)
+! !$acc declare copyin(data_copyin)
+! real(4)::data_copyinro(1_8:10_8)
+! !$acc declare copyin(readonly: data_copyinro)
+! real(4)::data_device_resident(1_8:20_8)
+! !$acc declare device_resident(data_device_resident)
+! integer(4)::data_link(1_8:50_8)
+! !$acc declare link(data_link)
+! contains
+! subroutine sub1()
+! !$acc routine
+! end
+! subroutine sub2()
+! !$acc routine seq
+! end
+! subroutine sub3()
+! !$acc routine gang
+! end
+! subroutine sub4()
+! !$acc routine vector
+! end
+! subroutine sub5()
+! !$acc routine worker
+! end
+! subroutine sub6()
+! !$acc routine gang(dim:2)
+! end
+! subroutine sub7()
+! !$acc routine bind("sub7_")
+! end
+! subroutine sub8()
+! !$acc routine bind(sub7)
+! end
+! subroutine sub9()
+! !$acc routine vector
+! !$acc routine seq bind(sub7)
+! !$acc routine gang bind(sub8)
+! end
+! subroutine sub10()
+! !$acc routine seq
+! end
+! subroutinesub11()
+! !$acc routine device_type(nvidia) gang device_type(*) seq
+! end
+! subroutinesub12()
+! !$acc routine device_type(host) bind(sub7) device_type(multicore) bind(sub8)
+! end
+! end
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-parallel-loop-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-parallel-loop-validity.f90
new file mode 100644
index 0000000000000..7f33f9e145110
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-parallel-loop-validity.f90
@@ -0,0 +1,144 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.11 Parallel Loop
+
+program openacc_parallel_loop_validity
+
+ implicit none
+
+ integer :: i, j, b
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ real :: reduction_r
+ logical :: reduction_l
+ logical :: ifCondition = .TRUE.
+ real(8), dimension(N) :: a, f, g, h
+ real(8), dimension(N, N) :: aa, bb, cc
+
+ !$acc parallel loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel loop
+
+ !$acc parallel loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel loop tile(2)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop self
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !ERROR: SELF clause on the PARALLEL LOOP directive only accepts optional scalar logical expression
+ !$acc parallel loop self(bb, cc(:,:))
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop self(.true.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop self(ifCondition)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+
+ !$acc parallel loop tile(2, 2)
+ do i = 1, N
+ do j = 1, N
+ aa(i, j) = 3.14
+ end do
+ end do
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the PARALLEL LOOP directive
+ !$acc parallel loop device_type(*) if(.TRUE.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel loop
+
+ !$acc kernels loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !ERROR: Unmatched END PARALLEL LOOP directive
+ !$acc end parallel loop
+
+ !$acc parallel loop reduction(+: reduction_r)
+ do i = 1, N
+ reduction_r = a(i) + i
+ end do
+
+ !$acc parallel loop reduction(*: reduction_r)
+ do i = 1, N
+ reduction_r = reduction_r * (a(i) + i)
+ end do
+
+ !$acc parallel loop reduction(min: reduction_r)
+ do i = 1, N
+ reduction_r = min(reduction_r, a(i) * i)
+ end do
+
+ !$acc parallel loop reduction(max: reduction_r)
+ do i = 1, N
+ reduction_r = max(reduction_r, a(i) * i)
+ end do
+
+ !$acc parallel loop reduction(iand: b)
+ do i = 1, N
+ b = iand(b, c(i))
+ end do
+
+ !$acc parallel loop reduction(ior: b)
+ do i = 1, N
+ b = ior(b, c(i))
+ end do
+
+ !$acc parallel loop reduction(ieor: b)
+ do i = 1, N
+ b = ieor(b, c(i))
+ end do
+
+ !$acc parallel loop reduction(.and.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .and. e(i)
+ end do
+
+ !$acc parallel loop reduction(.or.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .or. e(i)
+ end do
+
+ !$acc parallel loop reduction(.eqv.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .eqv. e(i)
+ end do
+
+ !$acc parallel loop reduction(.neqv.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .neqv. e(i)
+ end do
+
+ !$acc parallel loop
+ do i = 1, N
+ if(i == 10) cycle
+ end do
+
+end program openacc_parallel_loop_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-parallel.f90 b/flang/test/SemanticsChecked/OpenACC/acc-parallel.f90
new file mode 100644
index 0000000000000..3f17d8fc862a6
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-parallel.f90
@@ -0,0 +1,191 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.5.1 Parallel
+
+program openacc_parallel_validity
+
+ implicit none
+
+ integer :: i, j, b, gang_size, vector_size, worker_size
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ integer :: async1
+ integer :: wait1, wait2
+ real :: reduction_r
+ logical :: reduction_l
+ real(8), dimension(N, N) :: aa, bb, cc
+ real(8), dimension(:), allocatable :: dd
+ real(8), pointer :: p
+ logical :: ifCondition = .TRUE.
+ real(8), dimension(N) :: a, f, g, h
+
+ !$acc parallel device_type(*) num_gangs(2)
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc parallel async
+ !$acc end parallel
+
+ !$acc parallel async(1)
+ !$acc end parallel
+
+ !$acc parallel async(async1)
+ !$acc end parallel
+
+ !$acc parallel wait
+ !$acc end parallel
+
+ !$acc parallel wait(1)
+ !$acc end parallel
+
+ !$acc parallel wait(wait1)
+ !$acc end parallel
+
+ !$acc parallel wait(1,2)
+ !$acc end parallel
+
+ !$acc parallel wait(wait1, wait2)
+ !$acc end parallel
+
+ !$acc parallel num_gangs(8)
+ !$acc end parallel
+
+ !ERROR: NUM_GANGS clause accepts a maximum of 3 arguments
+ !$acc parallel num_gangs(1, 1, 1, 1)
+ !$acc end parallel
+
+ !$acc parallel num_workers(8)
+ !$acc end parallel
+
+ !$acc parallel vector_length(128)
+ !$acc end parallel
+
+ !$acc parallel if(.true.)
+ !$acc end parallel
+
+ !$acc parallel if(ifCondition)
+ !$acc end parallel
+
+ !$acc parallel self
+ !$acc end parallel
+
+ !$acc parallel self(.true.)
+ !$acc end parallel
+
+ !$acc parallel self(ifCondition)
+ !$acc end parallel
+
+ !$acc parallel copy(aa) copyin(bb) copyout(cc)
+ !$acc end parallel
+
+ !$acc parallel copy(aa, bb) copyout(zero: cc)
+ !$acc end parallel
+
+ !$acc parallel present(aa, bb) create(cc)
+ !$acc end parallel
+
+ !$acc parallel copyin(readonly: aa, bb) create(zero: cc)
+ !$acc end parallel
+
+ !$acc parallel deviceptr(aa, bb) no_create(cc)
+ !$acc end parallel
+
+ !ERROR: Argument `cc` on the ATTACH clause must be a variable or array with the POINTER or ALLOCATABLE attribute
+ !$acc parallel attach(dd, p, cc)
+ !$acc end parallel
+
+ !$acc parallel private(aa) firstprivate(bb, cc)
+ !$acc end parallel
+
+ !$acc parallel default(none)
+ !$acc end parallel
+
+ !$acc parallel default(present)
+ !$acc end parallel
+
+ !$acc parallel device_type(*)
+ !$acc end parallel
+
+ !$acc parallel device_type(default)
+ !$acc end parallel
+
+ !$acc parallel device_type(default, host)
+ !$acc end parallel
+
+ !ERROR: Clause PRIVATE is not allowed after clause DEVICE_TYPE on the PARALLEL directive
+ !ERROR: Clause FIRSTPRIVATE is not allowed after clause DEVICE_TYPE on the PARALLEL directive
+ !$acc parallel device_type(*) private(aa) firstprivate(bb)
+ !$acc end parallel
+
+ !$acc parallel device_type(*) async
+ !$acc end parallel
+
+ !$acc parallel device_type(*) wait
+ !$acc end parallel
+
+ !$acc parallel device_type(*) num_gangs(8)
+ !$acc end parallel
+
+ !$acc parallel device_type(*) async device_type(host) wait
+ !$acc end parallel
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the PARALLEL directive
+ !$acc parallel device_type(*) if(.TRUE.)
+ !$acc loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ do i = 1, 100
+ !$acc parallel
+ !ERROR: CYCLE to construct outside of PARALLEL construct is not allowed
+ if (i == 10) cycle
+ !$acc end parallel
+ end do
+
+ !$acc parallel
+ do i = 1, 100
+ if (i == 10) cycle
+ end do
+ !$acc end parallel
+
+ !ERROR: At most one NUM_GANGS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel num_gangs(400) num_gangs(400)
+ !$acc end parallel
+
+ !ERROR: At most one NUM_GANGS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel device_type(nvidia) num_gangs(400) num_gangs(200)
+ !$acc end parallel
+
+ !$acc parallel device_type(nvidia) num_gangs(400) device_type(radeon) num_gangs(200)
+ !$acc end parallel
+
+ !ERROR: At most one NUM_WORKERS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel num_workers(8) num_workers(4)
+ !$acc end parallel
+
+ !ERROR: At most one NUM_WORKERS clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel device_type(nvidia) num_workers(8) num_workers(4)
+ !$acc end parallel
+
+ !$acc parallel device_type(nvidia) num_workers(8) device_type(radeon) num_workers(4)
+ !$acc end parallel
+
+ !ERROR: At most one VECTOR_LENGTH clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel vector_length(128) vector_length(124)
+ !$acc end parallel
+
+ !ERROR: At most one VECTOR_LENGTH clause can appear on the PARALLEL directive or in group separated by the DEVICE_TYPE clause
+ !$acc parallel device_type(nvidia) vector_length(256) vector_length(128)
+ !$acc end parallel
+
+ !$acc parallel device_type(nvidia) vector_length(256) device_type(radeon) vector_length(128)
+ !$acc end parallel
+
+end program openacc_parallel_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-reduction-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-reduction-validity.f90
new file mode 100644
index 0000000000000..ccd009bffa2e2
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-reduction-validity.f90
@@ -0,0 +1,172 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC reduction validity.
+
+program openacc_reduction_validity
+
+ integer :: i
+ real :: r
+ complex :: c
+ logical :: l
+
+ !$acc parallel reduction(+:i)
+ !$acc end parallel
+
+ !$acc parallel reduction(*:i)
+ !$acc end parallel
+
+ !$acc parallel reduction(min:i)
+ !$acc end parallel
+
+ !$acc parallel reduction(max:i)
+ !$acc end parallel
+
+ !$acc parallel reduction(iand:i)
+ !$acc end parallel
+
+ !$acc parallel reduction(ior:i)
+ !$acc end parallel
+
+ !$acc parallel reduction(ieor:i)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for integer type
+ !$acc parallel reduction(.and.:i)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for integer type
+ !$acc parallel reduction(.or.:i)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for integer type
+ !$acc parallel reduction(.eqv.:i)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for integer type
+ !$acc parallel reduction(.neqv.:i)
+ !$acc end parallel
+
+ !$acc parallel reduction(+:r)
+ !$acc end parallel
+
+ !$acc parallel reduction(*:r)
+ !$acc end parallel
+
+ !$acc parallel reduction(min:r)
+ !$acc end parallel
+
+ !$acc parallel reduction(max:r)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for real type
+ !$acc parallel reduction(iand:r)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for real type
+ !$acc parallel reduction(ior:r)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for real type
+ !$acc parallel reduction(ieor:r)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for real type
+ !$acc parallel reduction(.and.:r)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for real type
+ !$acc parallel reduction(.or.:r)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for real type
+ !$acc parallel reduction(.eqv.:r)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for real type
+ !$acc parallel reduction(.neqv.:r)
+ !$acc end parallel
+
+ !$acc parallel reduction(+:c)
+ !$acc end parallel
+
+ !$acc parallel reduction(*:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(min:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(max:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(iand:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(ior:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(ieor:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(.and.:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(.or.:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(.eqv.:c)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for complex type
+ !$acc parallel reduction(.neqv.:c)
+ !$acc end parallel
+
+ !$acc parallel reduction(.and.:l)
+ !$acc end parallel
+
+ !$acc parallel reduction(.or.:l)
+ !$acc end parallel
+
+ !$acc parallel reduction(.eqv.:l)
+ !$acc end parallel
+
+ !$acc parallel reduction(.neqv.:l)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for logical type
+ !$acc parallel reduction(+:l)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for logical type
+ !$acc parallel reduction(*:l)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for logical type
+ !$acc parallel reduction(min:l)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for logical type
+ !$acc parallel reduction(max:l)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for logical type
+ !$acc parallel reduction(iand:l)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for logical type
+ !$acc parallel reduction(ior:l)
+ !$acc end parallel
+
+ !ERROR: reduction operator not supported for logical type
+ !$acc parallel reduction(ieor:l)
+ !$acc end parallel
+
+
+end program
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-resolve01.f90 b/flang/test/SemanticsChecked/OpenACC/acc-resolve01.f90
new file mode 100644
index 0000000000000..4d85c26990c1c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-resolve01.f90
@@ -0,0 +1,22 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Data-Mapping Attribute Clauses
+! 2.15.14 default Clause
+
+subroutine default_none()
+ integer a(3)
+
+ A = 1
+ B = 2
+ !$acc parallel default(none) private(c)
+ !ERROR: The DEFAULT(NONE) clause requires that 'a' must be listed in a data-mapping clause
+ A(1:2) = 3
+ !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-mapping clause
+ B = 4
+ C = 5
+ !$acc end parallel
+end subroutine default_none
+
+program mm
+ call default_none()
+end
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-resolve02.f90 b/flang/test/SemanticsChecked/OpenACC/acc-resolve02.f90
new file mode 100644
index 0000000000000..861cb26e31a30
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-resolve02.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+subroutine compute()
+ integer :: a(3), c, i
+
+ a = 1
+ !ERROR: 'c' appears in more than one data-sharing clause on the same OpenACC directive
+ !$acc parallel firstprivate(c) private(c)
+ do i = 1, 3
+ a(i) = c
+ end do
+ !$acc end parallel
+end subroutine compute
+
+program mm
+ call compute()
+end
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-resolve03.f90 b/flang/test/SemanticsChecked/OpenACC/acc-resolve03.f90
new file mode 100644
index 0000000000000..341e9d2ce68b2
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-resolve03.f90
@@ -0,0 +1,21 @@
+! RUN: %flang_fc1 -fopenacc %s
+! A regression test to check that
+! arbitrary compiler directives do not generate errors
+! inside OpenACC collapsed loops
+subroutine foo
+ integer, parameter :: loop_bound = 42
+ integer :: a
+ integer :: b
+ integer :: c
+
+ !$acc parallel
+ do a = 0, loop_bound
+ !$acc loop collapse(2)
+ do b = 0, loop_bound
+ !dir$ ivdep
+ do c = 0, loop_bound
+ enddo
+ enddo
+ enddo
+ !$acc end parallel
+end subroutine foo
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-resolve04.f90 b/flang/test/SemanticsChecked/OpenACC/acc-resolve04.f90
new file mode 100644
index 0000000000000..8a72630a2ec9f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-resolve04.f90
@@ -0,0 +1,34 @@
+! RUN: %flang_fc1 -fopenacc %s
+
+! Check common block resolution.
+! Check that symbol are correctly resolved in device, host and self clause.
+
+subroutine sub(a)
+ implicit none
+ real :: a(10)
+ real :: b(10), c(10), d
+ common/foo/ b, d, c
+ integer :: i, n
+
+ !$acc declare present(/foo/)
+ !$acc parallel loop gang vector
+ do i = 1, n
+ b(i) = a(i) + c(i) * d
+ end do
+end subroutine
+
+program test_resolve04
+ real :: a(10), b(10)
+ common /foo/ b, c
+
+!$acc data create(/foo/)
+!$acc update device(/foo/)
+!$acc update host(/foo/)
+!$acc update self(/foo/)
+!$acc end data
+
+!$acc data copy(/foo/)
+!$acc end data
+
+end
+
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-routine-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-routine-validity.f90
new file mode 100644
index 0000000000000..c135c2b86aac1
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-routine-validity.f90
@@ -0,0 +1,75 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.15.1 routine
+
+module openacc_routine_validity
+ implicit none
+
+ !$acc routine(sub3) seq
+
+ !$acc routine(fct2) vector
+
+ !$acc routine(sub3)
+
+ !ERROR: ROUTINE directive without name must appear within the specification part of a subroutine or function definition, or within an interface body for a subroutine or function in an interface block
+ !$acc routine seq
+
+ !$acc routine(dummy) seq
+
+contains
+
+ subroutine sub1(a)
+ real :: a(:)
+ !$acc routine
+ end subroutine sub1
+
+ subroutine sub2(a)
+ real :: a(:)
+ !ERROR: Clause NOHOST is not allowed after clause DEVICE_TYPE on the ROUTINE directive
+ !$acc routine seq device_type(*) nohost
+ end subroutine sub2
+
+ subroutine sub3(a)
+ real :: a(:)
+ end subroutine sub3
+
+ subroutine sub4(a)
+ real :: a(:)
+ !$acc routine seq
+ end subroutine sub4
+
+ subroutine sub5(a)
+ real :: a(:)
+ !$acc routine(sub5) seq
+ end subroutine sub5
+
+ function fct1(a)
+ integer :: fct1
+ real :: a(:)
+ !$acc routine vector nohost
+ end function fct1
+
+ function fct2(a)
+ integer :: fct2
+ real :: a(:)
+ end function fct2
+
+ function fct3(a)
+ integer :: fct3
+ real :: a(:)
+ !$acc routine seq bind(fct2)
+ end function fct3
+
+ function fct4(a)
+ integer :: fct4
+ real :: a(:)
+ !$acc routine seq bind("_fct4")
+ end function fct4
+
+ subroutine sub6(a)
+ real :: a(:)
+ !$acc routine seq bind(dummy_sub)
+ end subroutine sub6
+
+end module openacc_routine_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-routine-validity02.f90 b/flang/test/SemanticsChecked/OpenACC/acc-routine-validity02.f90
new file mode 100644
index 0000000000000..9410a5b17745d
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-routine-validity02.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check acc routine in the top level.
+
+subroutine sub1(a, n)
+ integer :: n
+ real :: a(n)
+end subroutine sub1
+
+!$acc routine(sub1)
+
+!dir$ value=1
+program test
+ integer, parameter :: N = 10
+ real :: a(N)
+ call sub1(a, N)
+end program
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-routine.f90 b/flang/test/SemanticsChecked/OpenACC/acc-routine.f90
new file mode 100644
index 0000000000000..8281822ca01d0
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-routine.f90
@@ -0,0 +1,136 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+subroutine sub1(a)
+ real, dimension(10) :: a
+end subroutine
+
+subroutine sub2(a)
+ !$acc routine(sub1) gang(dim:1)
+ real, dimension(10) :: a
+ call sub1(a)
+end subroutine
+
+subroutine sub3()
+ !$acc routine bind(sub1)
+end subroutine
+
+subroutine sub4()
+ !ERROR: Only the dim argument is allowed on the GANG clause on the ROUTINE directive
+ !$acc routine gang(num: 1)
+end subroutine
+
+subroutine sub5()
+ !ERROR: Only the dim argument is allowed on the GANG clause on the ROUTINE directive
+ !$acc routine gang(static: 1)
+end subroutine
+
+subroutine sub6()
+ !ERROR: Clause GANG is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang gang
+
+ !ERROR: Clause GANG is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker gang
+
+ !ERROR: Clause GANG is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector gang
+
+ !ERROR: Clause GANG is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq gang
+
+ !ERROR: Clause WORKER is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker worker
+
+ !ERROR: Clause WORKER is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang worker
+
+ !ERROR: Clause WORKER is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector worker
+
+ !ERROR: Clause WORKER is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq worker
+
+ !ERROR: Clause VECTOR is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector vector
+
+ !ERROR: Clause VECTOR is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang vector
+
+ !ERROR: Clause VECTOR is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker vector
+
+ !ERROR: Clause VECTOR is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq vector
+
+ !ERROR: Clause SEQ is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq seq
+
+ !ERROR: Clause SEQ is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang seq
+
+ !ERROR: Clause SEQ is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker seq
+
+ !ERROR: Clause SEQ is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector seq
+
+end subroutine
+
+subroutine sub7()
+ !$acc routine device_type(*) gang device_type(host) worker
+
+ !ERROR: Clause SEQ is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine device_type(*) gang seq
+
+ !ERROR: Clause WORKER is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine device_type(*) gang worker
+
+ !ERROR: Clause GANG is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang device_type(*) gang
+
+ !ERROR: Clause WORKER is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang device_type(*) worker
+
+ !ERROR: Clause VECTOR is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang device_type(*) vector
+
+ !ERROR: Clause SEQ is not allowed if clause GANG appears on the ROUTINE directive
+ !$acc routine gang device_type(*) seq
+
+ !ERROR: Clause WORKER is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker device_type(*) worker
+
+ !ERROR: Clause GANG is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker device_type(*) gang
+
+ !ERROR: Clause VECTOR is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker device_type(*) vector
+
+ !ERROR: Clause SEQ is not allowed if clause WORKER appears on the ROUTINE directive
+ !$acc routine worker device_type(*) seq
+
+ !ERROR: Clause VECTOR is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector device_type(*) vector
+
+ !ERROR: Clause GANG is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector device_type(*) gang
+
+ !ERROR: Clause VECTOR is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector device_type(*) vector
+
+ !ERROR: Clause SEQ is not allowed if clause VECTOR appears on the ROUTINE directive
+ !$acc routine vector device_type(*) seq
+
+ !ERROR: Clause SEQ is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq device_type(*) seq
+
+ !ERROR: Clause GANG is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq device_type(*) gang
+
+ !ERROR: Clause VECTOR is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq device_type(*) vector
+
+ !ERROR: Clause WORKER is not allowed if clause SEQ appears on the ROUTINE directive
+ !$acc routine seq device_type(*) worker
+
+ !$acc routine device_type(host) seq device_type(nvidia) gang device_type(multicore) vector device_type(*) worker
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-serial-loop.f90 b/flang/test/SemanticsChecked/OpenACC/acc-serial-loop.f90
new file mode 100644
index 0000000000000..2832274680eca
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-serial-loop.f90
@@ -0,0 +1,114 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.11 Serial Loop
+
+program openacc_serial_loop_validity
+
+ implicit none
+
+ integer :: i, b
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ integer :: async1
+ integer :: wait1, wait2
+ real :: reduction_r
+ logical :: reduction_l
+ logical :: ifCondition = .TRUE.
+ real(8), dimension(N) :: a
+
+
+ !$acc serial loop reduction(+: reduction_r)
+ do i = 1, N
+ reduction_r = a(i) + i
+ end do
+
+ !$acc serial loop reduction(*: reduction_r)
+ do i = 1, N
+ reduction_r = reduction_r * (a(i) + i)
+ end do
+
+ !$acc serial loop reduction(min: reduction_r)
+ do i = 1, N
+ reduction_r = min(reduction_r, a(i) * i)
+ end do
+
+ !$acc serial loop reduction(max: reduction_r)
+ do i = 1, N
+ reduction_r = max(reduction_r, a(i) * i)
+ end do
+
+ !$acc serial loop reduction(iand: b)
+ do i = 1, N
+ b = iand(b, c(i))
+ end do
+
+ !$acc serial loop reduction(ior: b)
+ do i = 1, N
+ b = ior(b, c(i))
+ end do
+
+ !$acc serial loop reduction(ieor: b)
+ do i = 1, N
+ b = ieor(b, c(i))
+ end do
+
+ !$acc serial loop reduction(.and.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .and. e(i)
+ end do
+
+ !$acc serial loop reduction(.or.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .or. e(i)
+ end do
+
+ !$acc serial loop reduction(.eqv.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .eqv. e(i)
+ end do
+
+ !$acc serial loop reduction(.neqv.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .neqv. e(i)
+ end do
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the SERIAL LOOP directive
+ !$acc serial loop device_type(*) if(.TRUE.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end serial loop
+
+ !$acc serial loop if(ifCondition)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end serial loop
+
+ !$acc serial loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !ERROR: Unmatched END PARALLEL LOOP directive
+ !$acc end parallel loop
+
+ !$acc serial loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end serial loop
+
+ !$acc serial loop
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end serial
+
+ !$acc serial loop
+ do i = 1, n
+ if(i == 10) cycle
+ end do
+
+end program openacc_serial_loop_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-serial.f90 b/flang/test/SemanticsChecked/OpenACC/acc-serial.f90
new file mode 100644
index 0000000000000..a23daecce8dd3
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-serial.f90
@@ -0,0 +1,182 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc -pedantic
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.5.2 Serial
+
+program openacc_serial_validity
+
+ implicit none
+
+ type atype
+ real(8), dimension(10) :: arr
+ real(8) :: s
+ end type atype
+
+ integer :: i, j, b, gang_size, vector_size, worker_size
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ logical, dimension(N) :: d, e
+ integer :: async1
+ integer :: wait1, wait2
+ real :: reduction_r
+ logical :: reduction_l
+ real(8), dimension(N, N) :: aa, bb, cc
+ real(8), dimension(:), allocatable :: dd
+ real(8), pointer :: p
+ logical :: ifCondition = .TRUE.
+ type(atype) :: t
+ type(atype), dimension(10) :: ta
+
+ real(8), dimension(N) :: a, f, g, h
+
+ !$acc serial
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ !$acc end serial
+
+ !$acc serial
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ a(i) = 3.14
+ end do
+ !$acc end serial
+
+ !$acc serial
+ !$acc end serial
+
+ !$acc serial async
+ !$acc end serial
+
+ !$acc serial async(1)
+ !$acc end serial
+
+ !ERROR: At most one ASYNC clause can appear on the SERIAL directive
+ !$acc serial async(1) async(2)
+ !$acc end serial
+
+ !$acc serial async(async1)
+ !$acc end serial
+
+ !$acc serial wait
+ !$acc end serial
+
+ !$acc serial wait(1)
+ !$acc end serial
+
+ !$acc serial wait(wait1)
+ !$acc end serial
+
+ !$acc serial wait(1,2)
+ !$acc end serial
+
+ !$acc serial wait(wait1, wait2)
+ !$acc end serial
+
+ !$acc serial wait(wait1) wait(wait2)
+ !$acc end serial
+
+ !PORTABILITY: NUM_GANGS clause is not allowed on the SERIAL directive and will be ignored
+ !$acc serial num_gangs(8)
+ !$acc end serial
+
+ !PORTABILITY: NUM_WORKERS clause is not allowed on the SERIAL directive and will be ignored
+ !$acc serial num_workers(8)
+ !$acc end serial
+
+ !PORTABILITY: VECTOR_LENGTH clause is not allowed on the SERIAL directive and will be ignored
+ !$acc serial vector_length(128)
+ !$acc end serial
+
+ !$acc serial if(.true.)
+ !$acc end serial
+
+ !ERROR: At most one IF clause can appear on the SERIAL directive
+ !$acc serial if(.true.) if(ifCondition)
+ !$acc end serial
+
+ !$acc serial if(ifCondition)
+ !$acc end serial
+
+ !$acc serial self
+ !$acc end serial
+
+ !$acc serial self(.true.)
+ !$acc end serial
+
+ !$acc serial self(ifCondition)
+ !$acc end serial
+
+ !$acc serial reduction(.neqv.: reduction_l)
+ !$acc loop reduction(.neqv.: reduction_l)
+ do i = 1, N
+ reduction_l = d(i) .neqv. e(i)
+ end do
+ !$acc end serial
+
+ !$acc serial copy(aa) copyin(bb) copyout(cc)
+ !$acc end serial
+
+ !$acc serial copy(aa, bb) copyout(zero: cc)
+ !$acc end serial
+
+ !$acc serial present(aa, bb) create(cc)
+ !$acc end serial
+
+ !$acc serial copyin(readonly: aa, bb) create(zero: cc)
+ !$acc end serial
+
+ !$acc serial deviceptr(aa, bb) no_create(cc)
+ !$acc end serial
+
+ !ERROR: Argument `aa` on the ATTACH clause must be a variable or array with the POINTER or ALLOCATABLE attribute
+ !$acc serial attach(aa, dd, p)
+ !$acc end serial
+
+ !$acc serial firstprivate(bb, cc)
+ !$acc end serial
+
+ !$acc serial private(aa)
+ !$acc end serial
+
+ !$acc serial default(none)
+ !$acc end serial
+
+ !$acc serial default(present)
+ !$acc end serial
+
+ !ERROR: At most one DEFAULT clause can appear on the SERIAL directive
+ !$acc serial default(present) default(none)
+ !$acc end serial
+
+ !$acc serial device_type(*) async wait
+ !$acc end serial
+
+ !$acc serial device_type(*) async
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end serial
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the SERIAL directive
+ !$acc serial device_type(*) if(.TRUE.)
+ do i = 1, N
+ a(i) = 3.14
+ end do
+ !$acc end serial
+
+ do i = 1, 100
+ !$acc serial
+ !ERROR: CYCLE to construct outside of SERIAL construct is not allowed
+ if (i == 10) cycle
+ !$acc end serial
+ end do
+
+ !$acc serial
+ do i = 1, 100
+ if (i == 10) cycle
+ end do
+ !$acc end serial
+
+end program openacc_serial_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-set-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-set-validity.f90
new file mode 100644
index 0000000000000..74522b30d11bc
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-set-validity.f90
@@ -0,0 +1,108 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.14.3 Set
+
+program openacc_clause_validity
+
+ implicit none
+
+ integer :: i, j
+ integer, parameter :: N = 256
+ real(8), dimension(N) :: a
+
+ !$acc parallel
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ !$acc end parallel
+
+ !$acc serial
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ !$acc end serial
+
+ !$acc kernels
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ !$acc end kernels
+
+ !$acc parallel
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc serial
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ a(i) = 3.14
+ end do
+ !$acc end serial
+
+ !$acc kernels
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ a(i) = 3.14
+ end do
+ !$acc end kernels
+
+ !$acc parallel loop
+ do i = 1, N
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ a(i) = 3.14
+ end do
+
+ !$acc serial loop
+ do i = 1, N
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop
+ do i = 1, N
+ !ERROR: Directive SET may not be called within a compute region
+ !$acc set default_async(i)
+ a(i) = 3.14
+ end do
+
+ !ERROR: At least one of DEFAULT_ASYNC, DEVICE_NUM, DEVICE_TYPE clause must appear on the SET directive
+ !$acc set
+
+ !ERROR: At least one of DEFAULT_ASYNC, DEVICE_NUM, DEVICE_TYPE clause must appear on the SET directive
+ !$acc set if(.TRUE.)
+
+ !ERROR: At most one DEFAULT_ASYNC clause can appear on the SET directive
+ !$acc set default_async(2) default_async(1)
+
+ !ERROR: At most one DEFAULT_ASYNC clause can appear on the SET directive
+ !$acc set default_async(2) default_async(1)
+
+ !ERROR: At most one DEVICE_NUM clause can appear on the SET directive
+ !$acc set device_num(1) device_num(i)
+
+ !ERROR: At most one DEVICE_TYPE clause can appear on the SET directive
+ !$acc set device_type(*) device_type(nvidia)
+
+ !$acc set default_async(2)
+ !$acc set default_async(i)
+ !$acc set device_num(1)
+ !$acc set device_num(i)
+ !$acc set device_type(default)
+ !$acc set device_num(1) default_async(2) device_type(*)
+
+ !ERROR: The DEVICE_TYPE clause on the SET directive accepts only one value
+ !$acc set device_type(*, default)
+
+ !ERROR: At least one of DEFAULT_ASYNC, DEVICE_NUM, DEVICE_TYPE clause must appear on the SET directive
+ !$acc set
+
+end program openacc_clause_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-shutdown-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-shutdown-validity.f90
new file mode 100644
index 0000000000000..43aed4fc98f42
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-shutdown-validity.f90
@@ -0,0 +1,96 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.14.2 Shutdown
+
+program openacc_shutdown_validity
+
+ implicit none
+
+ integer :: i, j
+ integer, parameter :: N = 256
+ logical :: ifCondition = .TRUE.
+ real(8), dimension(N) :: a
+
+ !$acc parallel
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ !$acc end parallel
+
+ !$acc serial
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ !$acc end serial
+
+ !$acc kernels
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ !$acc end kernels
+
+ !$acc parallel
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ a(i) = 3.14
+ end do
+ !$acc end parallel
+
+ !$acc serial
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ a(i) = 3.14
+ end do
+ !$acc end serial
+
+ !$acc kernels
+ !$acc loop
+ do i = 1, N
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ a(i) = 3.14
+ end do
+ !$acc end kernels
+
+ !$acc parallel loop
+ do i = 1, N
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ a(i) = 3.14
+ end do
+
+ !$acc serial loop
+ do i = 1, N
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ a(i) = 3.14
+ end do
+
+ !$acc kernels loop
+ do i = 1, N
+ !ERROR: Directive SHUTDOWN may not be called within a compute region
+ !$acc shutdown
+ a(i) = 3.14
+ end do
+
+ !$acc shutdown
+ !$acc shutdown if(.TRUE.)
+ !$acc shutdown if(ifCondition)
+ !$acc shutdown device_num(1)
+ !$acc shutdown device_num(i)
+ !$acc shutdown device_type(*)
+ !$acc shutdown device_type(*, default, host)
+ !$acc shutdown device_num(i) device_type(default, host) if(ifCondition)
+
+ !ERROR: At most one IF clause can appear on the SHUTDOWN directive
+ !$acc shutdown if(.TRUE.) if(ifCondition)
+
+ !ERROR: At most one DEVICE_NUM clause can appear on the SHUTDOWN directive
+ !$acc shutdown device_num(1) device_num(i)
+
+ !ERROR: At most one DEVICE_TYPE clause can appear on the SHUTDOWN directive
+ !$acc shutdown device_type(*) device_type(host, default)
+
+end program openacc_shutdown_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-symbols01.f90 b/flang/test/SemanticsChecked/OpenACC/acc-symbols01.f90
new file mode 100644
index 0000000000000..375445bad13a5
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-symbols01.f90
@@ -0,0 +1,26 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenacc
+
+!DEF: /mm MainProgram
+program mm
+ !DEF: /mm/x ObjectEntity REAL(4)
+ !DEF: /mm/y ObjectEntity REAL(4)
+ real x, y
+ !DEF: /mm/a ObjectEntity INTEGER(4)
+ !DEF: /mm/b ObjectEntity INTEGER(4)
+ !DEF: /mm/c ObjectEntity INTEGER(4)
+ !DEF: /mm/i ObjectEntity INTEGER(4)
+ integer a(10), b(10), c(10), i
+ !REF: /mm/b
+ b = 2
+ !$acc parallel present(c) firstprivate(b) private(a)
+ !$acc loop
+ !REF: /mm/i
+ do i=1,10
+ !REF: /mm/a
+ !REF: /mm/i
+ !REF: /mm/b
+ a(i) = b(i)
+ end do
+ !$acc end parallel
+ end program
+
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-symbols02.f90 b/flang/test/SemanticsChecked/OpenACC/acc-symbols02.f90
new file mode 100644
index 0000000000000..0627af80b1563
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-symbols02.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenacc
+
+!DEF:/acc_declare_symbolsModule
+module acc_declare_symbols
+ !DEF: /acc_declare_symbols/a PUBLIC (AccCreate, AccDeclare) ObjectEntity REAL(4)
+ real a(100)
+ !$acc declare create(a)
+
+ !DEF:/acc_declare_symbols/b PUBLIC (AccCopyIn, AccDeclare) ObjectEntity REAL(4)
+ real b(20)
+ !$acc declare copyin(b)
+
+ !DEF:/acc_declare_symbols/c PUBLIC (AccDeviceResident, AccDeclare) ObjectEntity REAL(4)
+ real c(10)
+ !$acc declare device_resident(c)
+
+ !DEF:/acc_declare_symbols/d PUBLIC (AccLink, AccDeclare) ObjectEntity REAL(4)
+ real d(10)
+ !$acc declare link(d)
+
+end module
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-update-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-update-validity.f90
new file mode 100644
index 0000000000000..1e75742e63e97
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-update-validity.f90
@@ -0,0 +1,67 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.14.4 Update
+
+program openacc_update_validity
+
+ implicit none
+
+ type atype
+ real(8), dimension(10) :: arr
+ end type atype
+
+ integer :: i
+ integer, parameter :: N = 256
+ integer, dimension(N) :: c
+ integer :: async1
+ integer :: wait1, wait2
+ real(8), dimension(N, N) :: aa, bb, cc
+ logical :: ifCondition = .TRUE.
+ type(atype) :: t
+ type(atype), dimension(10) :: ta
+ real(8), dimension(N) :: a, f, g, h
+
+ !ERROR: At least one of DEVICE, HOST, SELF clause must appear on the UPDATE directive
+ !$acc update
+
+ !$acc update device(t%arr(:))
+
+ !$acc update device(ta(i)%arr(:))
+
+ !$acc update self(a, f) host(g) device(h)
+
+ !$acc update host(aa) async(1)
+
+ !$acc update device(bb) async(async1)
+
+ !ERROR: At most one ASYNC clause can appear on the UPDATE directive
+ !$acc update host(aa, bb) async(1) async(2)
+
+ !$acc update self(bb, cc(:,:)) wait(1)
+
+ !ERROR: SELF clause on the UPDATE directive must have a var-list
+ !$acc update self
+
+ !$acc update device(aa, bb, cc) wait(wait1)
+
+ !$acc update host(aa) host(bb) device(cc) wait(1,2)
+
+ !$acc update device(aa, cc) wait(wait1, wait2)
+
+ !$acc update device(aa) device_type(*) async
+
+ !$acc update host(bb) device_type(*) wait
+
+ !$acc update self(cc) device_type(host,multicore) async device_type(*) wait
+
+ !ERROR: At most one IF clause can appear on the UPDATE directive
+ !$acc update device(aa) if(.true.) if(ifCondition)
+
+ !ERROR: At most one IF_PRESENT clause can appear on the UPDATE directive
+ !$acc update device(bb) if_present if_present
+
+ !ERROR: Clause IF is not allowed after clause DEVICE_TYPE on the UPDATE directive
+ !$acc update device(i) device_type(*) if(.TRUE.)
+
+end program openacc_update_validity
diff --git a/flang/test/SemanticsChecked/OpenACC/acc-wait-validity.f90 b/flang/test/SemanticsChecked/OpenACC/acc-wait-validity.f90
new file mode 100644
index 0000000000000..25d603dad0502
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenACC/acc-wait-validity.f90
@@ -0,0 +1,42 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC clause validity for the following construct and directive:
+! 2.16.13 Wait
+
+program openacc_wait_validity
+
+ implicit none
+
+ logical :: ifCondition = .TRUE.
+
+ !$acc wait
+
+ !$acc wait async
+
+ !$acc wait(1)
+ !$acc wait(1, 2)
+
+ !$acc wait(queues: 1)
+ !$acc wait(queues: 1, 2)
+
+ !$acc wait(devnum: 1: 3)
+ !$acc wait(devnum: 1: 3, 4)
+
+ !$acc wait(devnum: 1: queues: 3)
+ !$acc wait(devnum: 1: queues: 3, 4)
+
+ !$acc wait(1) if(.true.)
+
+ !ERROR: At most one IF clause can appear on the WAIT directive
+ !$acc wait(1) if(.true.) if(.false.)
+
+ !$acc wait(1) if(.true.) async
+
+ !$acc wait(1) if(ifCondition) async
+
+ !$acc wait(1) if(.true.) async(1)
+
+ !ERROR: At most one ASYNC clause can appear on the WAIT directive
+ !$acc wait(1) if(.true.) async(1) async
+
+end program openacc_wait_validity
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate-clause01.f90 b/flang/test/SemanticsChecked/OpenMP/allocate-clause01.f90
new file mode 100644
index 0000000000000..2b9a72e928eba
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate-clause01.f90
@@ -0,0 +1,24 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! The allocate clause's allocator modifier must be of type allocator_handle
+! and the align modifier must be constant, positive integer expression
+
+subroutine allocate()
+ use omp_lib
+
+ integer, allocatable :: a, b, c
+
+ !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression
+ !$omp allocators allocate(-1: a)
+ allocate(a)
+
+ !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression
+ !$omp allocators allocate(allocator(-2), align(-3): b)
+ allocate(b)
+
+ !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression
+ !$omp allocators allocate(align(-4): c)
+ allocate(c)
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate-directive.f90 b/flang/test/SemanticsChecked/OpenMP/allocate-directive.f90
new file mode 100644
index 0000000000000..18a14b825f00d
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate-directive.f90
@@ -0,0 +1,27 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! Check OpenMP Allocate directive
+use omp_lib
+
+! 2.11.3 declarative allocate
+! 2.11.3 executable allocate
+
+integer :: x, y
+integer, allocatable :: a, b, m, n, t, z
+!$omp allocate(x, y)
+!$omp allocate(x, y) allocator(omp_default_mem_alloc)
+
+!$omp allocate(a, b)
+ allocate ( a, b )
+
+!$omp allocate(a, b) allocator(omp_default_mem_alloc)
+ allocate ( a, b )
+
+!$omp allocate(t) allocator(omp_const_mem_alloc)
+!$omp allocate(z) allocator(omp_default_mem_alloc)
+!$omp allocate(m) allocator(omp_default_mem_alloc)
+!$omp allocate(n)
+ allocate ( t, z, m, n )
+
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate01.f90 b/flang/test/SemanticsChecked/OpenMP/allocate01.f90
new file mode 100644
index 0000000000000..6ccb8bb09e830
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate01.f90
@@ -0,0 +1,27 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! The allocate directive must appear in the same scope as the declarations of
+! each of its list items and must follow all such declarations.
+
+subroutine allocate()
+use omp_lib
+ integer, allocatable :: x(:)
+ integer :: y
+ contains
+ subroutine sema()
+ integer :: a, b
+ real, dimension (:,:), allocatable :: darray
+
+ !ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
+ !$omp allocate(y)
+ print *, a
+
+ !ERROR: List items must be declared in the same scoping unit in which the ALLOCATE directive appears
+ !$omp allocate(x) allocator(omp_default_mem_alloc)
+ allocate ( x(a), darray(a, b) )
+ end subroutine sema
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate02.f90 b/flang/test/SemanticsChecked/OpenMP/allocate02.f90
new file mode 100644
index 0000000000000..8f0579e810bb9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate02.f90
@@ -0,0 +1,26 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! At most one allocator clause can appear on the allocate directive.
+
+subroutine allocate()
+use omp_lib
+ integer :: x, y
+ integer :: a, b
+ real, dimension (:,:), allocatable :: darray
+
+ !$omp allocate(x, y) allocator(omp_default_mem_alloc)
+
+ !ERROR: At most one ALLOCATOR clause can appear on the ALLOCATE directive
+ !$omp allocate(x, y) allocator(omp_default_mem_alloc) allocator(omp_default_mem_alloc)
+
+ !$omp allocate(darray) allocator(omp_default_mem_alloc)
+ allocate ( darray(a, b) )
+
+ !ERROR: At most one ALLOCATOR clause can appear on the ALLOCATE directive
+ !$omp allocate(darray) allocator(omp_default_mem_alloc) allocator(omp_default_mem_alloc)
+ allocate ( darray(a, b) )
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate03.f90 b/flang/test/SemanticsChecked/OpenMP/allocate03.f90
new file mode 100644
index 0000000000000..e35115f3897cc
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate03.f90
@@ -0,0 +1,25 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! A variable that is part of another variable (as an array or
+! structure element) cannot appear in an allocate directive.
+subroutine allocate()
+use omp_lib
+
+ type my_type
+ integer :: array(10)
+ end type my_type
+ type(my_type) :: my_var
+ real, dimension (:,:), allocatable :: darray
+ integer :: a, b
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the ALLOCATE directive
+ !$omp allocate(my_var%array)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the ALLOCATE directive
+ !$omp allocate(darray, my_var%array) allocator(omp_default_mem_alloc)
+ allocate ( darray(a, b) )
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate04.f90 b/flang/test/SemanticsChecked/OpenMP/allocate04.f90
new file mode 100644
index 0000000000000..ea89d9446cc14
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate04.f90
@@ -0,0 +1,16 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! Only the allocator clause is allowed on the allocate directive
+subroutine allocate()
+use omp_lib
+
+ integer :: x, y
+
+ !$omp allocate(x) allocator(omp_default_mem_alloc)
+
+ !ERROR: PRIVATE clause is not allowed on the ALLOCATE directive
+ !$omp allocate(y) private(y)
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate05.f90 b/flang/test/SemanticsChecked/OpenMP/allocate05.f90
new file mode 100644
index 0000000000000..a787e8bb32a4c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate05.f90
@@ -0,0 +1,26 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! allocate directives that appear in a target region must specify an allocator
+! clause unless a requires directive with the dynamic_allocators clause is present
+! in the same compilation unit.
+
+subroutine allocate()
+use omp_lib
+ integer :: a, b
+ real, dimension (:,:), allocatable :: darray
+
+ !$omp target
+ !$omp allocate allocator(omp_default_mem_alloc)
+ allocate ( darray(a, b) )
+ !$omp end target
+
+ !$omp target
+ !ERROR: ALLOCATE directives that appear in a TARGET region must specify an allocator clause
+ !$omp allocate
+ allocate ( darray(a, b) )
+ !$omp end target
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate06.f90 b/flang/test/SemanticsChecked/OpenMP/allocate06.f90
new file mode 100644
index 0000000000000..e14134cd07301
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate06.f90
@@ -0,0 +1,20 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! List items specified in the allocate directive must not have the ALLOCATABLE attribute unless the directive is associated with an
+! allocate statement.
+
+subroutine allocate()
+use omp_lib
+ integer :: a, b, x
+ real, dimension (:,:), allocatable :: darray
+
+ !ERROR: List items specified in the ALLOCATE directive must not have the ALLOCATABLE attribute unless the directive is associated with an ALLOCATE statement
+ !$omp allocate(darray) allocator(omp_default_mem_alloc)
+
+ !$omp allocate(darray) allocator(omp_default_mem_alloc)
+ allocate(darray(a, b))
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate07.f90 b/flang/test/SemanticsChecked/OpenMP/allocate07.f90
new file mode 100644
index 0000000000000..396df598b2521
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate07.f90
@@ -0,0 +1,37 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! A type parameter inquiry cannot appear in an allocate directive.
+
+subroutine allocate()
+use omp_lib
+ type my_type(kind_param, len_param)
+ INTEGER, KIND :: kind_param
+ INTEGER, LEN :: len_param
+ INTEGER :: array(10)
+ end type
+
+ type(my_type(2, 4)) :: my_var
+ INTEGER(KIND=4) :: x
+ CHARACTER(LEN=32) :: w
+ INTEGER, DIMENSION(:), ALLOCATABLE :: y
+
+ !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive
+ !$omp allocate(x%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive
+ !$omp allocate(w%LEN)
+
+ !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive
+ !$omp allocate(y%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive
+ !$omp allocate(my_var%kind_param)
+
+ !ERROR: A type parameter inquiry cannot appear on the ALLOCATE directive
+ !$omp allocate(my_var%len_param)
+
+end subroutine allocate
+
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate08.f90 b/flang/test/SemanticsChecked/OpenMP/allocate08.f90
new file mode 100644
index 0000000000000..fc950ea4fca36
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate08.f90
@@ -0,0 +1,44 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a
+! module, then only predefined memory allocator parameters can be used in the allocator clause
+
+module AllocateModule
+ INTEGER :: z
+end module
+
+subroutine allocate()
+use omp_lib
+use AllocateModule
+ integer, SAVE :: x
+ integer :: w
+ COMMON /CommonName/ y
+
+ integer(kind=omp_allocator_handle_kind) :: custom_allocator
+ integer(kind=omp_memspace_handle_kind) :: memspace
+ type(omp_alloctrait), dimension(1) :: trait
+ memspace = omp_default_mem_space
+ trait(1)%key = fallback
+ trait(1)%value = default_mem_fb
+ custom_allocator = omp_init_allocator(memspace, 1, trait)
+
+ !$omp allocate(x) allocator(omp_default_mem_alloc)
+ !$omp allocate(y) allocator(omp_default_mem_alloc)
+ !$omp allocate(z) allocator(omp_default_mem_alloc)
+
+ !$omp allocate(x)
+ !$omp allocate(y)
+ !$omp allocate(z)
+
+ !$omp allocate(w) allocator(custom_allocator)
+
+ !ERROR: If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a module, then only predefined memory allocator parameters can be used in the allocator clause
+ !$omp allocate(x) allocator(custom_allocator)
+ !ERROR: If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a module, then only predefined memory allocator parameters can be used in the allocator clause
+ !$omp allocate(y) allocator(custom_allocator)
+ !ERROR: If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a module, then only predefined memory allocator parameters can be used in the allocator clause
+ !$omp allocate(z) allocator(custom_allocator)
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocate09.f90 b/flang/test/SemanticsChecked/OpenMP/allocate09.f90
new file mode 100644
index 0000000000000..0f93a340fe1e4
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocate09.f90
@@ -0,0 +1,35 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.0
+! 2.11.3 allocate Directive
+! List items specified in an allocate directive that is associated
+! with an allocate statement must be variables that are allocated
+! by the allocate statement.
+
+subroutine allocate()
+use omp_lib
+ integer, dimension(:), allocatable :: a, b, c, d, e, f, &
+ g, h, i, j, k, l
+
+ !$omp allocate(a) allocator(omp_default_mem_alloc)
+ allocate(a(1), b(2))
+
+ !$omp allocate(c, d) allocator(omp_default_mem_alloc)
+ allocate(c(3), d(4))
+
+ !$omp allocate(e) allocator(omp_default_mem_alloc)
+ !$omp allocate(f, g) allocator(omp_default_mem_alloc)
+ !$omp allocate
+ allocate(e(5), f(6), g(7))
+
+ !ERROR: Object 'i' in ALLOCATE directive not found in corresponding ALLOCATE statement
+ !$omp allocate(h, i) allocator(omp_default_mem_alloc)
+ allocate(h(8))
+
+ !ERROR: Object 'j' in ALLOCATE directive not found in corresponding ALLOCATE statement
+ !$omp allocate(j, k) allocator(omp_default_mem_alloc)
+ !$omp allocate(l) allocator(omp_default_mem_alloc)
+ allocate(k(9), l(10))
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocators01.f90 b/flang/test/SemanticsChecked/OpenMP/allocators01.f90
new file mode 100644
index 0000000000000..c75c522ecae10
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocators01.f90
@@ -0,0 +1,23 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! 6.7 allocators construct
+! A list item that appears in an allocate clause must appear as
+! one of the variables that is allocated by the allocate-stmt in
+! the associated allocator structured block.
+
+subroutine allocate()
+use omp_lib
+
+ integer, allocatable :: arr1(:), arr2(:, :), arr3(:), arr4(:, :)
+
+ !$omp allocators allocate(arr3)
+ allocate(arr3(3), arr4(4, 4))
+ !$omp end allocators
+
+ !ERROR: Object 'arr1' in ALLOCATORS directive not found in corresponding ALLOCATE statement
+ !$omp allocators allocate(omp_default_mem_alloc: arr1, arr2)
+ allocate(arr2(2, 2))
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocators02.f90 b/flang/test/SemanticsChecked/OpenMP/allocators02.f90
new file mode 100644
index 0000000000000..8055d21c68095
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocators02.f90
@@ -0,0 +1,22 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! 6.7 allocators construct
+! A variable that is part of another variable (as an array or
+! structure element) cannot appear in an allocatprs construct.
+
+subroutine allocate()
+use omp_lib
+
+ type my_type
+ integer, allocatable :: array(:)
+ end type my_type
+
+ type(my_type) :: my_var
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the ALLOCATORS directive
+ !$omp allocators allocate(my_var%array)
+ allocate(my_var%array(10))
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocators03.f90 b/flang/test/SemanticsChecked/OpenMP/allocators03.f90
new file mode 100644
index 0000000000000..03cff1b1e9913
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocators03.f90
@@ -0,0 +1,17 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! 6.7 allocators construct
+! Only the allocate clause is allowed on the allocators construct
+
+subroutine allocate()
+use omp_lib
+
+ integer, allocatable :: arr1(:), arr2(:)
+
+ !ERROR: PRIVATE clause is not allowed on the ALLOCATORS directive
+ !$omp allocators allocate(arr1) private(arr2)
+ allocate(arr1(23), arr2(2))
+
+end subroutine allocate
diff --git a/flang/test/SemanticsChecked/OpenMP/allocators04.f90 b/flang/test/SemanticsChecked/OpenMP/allocators04.f90
new file mode 100644
index 0000000000000..1d2e96443a9da
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocators04.f90
@@ -0,0 +1,31 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! Inherited from 2.11.3 allocate Directive
+! If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a
+! module, then only predefined memory allocator parameters can be used in the allocator clause
+! SAVE and common block names can't be declared as allocatable, only module scope variables are tested
+
+module AllocateModule
+ integer, allocatable :: a, b
+end module
+
+subroutine allocate()
+ use omp_lib
+ use AllocateModule
+
+ integer(kind=omp_allocator_handle_kind) :: custom_allocator
+ type(omp_alloctrait) :: trait(1)
+
+ trait(1)%key = fallback
+ trait(1)%value = default_mem_fb
+ custom_allocator = omp_init_allocator(omp_default_mem_space, 1, trait)
+
+ !$omp allocators allocate(omp_default_mem_alloc: a)
+ allocate(a)
+
+ !ERROR: If list items within the ALLOCATORS directive have the SAVE attribute, are a common block name, or are declared in the scope of a module, then only predefined memory allocator parameters can be used in the allocator clause
+ !$omp allocators allocate(custom_allocator: b)
+ allocate(b)
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/allocators05.f90 b/flang/test/SemanticsChecked/OpenMP/allocators05.f90
new file mode 100644
index 0000000000000..d0e11ca5874d7
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocators05.f90
@@ -0,0 +1,26 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! Inherited from 2.11.3 allocate directive
+! allocate directives that appear in a target region must specify an
+! allocator clause unless a requires directive with the dynamic_allocators
+! clause is present in the same compilation unit.
+
+subroutine allocate()
+ use omp_lib
+
+ integer :: i
+ integer, allocatable :: a(:), b(:)
+ integer, parameter :: LEN = 2
+
+ !$omp target private(a, b)
+ !ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
+ !$omp allocators allocate(omp_default_mem_alloc: a)
+ allocate(a(LEN))
+ !ERROR: ALLOCATORS directives that appear in a TARGET region must specify an allocator
+ !ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
+ !$omp allocators allocate(b)
+ allocate(b(LEN))
+ !$omp end target
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/allocators06.f90 b/flang/test/SemanticsChecked/OpenMP/allocators06.f90
new file mode 100644
index 0000000000000..a975204c11339
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/allocators06.f90
@@ -0,0 +1,18 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! Inherited from 2.11.3 allocate directive
+! The allocate directive must appear in the same scope as the declarations of
+! each of its list items and must follow all such declarations.
+
+subroutine allocate()
+ use omp_lib
+ integer, allocatable :: a
+contains
+ subroutine test()
+ !ERROR: List items must be declared in the same scoping unit in which the ALLOCATORS directive appears
+ !$omp allocators allocate(omp_default_mem_alloc: a)
+ allocate(a)
+ end subroutine
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic-hint-clause.f90 b/flang/test/SemanticsChecked/OpenMP/atomic-hint-clause.f90
new file mode 100644
index 0000000000000..e157b7e1e73a7
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic-hint-clause.f90
@@ -0,0 +1,108 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! Semantic checks on hint clauses, as they appear on atomic constructs
+
+program sample
+ use omp_lib
+ integer :: x, y
+ logical :: z
+ real :: k
+ integer :: p(1)
+ integer, parameter :: a = 1
+ !$omp atomic hint(1) write
+ y = 2
+
+ !$omp atomic read hint(2)
+ y = x
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp atomic hint(3)
+ y = y + 10
+
+ !$omp atomic update hint(5)
+ y = x + y
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp atomic hint(7) capture
+ y = x
+ x = y
+ !$omp end atomic
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp atomic update hint(x)
+ y = y * 1
+
+ !$omp atomic read hint(4)
+ y = x
+
+ !$omp atomic hint(8)
+ x = x * y
+
+ !$omp atomic write hint(omp_sync_hint_uncontended)
+ x = 10 * y
+
+ !$omp atomic hint(omp_lock_hint_speculative)
+ x = y + x
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint) read
+ y = x
+
+ !$omp atomic hint(omp_sync_hint_nonspeculative)
+ y = y * 9
+
+ !$omp atomic hint(omp_sync_hint_none) read
+ y = x
+
+ !$omp atomic read hint(omp_sync_hint_uncontended + omp_lock_hint_speculative)
+ y = x
+
+ !$omp atomic hint(omp_lock_hint_nonspeculative + omp_lock_hint_uncontended)
+ x = x * y
+
+ !$omp atomic write hint(omp_lock_hint_contended + omp_sync_hint_speculative)
+ x = 10 * y
+
+ !$omp atomic hint(omp_lock_hint_contended + omp_sync_hint_nonspeculative)
+ x = y + x
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint_contended) read
+ y = x
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp atomic hint(omp_sync_hint_nonspeculative + omp_lock_hint_speculative)
+ y = y * 9
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !$omp atomic hint(1.0) read
+ y = x
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Operands of + must be numeric; have LOGICAL(4) and INTEGER(4)
+ !$omp atomic hint(z + omp_sync_hint_nonspeculative) read
+ y = x
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp atomic hint(k + omp_sync_hint_speculative) read
+ y = x
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp atomic hint(p(1) + omp_sync_hint_uncontended) write
+ x = 10 * y
+
+ !$omp atomic write hint(a)
+ !ERROR: RHS expression on atomic assignment statement cannot access 'x'
+ x = y + x
+
+ !$omp atomic hint(abs(-1)) write
+ x = 7
+
+ !$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint_uncontended + omp_sync_hint_speculative) write
+ x = 7
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic-update-overloaded-ops.f90 b/flang/test/SemanticsChecked/OpenMP/atomic-update-overloaded-ops.f90
new file mode 100644
index 0000000000000..21a9b87d26345
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic-update-overloaded-ops.f90
@@ -0,0 +1,31 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+module new_operator
+ implicit none
+
+ interface operator(.MYOPERATOR.)
+ module procedure myprocedure
+ end interface
+contains
+ pure integer function myprocedure(param1, param2)
+ integer, intent(in) :: param1, param2
+ myprocedure = param1 + param2
+ end function
+end module
+
+program sample
+ use new_operator
+ implicit none
+ integer :: x, y
+
+ !$omp atomic update
+ x = x / y
+
+ !$omp atomic update
+ !ERROR: Invalid or missing operator in atomic update statement
+ x = x .MYOPERATOR. y
+
+ !$omp atomic
+ !ERROR: Invalid or missing operator in atomic update statement
+ x = x .MYOPERATOR. y
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic.f90 b/flang/test/SemanticsChecked/OpenMP/atomic.f90
new file mode 100644
index 0000000000000..44f06b7460bf1
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic.f90
@@ -0,0 +1,58 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+use omp_lib
+! Check OpenMP 2.13.6 atomic Construct
+
+ a = 1.0
+ !$omp parallel num_threads(4)
+ !$omp atomic seq_cst, read
+ b = a
+
+ !$omp atomic seq_cst write
+ a = b
+ !$omp end atomic
+
+ !$omp atomic read acquire hint(OMP_LOCK_HINT_CONTENDED)
+ a = b
+
+ !$omp atomic release hint(OMP_LOCK_HINT_UNCONTENDED) write
+ a = b
+
+ !$omp atomic capture seq_cst
+ b = a
+ a = a + 1
+ !$omp end atomic
+
+ !$omp atomic hint(1) acq_rel capture
+ b = a
+ a = a + 1
+ !$omp end atomic
+
+ !ERROR: expected end of line
+ !$omp atomic read write
+ a = a + 1
+
+ !$omp atomic
+ a = a + 1
+ !ERROR: expected 'UPDATE'
+ !ERROR: expected 'WRITE'
+ !ERROR: expected 'CAPTURE'
+ !ERROR: expected 'READ'
+ !$omp atomic num_threads(4)
+ a = a + 1
+
+ !ERROR: expected end of line
+ !$omp atomic capture num_threads(4)
+ a = a + 1
+
+ !$omp atomic relaxed
+ a = a + 1
+
+ !ERROR: expected 'UPDATE'
+ !ERROR: expected 'WRITE'
+ !ERROR: expected 'CAPTURE'
+ !ERROR: expected 'READ'
+ !$omp atomic num_threads write
+ a = a + 1
+
+ !$omp end parallel
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic01.f90 b/flang/test/SemanticsChecked/OpenMP/atomic01.f90
new file mode 100644
index 0000000000000..f0e1b47d2fa16
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic01.f90
@@ -0,0 +1,404 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! Semantic checks for OpenMP 5.0 standard 2.17.7 atomic Construct.
+
+use omp_lib
+ implicit none
+ integer :: i, j = 10, k=-100, a
+! 2.17.7.1
+! Handled inside parser.
+! OpenMP constructs may not be encountered during execution of an atomic region
+
+! 2.17.7.2
+! At most one memory-order-clause may appear on the construct.
+
+!READ
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the READ directive
+ !$omp atomic seq_cst seq_cst read
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the READ directive
+ !$omp atomic read seq_cst seq_cst
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the READ directive
+ !$omp atomic seq_cst read seq_cst
+ i = j
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQUIRE clause can appear on the READ directive
+ !$omp atomic acquire acquire read
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQUIRE clause can appear on the READ directive
+ !$omp atomic read acquire acquire
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQUIRE clause can appear on the READ directive
+ !$omp atomic acquire read acquire
+ i = j
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the READ directive
+ !$omp atomic relaxed relaxed read
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the READ directive
+ !$omp atomic read relaxed relaxed
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the READ directive
+ !$omp atomic relaxed read relaxed
+ i = j
+
+!UPDATE
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the UPDATE directive
+ !$omp atomic seq_cst seq_cst update
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the UPDATE directive
+ !$omp atomic update seq_cst seq_cst
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the UPDATE directive
+ !$omp atomic seq_cst update seq_cst
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the UPDATE directive
+ !$omp atomic release release update
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the UPDATE directive
+ !$omp atomic update release release
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the UPDATE directive
+ !$omp atomic release update release
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the UPDATE directive
+ !$omp atomic relaxed relaxed update
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the UPDATE directive
+ !$omp atomic update relaxed relaxed
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the UPDATE directive
+ !$omp atomic relaxed update relaxed
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+!CAPTURE
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the CAPTURE directive
+ !$omp atomic seq_cst seq_cst capture
+ i = j
+ j = k
+ !$omp end atomic
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the CAPTURE directive
+ !$omp atomic capture seq_cst seq_cst
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the CAPTURE directive
+ !$omp atomic seq_cst capture seq_cst
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the CAPTURE directive
+ !$omp atomic release release capture
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the CAPTURE directive
+ !$omp atomic capture release release
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the CAPTURE directive
+ !$omp atomic release capture release
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the CAPTURE directive
+ !$omp atomic relaxed relaxed capture
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the CAPTURE directive
+ !$omp atomic capture relaxed relaxed
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the CAPTURE directive
+ !$omp atomic relaxed capture relaxed
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQ_REL clause can appear on the CAPTURE directive
+ !$omp atomic acq_rel acq_rel capture
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQ_REL clause can appear on the CAPTURE directive
+ !$omp atomic capture acq_rel acq_rel
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQ_REL clause can appear on the CAPTURE directive
+ !$omp atomic acq_rel capture acq_rel
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQUIRE clause can appear on the CAPTURE directive
+ !$omp atomic acquire acquire capture
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQUIRE clause can appear on the CAPTURE directive
+ !$omp atomic capture acquire acquire
+ i = j
+ j = k
+ !$omp end atomic
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one ACQUIRE clause can appear on the CAPTURE directive
+ !$omp atomic acquire capture acquire
+ i = j
+ j = k
+ !$omp end atomic
+
+!WRITE
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the WRITE directive
+ !$omp atomic seq_cst seq_cst write
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the WRITE directive
+ !$omp atomic write seq_cst seq_cst
+ i = j
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the WRITE directive
+ !$omp atomic seq_cst write seq_cst
+ i = j
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the WRITE directive
+ !$omp atomic release release write
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the WRITE directive
+ !$omp atomic write release release
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the WRITE directive
+ !$omp atomic release write release
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the WRITE directive
+ !$omp atomic relaxed relaxed write
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the WRITE directive
+ !$omp atomic write relaxed relaxed
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the WRITE directive
+ !$omp atomic relaxed write relaxed
+ i = j
+
+!No atomic-clause
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELAXED clause can appear on the ATOMIC directive
+ !$omp atomic relaxed relaxed
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one SEQ_CST clause can appear on the ATOMIC directive
+ !$omp atomic seq_cst seq_cst
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !ERROR: At most one RELEASE clause can appear on the ATOMIC directive
+ !$omp atomic release release
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+! 2.17.7.3
+! At most one hint clause may appear on the construct.
+
+ !ERROR: At most one HINT clause can appear on the READ directive
+ !$omp atomic hint(omp_sync_hint_speculative) hint(omp_sync_hint_speculative) read
+ i = j
+ !ERROR: At most one HINT clause can appear on the READ directive
+ !$omp atomic hint(omp_sync_hint_nonspeculative) read hint(omp_sync_hint_nonspeculative)
+ i = j
+ !ERROR: At most one HINT clause can appear on the READ directive
+ !$omp atomic read hint(omp_sync_hint_uncontended) hint (omp_sync_hint_uncontended)
+ i = j
+ !ERROR: At most one HINT clause can appear on the WRITE directive
+ !$omp atomic hint(omp_sync_hint_contended) hint(omp_sync_hint_speculative) write
+ i = j
+ !ERROR: At most one HINT clause can appear on the WRITE directive
+ !$omp atomic hint(omp_sync_hint_nonspeculative) write hint(omp_sync_hint_nonspeculative)
+ i = j
+ !ERROR: At most one HINT clause can appear on the WRITE directive
+ !$omp atomic write hint(omp_sync_hint_none) hint (omp_sync_hint_uncontended)
+ i = j
+ !ERROR: At most one HINT clause can appear on the WRITE directive
+ !$omp atomic hint(omp_sync_hint_contended) hint(omp_sync_hint_speculative) write
+ i = j
+ !ERROR: At most one HINT clause can appear on the WRITE directive
+ !$omp atomic hint(omp_sync_hint_nonspeculative) write hint(omp_sync_hint_nonspeculative)
+ i = j
+ !ERROR: At most one HINT clause can appear on the WRITE directive
+ !$omp atomic write hint(omp_sync_hint_none) hint (omp_sync_hint_uncontended)
+ i = j
+ !ERROR: At most one HINT clause can appear on the UPDATE directive
+ !$omp atomic hint(omp_sync_hint_contended) hint(omp_sync_hint_speculative) update
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: At most one HINT clause can appear on the UPDATE directive
+ !$omp atomic hint(omp_sync_hint_nonspeculative) update hint(omp_sync_hint_nonspeculative)
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: At most one HINT clause can appear on the UPDATE directive
+ !$omp atomic update hint(omp_sync_hint_none) hint (omp_sync_hint_uncontended)
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: At most one HINT clause can appear on the ATOMIC directive
+ !$omp atomic hint(omp_sync_hint_contended) hint(omp_sync_hint_speculative)
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: At most one HINT clause can appear on the ATOMIC directive
+ !$omp atomic hint(omp_sync_hint_none) hint(omp_sync_hint_nonspeculative)
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: At most one HINT clause can appear on the ATOMIC directive
+ !$omp atomic hint(omp_sync_hint_none) hint (omp_sync_hint_uncontended)
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+ !ERROR: At most one HINT clause can appear on the CAPTURE directive
+ !$omp atomic hint(omp_sync_hint_contended) hint(omp_sync_hint_speculative) capture
+ i = j
+ j = k
+ !$omp end atomic
+ !ERROR: At most one HINT clause can appear on the CAPTURE directive
+ !$omp atomic hint(omp_sync_hint_nonspeculative) capture hint(omp_sync_hint_nonspeculative)
+ i = j
+ j = k
+ !$omp end atomic
+ !ERROR: At most one HINT clause can appear on the CAPTURE directive
+ !$omp atomic capture hint(omp_sync_hint_none) hint (omp_sync_hint_uncontended)
+ i = j
+ j = k
+ !$omp end atomic
+! 2.17.7.4
+! If atomic-clause is read then memory-order-clause must not be acq_rel or release.
+
+ !ERROR: Clause ACQ_REL is not allowed if clause READ appears on the ATOMIC directive
+ !$omp atomic acq_rel read
+ i = j
+ !ERROR: Clause ACQ_REL is not allowed if clause READ appears on the ATOMIC directive
+ !$omp atomic read acq_rel
+ i = j
+
+ !ERROR: Clause RELEASE is not allowed if clause READ appears on the ATOMIC directive
+ !$omp atomic release read
+ i = j
+ !ERROR: Clause RELEASE is not allowed if clause READ appears on the ATOMIC directive
+ !$omp atomic read release
+ i = j
+
+! 2.17.7.5
+! If atomic-clause is write then memory-order-clause must not be acq_rel or acquire.
+
+ !ERROR: Clause ACQ_REL is not allowed if clause WRITE appears on the ATOMIC directive
+ !$omp atomic acq_rel write
+ i = j
+ !ERROR: Clause ACQ_REL is not allowed if clause WRITE appears on the ATOMIC directive
+ !$omp atomic write acq_rel
+ i = j
+
+ !ERROR: Clause ACQUIRE is not allowed if clause WRITE appears on the ATOMIC directive
+ !$omp atomic acquire write
+ i = j
+ !ERROR: Clause ACQUIRE is not allowed if clause WRITE appears on the ATOMIC directive
+ !$omp atomic write acquire
+ i = j
+
+
+! 2.17.7.6
+! If atomic-clause is update or not present then memory-order-clause must not be acq_rel or acquire.
+
+ !ERROR: Clause ACQ_REL is not allowed if clause UPDATE appears on the ATOMIC directive
+ !$omp atomic acq_rel update
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+ !ERROR: Clause ACQ_REL is not allowed if clause UPDATE appears on the ATOMIC directive
+ !$omp atomic update acq_rel
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+ !ERROR: Clause ACQUIRE is not allowed if clause UPDATE appears on the ATOMIC directive
+ !$omp atomic acquire update
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+ !ERROR: Clause ACQUIRE is not allowed if clause UPDATE appears on the ATOMIC directive
+ !$omp atomic update acquire
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+ !ERROR: Clause ACQ_REL is not allowed on the ATOMIC directive
+ !$omp atomic acq_rel
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+
+ !ERROR: Clause ACQUIRE is not allowed on the ATOMIC directive
+ !$omp atomic acquire
+ !ERROR: Invalid or missing operator in atomic update statement
+ i = j
+end program
+
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic02.f90 b/flang/test/SemanticsChecked/OpenMP/atomic02.f90
new file mode 100644
index 0000000000000..b823bc4c33b23
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic02.f90
@@ -0,0 +1,111 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+
+! OpenMP Atomic construct
+! section 2.17.7
+! operator is one of +, *, -, /, .AND., .OR., .EQV., or .NEQV
+
+program OmpAtomic
+ use omp_lib
+ CHARACTER c*3, d*3
+ LOGICAL l, m, n
+
+ a = 1
+ b = 2
+ c = 'foo'
+ d = 'bar'
+ m = .TRUE.
+ n = .FALSE.
+ !$omp parallel num_threads(4)
+
+ !$omp atomic
+ a = a + (4*2)
+ !$omp atomic
+ a = a*(b + 1)
+ !$omp atomic
+ a = a - 3
+ !$omp atomic
+ a = a/(b + 1)
+ !$omp atomic
+ !ERROR: Invalid or missing operator in atomic update statement
+ a = a**4
+ !$omp atomic
+ !ERROR: Invalid or missing operator in atomic update statement
+ c = c//d
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .LT. b
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .LE. b
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .EQ. b
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .NE. b
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .GE. b
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .GT. b
+ !$omp atomic
+ m = m .AND. n
+ !$omp atomic
+ m = m .OR. n
+ !$omp atomic
+ m = m .EQV. n
+ !$omp atomic
+ m = m .NEQV. n
+ !$omp atomic update
+ a = a + (4*2)
+ !$omp atomic update
+ a = a*(b + 1)
+ !$omp atomic update
+ a = a - 3
+ !$omp atomic update
+ a = a/(b + 1)
+ !$omp atomic update
+ !ERROR: Invalid or missing operator in atomic update statement
+ a = a**4
+ !$omp atomic update
+ !ERROR: Invalid or missing operator in atomic update statement
+ c = c//d
+ !$omp atomic update
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .LT. b
+ !$omp atomic update
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .LE. b
+ !$omp atomic update
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .EQ. b
+ !$omp atomic update
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .GE. b
+ !$omp atomic update
+ !ERROR: Atomic update statement should be of form `l = l operator expr` OR `l = expr operator l`
+ !ERROR: Invalid or missing operator in atomic update statement
+ l = a .GT. b
+ !$omp atomic update
+ m = m .AND. n
+ !$omp atomic update
+ m = m .OR. n
+ !$omp atomic update
+ m = m .EQV. n
+ !$omp atomic update
+ m = m .NEQV. n
+ !$omp end parallel
+end program OmpAtomic
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic03.f90 b/flang/test/SemanticsChecked/OpenMP/atomic03.f90
new file mode 100644
index 0000000000000..76367495b9861
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic03.f90
@@ -0,0 +1,144 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+
+! OpenMP Atomic construct
+! section 2.17.7
+! Intrinsic procedure name is one of MAX, MIN, IAND, IOR, or IEOR.
+
+program OmpAtomic
+ use omp_lib
+ real x
+ integer :: y, z, a, b, c, d
+ x = 5.73
+ y = 3
+ z = 1
+!$omp atomic
+ y = IAND(y, 4)
+!$omp atomic
+ y = IOR(y, 5)
+!$omp atomic
+ y = IEOR(y, 6)
+!$omp atomic
+ y = MAX(y, 7)
+!$omp atomic
+ y = MIN(y, 8)
+
+!$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = IAND(y, 4)
+!$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = IOR(y, 5)
+!$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = IEOR(y, 6)
+!$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = MAX(y, 7, b, c)
+!$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = MIN(y, 8, a, d)
+
+!$omp atomic
+ !ERROR: Invalid intrinsic procedure name in OpenMP ATOMIC (UPDATE) statement
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'y'
+ y = FRACTION(x)
+!$omp atomic
+ !ERROR: Invalid intrinsic procedure name in OpenMP ATOMIC (UPDATE) statement
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'y'
+ y = REAL(x)
+!$omp atomic update
+ y = IAND(y, 4)
+!$omp atomic update
+ y = IOR(y, 5)
+!$omp atomic update
+ y = IEOR(y, 6)
+!$omp atomic update
+ y = MAX(y, 7)
+!$omp atomic update
+ y = MIN(y, 8)
+
+!$omp atomic update
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = IAND(y, 4)
+!$omp atomic update
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = IOR(y, 5)
+!$omp atomic update
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = IEOR(y, 6)
+!$omp atomic update
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = MAX(y, 7)
+!$omp atomic update
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = MIN(y, 8)
+
+!$omp atomic update
+ !ERROR: Invalid intrinsic procedure name in OpenMP ATOMIC (UPDATE) statement
+ y = MOD(y, 9)
+!$omp atomic update
+ !ERROR: Invalid intrinsic procedure name in OpenMP ATOMIC (UPDATE) statement
+ x = ABS(x)
+end program OmpAtomic
+
+subroutine conflicting_types()
+ type simple
+ integer :: z
+ end type
+ real x
+ integer :: y, z
+ type(simple) ::s
+ z = 1
+ !$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'z'
+ z = IAND(s%z, 4)
+end subroutine
+
+subroutine more_invalid_atomic_update_stmts()
+ integer :: a, b
+ integer :: k(10)
+ type some_type
+ integer :: m(10)
+ end type
+ type(some_type) :: s
+
+ !$omp atomic update
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'a'
+ a = min(a, a, b)
+
+ !$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'a'
+ a = max(b, a, b, a)
+
+ !$omp atomic
+ !ERROR: Atomic update statement should be of the form `a = intrinsic_procedure(a, expr_list)` OR `a = intrinsic_procedure(expr_list, a)`
+ a = min(b, a, b)
+
+ !$omp atomic
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'a'
+ a = max(b, a, b, a, b)
+
+ !$omp atomic update
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'y'
+ y = min(z, x)
+
+ !$omp atomic
+ z = max(z, y)
+
+ !$omp atomic update
+ !ERROR: Expected scalar variable on the LHS of atomic update assignment statement
+ !ERROR: Intrinsic procedure arguments in atomic update statement must have exactly one occurence of 'k'
+ k = max(x, y)
+
+ !$omp atomic
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar REAL(4) and rank 1 array of REAL(4)
+ !ERROR: Expected scalar expression on the RHS of atomic update assignment statement
+ x = min(x, k)
+
+ !$omp atomic
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar REAL(4) and rank 1 array of REAL(4)
+ !ERROR: Expected scalar expression on the RHS of atomic update assignment statement
+ z =z + s%m
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic04.f90 b/flang/test/SemanticsChecked/OpenMP/atomic04.f90
new file mode 100644
index 0000000000000..a9644ad95aa30
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic04.f90
@@ -0,0 +1,265 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+
+! OpenMP Atomic construct
+! section 2.17.7
+! Update assignment must be 'var = var op expr' or 'var = expr op var'
+
+program OmpAtomic
+ use omp_lib
+ real x
+ integer y
+ logical m, n, l
+ x = 5.73
+ y = 3
+ m = .TRUE.
+ n = .FALSE.
+!$omp atomic
+ x = x + 1
+!$omp atomic
+ x = 1 + x
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y + 1
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1 + y
+
+!$omp atomic
+ x = x - 1
+!$omp atomic
+ x = 1 - x
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y - 1
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1 - y
+
+!$omp atomic
+ x = x*1
+!$omp atomic
+ x = 1*x
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y*1
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1*y
+
+!$omp atomic
+ x = x/1
+!$omp atomic
+ x = 1/x
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y/1
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1/y
+
+!$omp atomic
+ m = m .AND. n
+!$omp atomic
+ m = n .AND. m
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .AND. l
+
+!$omp atomic
+ m = m .OR. n
+!$omp atomic
+ m = n .OR. m
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .OR. l
+
+!$omp atomic
+ m = m .EQV. n
+!$omp atomic
+ m = n .EQV. m
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .EQV. l
+
+!$omp atomic
+ m = m .NEQV. n
+!$omp atomic
+ m = n .NEQV. m
+!$omp atomic
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .NEQV. l
+
+!$omp atomic update
+ x = x + 1
+!$omp atomic update
+ x = 1 + x
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y + 1
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1 + y
+
+!$omp atomic update
+ x = x - 1
+!$omp atomic update
+ x = 1 - x
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y - 1
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1 - y
+
+!$omp atomic update
+ x = x*1
+!$omp atomic update
+ x = 1*x
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y*1
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1*y
+
+!$omp atomic update
+ x = x/1
+!$omp atomic update
+ x = 1/x
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = y/1
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Exactly one occurence of 'x' expected on the RHS of atomic update assignment statement
+ x = 1/y
+
+!$omp atomic update
+ m = m .AND. n
+!$omp atomic update
+ m = n .AND. m
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .AND. l
+
+!$omp atomic update
+ m = m .OR. n
+!$omp atomic update
+ m = n .OR. m
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .OR. l
+
+!$omp atomic update
+ m = m .EQV. n
+!$omp atomic update
+ m = n .EQV. m
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .EQV. l
+
+!$omp atomic update
+ m = m .NEQV. n
+!$omp atomic update
+ m = n .NEQV. m
+!$omp atomic update
+ !ERROR: Atomic update statement should be of form `m = m operator expr` OR `m = expr operator m`
+ !ERROR: Exactly one occurence of 'm' expected on the RHS of atomic update assignment statement
+ m = n .NEQV. l
+
+end program OmpAtomic
+
+subroutine more_invalid_atomic_update_stmts()
+ integer :: a, b, c
+ integer :: d(10)
+ real :: x, y, z(10)
+ type some_type
+ real :: m
+ real :: n(10)
+ end type
+ type(some_type) p
+
+ !$omp atomic
+ !ERROR: Invalid or missing operator in atomic update statement
+ x = x
+
+ !$omp atomic update
+ !ERROR: Invalid or missing operator in atomic update statement
+ x = 1
+
+ !$omp atomic update
+ !ERROR: Exactly one occurence of 'a' expected on the RHS of atomic update assignment statement
+ a = a * b + a
+
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `a = a operator expr` OR `a = expr operator a`
+ a = b * (a + 9)
+
+ !$omp atomic update
+ !ERROR: Exactly one occurence of 'a' expected on the RHS of atomic update assignment statement
+ a = a * (a + b)
+
+ !$omp atomic
+ !ERROR: Exactly one occurence of 'a' expected on the RHS of atomic update assignment statement
+ a = (b + a) * a
+
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `a = a operator expr` OR `a = expr operator a`
+ a = a * b + c
+
+ !$omp atomic update
+ !ERROR: Atomic update statement should be of form `a = a operator expr` OR `a = expr operator a`
+ a = a + b + c
+
+ !$omp atomic
+ a = b * c + a
+
+ !$omp atomic update
+ a = c + b + a
+
+ !$omp atomic
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar INTEGER(4) and rank 1 array of INTEGER(4)
+ !ERROR: Expected scalar expression on the RHS of atomic update assignment statement
+ a = a + d
+
+ !$omp atomic update
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar REAL(4) and rank 1 array of REAL(4)
+ !ERROR: Atomic update statement should be of form `x = x operator expr` OR `x = expr operator x`
+ !ERROR: Expected scalar expression on the RHS of atomic update assignment statement
+ x = x * y / z
+
+ !$omp atomic
+ !ERROR: Atomic update statement should be of form `p%m = p%m operator expr` OR `p%m = expr operator p%m`
+ !ERROR: Exactly one occurence of 'p%m' expected on the RHS of atomic update assignment statement
+ p%m = x + y
+
+ !$omp atomic update
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar REAL(4) and rank 1 array of REAL(4)
+ !ERROR: Expected scalar expression on the RHS of atomic update assignment statement
+ !ERROR: Exactly one occurence of 'p%m' expected on the RHS of atomic update assignment statement
+ p%m = p%m + p%n
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/atomic05.f90 b/flang/test/SemanticsChecked/OpenMP/atomic05.f90
new file mode 100644
index 0000000000000..2d9566463309c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/atomic05.f90
@@ -0,0 +1,29 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
+
+! This tests the various semantics related to the clauses of various OpenMP atomic constructs
+
+program OmpAtomic
+ use omp_lib
+ integer :: g, x
+
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !$omp atomic relaxed, seq_cst
+ x = x + 1
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !$omp atomic read seq_cst, relaxed
+ x = g
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !$omp atomic write relaxed, release
+ x = 2 * 4
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !$omp atomic update release, seq_cst
+ !ERROR: Invalid or missing operator in atomic update statement
+ x = 10
+ !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct
+ !$omp atomic capture release, seq_cst
+ x = g
+ g = x * 10
+ !$omp end atomic
+end program OmpAtomic
diff --git a/flang/test/SemanticsChecked/OpenMP/barrier.f90 b/flang/test/SemanticsChecked/OpenMP/barrier.f90
new file mode 100644
index 0000000000000..1483fbd08f958
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/barrier.f90
@@ -0,0 +1,4 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+!$omp barrier
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/clause-validity01.f90 b/flang/test/SemanticsChecked/OpenMP/clause-validity01.f90
new file mode 100644
index 0000000000000..22ac57065ffec
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/clause-validity01.f90
@@ -0,0 +1,576 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags %openmp_module_flag
+use omp_lib
+! Check OpenMP clause validity for the following directives:
+!
+! 2.5 PARALLEL construct
+! 2.7.1 Loop construct
+! ...
+
+ use iso_c_binding
+ integer :: b = 128
+ integer, allocatable :: allc
+ type(C_PTR) :: cpt
+ integer :: z, c = 32
+ integer, parameter :: num = 16
+ real(8) :: arrayA(256), arrayB(512)
+
+ integer(omp_memspace_handle_kind) :: xy_memspace = omp_default_mem_space
+ type(omp_alloctrait) :: xy_traits(1) = [omp_alloctrait(omp_atk_alignment,64)]
+ integer(omp_allocator_handle_kind) :: xy_alloc
+ xy_alloc = omp_init_allocator(xy_memspace, 1, xy_traits)
+
+ arrayA = 1.414
+ arrayB = 3.14
+ N = 1024
+
+! 2.5 parallel-clause -> if-clause |
+! num-threads-clause |
+! default-clause |
+! private-clause |
+! firstprivate-clause |
+! shared-clause |
+! copyin-clause |
+! reduction-clause |
+! proc-bind-clause |
+! allocate-clause
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !$omp parallel private(b) allocate(b)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !$omp parallel private(c, b) allocate(omp_default_mem_space : b, c)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !$omp parallel allocate(b) allocate(c) private(b, c)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !$omp parallel allocate(xy_alloc :b) private(b)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !$omp task private(b) allocate(b)
+ do i = 1, N
+ z = 2
+ end do
+ !$omp end task
+
+ !$omp teams private(b) allocate(b)
+ do i = 1, N
+ z = 2
+ end do
+ !$omp end teams
+
+ !$omp target private(b) allocate(b)
+ do i = 1, N
+ z = 2
+ end do
+ !$omp end target
+
+ !ERROR: ALLOCATE clause is not allowed on the TARGET DATA directive
+ !$omp target data map(from: b) allocate(b)
+ do i = 1, N
+ z = 2
+ enddo
+ !$omp end target data
+
+ !ERROR: SCHEDULE clause is not allowed on the PARALLEL directive
+ !$omp parallel schedule(static)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !ERROR: COLLAPSE clause is not allowed on the PARALLEL directive
+ !$omp parallel collapse(2)
+ do i = 1, N
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end parallel
+
+ !ERROR: The parameter of the COLLAPSE clause must be a constant positive integer expression
+ !$omp do collapse(-1)
+ do i = 1, N
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end do
+
+ a = 1.0
+ !$omp parallel firstprivate(a)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !ERROR: NUM_THREADS clause is not allowed on the END PARALLEL directive
+ !$omp end parallel num_threads(4)
+
+ !ERROR: LASTPRIVATE clause is not allowed on the PARALLEL directive
+ !ERROR: NUM_TASKS clause is not allowed on the PARALLEL directive
+ !ERROR: INBRANCH clause is not allowed on the PARALLEL directive
+ !$omp parallel lastprivate(a) NUM_TASKS(4) inbranch
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !ERROR: At most one NUM_THREADS clause can appear on the PARALLEL directive
+ !$omp parallel num_threads(2) num_threads(4)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !ERROR: The parameter of the NUM_THREADS clause must be a positive integer expression
+ !$omp parallel num_threads(1-4)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !ERROR: NOWAIT clause is not allowed on the END PARALLEL directive
+ !$omp end parallel nowait
+
+ !$omp parallel num_threads(num-10)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !$omp parallel num_threads(b+1)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+ !$omp parallel
+ do i = 1, N
+ enddo
+ !ERROR: Unmatched END TARGET directive
+ !$omp end target
+
+ ! OMP 5.0 - 2.6 Restriction point 1
+ outofparallel: do k =1, 10
+ !$omp parallel
+ !$omp do
+ outer: do i=0, 10
+ inner: do j=1, 10
+ exit
+ exit outer
+ !ERROR: EXIT to construct 'outofparallel' outside of PARALLEL construct is not allowed
+ !ERROR: EXIT to construct 'outofparallel' outside of DO construct is not allowed
+ exit outofparallel
+ end do inner
+ end do outer
+ !$omp end do
+ !$omp end parallel
+ end do outofparallel
+
+! 2.7.1 do-clause -> private-clause |
+! firstprivate-clause |
+! lastprivate-clause |
+! linear-clause |
+! reduction-clause |
+! schedule-clause |
+! collapse-clause |
+! ordered-clause
+
+ !ERROR: When SCHEDULE clause has AUTO specified, it must not have chunk size specified
+ !ERROR: At most one SCHEDULE clause can appear on the DO directive
+ !ERROR: When SCHEDULE clause has RUNTIME specified, it must not have chunk size specified
+ !$omp do schedule(auto, 2) schedule(runtime, 2)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: A modifier may not be specified in a LINEAR clause on the DO directive
+ !$omp do linear(ref(b))
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: The NONMONOTONIC modifier can only be specified with SCHEDULE(DYNAMIC) or SCHEDULE(GUIDED)
+ !ERROR: The NONMONOTONIC modifier cannot be specified if an ORDERED clause is specified
+ !$omp do schedule(NONMONOTONIC:static) ordered
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !$omp do schedule(simd, monotonic:dynamic)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: Clause LINEAR is not allowed if clause ORDERED appears on the DO directive
+ !ERROR: The parameter of the ORDERED clause must be a constant positive integer expression
+ !$omp do ordered(1-1) private(b) linear(b) linear(a)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: The parameter of the ORDERED clause must be greater than or equal to the parameter of the COLLAPSE clause
+ !$omp do collapse(num-14) ordered(1)
+ do i = 1, N
+ do j = 1, N
+ do k = 1, N
+ a = 3.14
+ enddo
+ enddo
+ enddo
+
+ !$omp parallel do simd if(parallel:a>1.)
+ do i = 1, N
+ enddo
+ !$omp end parallel do simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp parallel do if(target:a>1.)
+ do i = 1, N
+ enddo
+ !ERROR: Unmatched END SIMD directive
+ !$omp end simd
+
+! 2.7.2 sections-clause -> private-clause |
+! firstprivate-clause |
+! lastprivate-clause |
+! reduction-clause
+
+ !$omp parallel
+ !$omp sections
+ !$omp section
+ a = 0.0
+ !$omp section
+ b = 1
+ !$omp end sections nowait
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp sections
+ !$omp section
+ a = 0.0
+ !ERROR: Unmatched END PARALLEL SECTIONS directive
+ !$omp end parallel sections
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp sections
+ a = 0.0
+ b = 1
+ !$omp section
+ c = 1
+ d = 2
+ !ERROR: NUM_THREADS clause is not allowed on the END SECTIONS directive
+ !$omp end sections num_threads(4)
+
+ !$omp parallel
+ !$omp sections
+ b = 1
+ !$omp section
+ c = 1
+ d = 2
+ !ERROR: At most one NOWAIT clause can appear on the END SECTIONS directive
+ !$omp end sections nowait nowait
+ !$omp end parallel
+
+ !$omp end parallel
+
+! 2.11.2 parallel-sections-clause -> parallel-clause |
+! sections-clause
+
+ !$omp parallel sections num_threads(4) private(b) lastprivate(d)
+ a = 0.0
+ !$omp section
+ b = 1
+ c = 2
+ !$omp section
+ d = 3
+ !$omp end parallel sections
+
+ !ERROR: At most one NUM_THREADS clause can appear on the PARALLEL SECTIONS directive
+ !$omp parallel sections num_threads(1) num_threads(4)
+ a = 0.0
+ !ERROR: Unmatched END SECTIONS directive
+ !$omp end sections
+
+ !$omp parallel sections
+ !ERROR: NOWAIT clause is not allowed on the END PARALLEL SECTIONS directive
+ !$omp end parallel sections nowait
+
+! 2.7.3 single-clause -> private-clause |
+! firstprivate-clause
+! end-single-clause -> copyprivate-clause |
+! nowait-clause
+
+ !$omp parallel
+ b = 1
+ !ERROR: LASTPRIVATE clause is not allowed on the SINGLE directive
+ !ERROR: NOWAIT clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive
+ !$omp single private(a) lastprivate(c) nowait
+ a = 3.14
+ !ERROR: Clause NOWAIT is not allowed if clause COPYPRIVATE appears on the END SINGLE directive
+ !ERROR: COPYPRIVATE variable 'a' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
+ !ERROR: At most one NOWAIT clause can appear on the END SINGLE directive
+ !$omp end single copyprivate(a) nowait nowait
+ c = 2
+ !$omp end parallel
+
+! 2.7.4 workshare
+
+ !$omp parallel
+ !$omp workshare
+ a = 1.0
+ !$omp end workshare nowait
+ !ERROR: NUM_THREADS clause is not allowed on the WORKSHARE directive
+ !$omp workshare num_threads(4)
+ a = 1.0
+ !ERROR: COPYPRIVATE clause is not allowed on the END WORKSHARE directive
+ !$omp end workshare nowait copyprivate(a)
+ !ERROR: NOWAIT clause is not allowed on the OMP WORKSHARE directive, use it on OMP END WORKSHARE directive
+ !$omp workshare nowait
+ !$omp end workshare
+ !$omp end parallel
+
+! 2.8.1 simd-clause -> safelen-clause |
+! simdlen-clause |
+! linear-clause |
+! aligned-clause |
+! private-clause |
+! lastprivate-clause |
+! reduction-clause |
+! collapse-clause
+
+ a = 0.0
+ !ERROR: TASK_REDUCTION clause is not allowed on the SIMD directive
+ !$omp simd private(b) reduction(+:a) task_reduction(+:a)
+ do i = 1, N
+ a = a + b + 3.14
+ enddo
+
+ !ERROR: At most one SAFELEN clause can appear on the SIMD directive
+ !$omp simd safelen(1) safelen(2)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: The parameter of the SIMDLEN clause must be a constant positive integer expression
+ !$omp simd simdlen(-1)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: The parameter of the ALIGNED clause must be a constant positive integer expression
+ !$omp simd aligned(cpt:-2)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !$omp parallel
+ !ERROR: The parameter of the SIMDLEN clause must be less than or equal to the parameter of the SAFELEN clause
+ !$omp simd safelen(1+1) simdlen(1+2)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+
+! 2.11.1 parallel-do-clause -> parallel-clause |
+! do-clause
+
+ !ERROR: At most one PROC_BIND clause can appear on the PARALLEL DO directive
+ !ERROR: A modifier may not be specified in a LINEAR clause on the PARALLEL DO directive
+ !$omp parallel do proc_bind(master) proc_bind(close) linear(val(b))
+ do i = 1, N
+ a = 3.14
+ enddo
+
+! 2.8.3 do-simd-clause -> do-clause |
+! simd-clause
+
+ !$omp parallel
+ !ERROR: No ORDERED clause with a parameter can be specified on the DO SIMD directive
+ !ERROR: NOGROUP clause is not allowed on the DO SIMD directive
+ !ERROR: NOWAIT clause is not allowed on the OMP DO SIMD directive, use it on OMP END DO SIMD directive
+ !$omp do simd ordered(2) NOGROUP nowait
+ do i = 1, N
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !omp end do nowait
+ !$omp end parallel
+
+! 2.11.4 parallel-do-simd-clause -> parallel-clause |
+! do-simd-clause
+
+ !$omp parallel do simd collapse(2) safelen(2) &
+ !$omp & simdlen(1) private(c) firstprivate(a) proc_bind(spread)
+ do i = 1, N
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+
+! 2.9.2 taskloop -> TASKLOOP [taskloop-clause[ [,] taskloop-clause]...]
+! taskloop-clause -> if-clause |
+! shared-clause |
+! private-clause |
+! firstprivate-clause |
+! lastprivate-clause |
+! default-clause |
+! grainsize-clause |
+! num-tasks-clause |
+! collapse-clause |
+! final-clause |
+! priority-clause |
+! untied-clause |
+! mergeable-clause |
+! nogroup-clause
+
+ !$omp taskloop
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: SCHEDULE clause is not allowed on the TASKLOOP directive
+ !$omp taskloop schedule(static)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: GRAINSIZE and NUM_TASKS clauses are mutually exclusive and may not appear on the same TASKLOOP directive
+ !$omp taskloop num_tasks(3) grainsize(2)
+ do i = 1,N
+ a = 3.14
+ enddo
+
+ !ERROR: At most one NUM_TASKS clause can appear on the TASKLOOP directive
+ !ERROR: TASK_REDUCTION clause is not allowed on the TASKLOOP directive
+ !$omp taskloop num_tasks(3) num_tasks(2) task_reduction(*:a)
+ do i = 1,N
+ a = 3.14
+ enddo
+
+! 2.13.1 master
+
+ !$omp parallel
+ !$omp master
+ a=3.14
+ !$omp end master
+ !$omp end parallel
+
+ !$omp parallel
+ !ERROR: NUM_THREADS clause is not allowed on the MASTER directive
+ !$omp master num_threads(4)
+ a=3.14
+ !$omp end master
+ !$omp end parallel
+
+! Standalone Directives (basic)
+
+ !$omp taskyield
+ !$omp barrier
+ !$omp taskwait
+ !ERROR: DEPEND(SOURCE) or DEPEND(SINK : vec) can be used only with the ordered directive. Used here in the TASKWAIT construct.
+ !$omp taskwait depend(source)
+ ! !$omp taskwait depend(sink:i-1)
+ ! !$omp target enter data map(to:arrayA) map(alloc:arrayB)
+ ! !$omp target update from(arrayA) to(arrayB)
+ ! !$omp target exit data map(from:arrayA) map(delete:arrayB)
+ !$omp flush (c)
+ !$omp flush acq_rel
+ !$omp flush release
+ !$omp flush acquire
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush release (c)
+ !ERROR: SEQ_CST clause is not allowed on the FLUSH directive
+ !$omp flush seq_cst
+ !ERROR: RELAXED clause is not allowed on the FLUSH directive
+ !$omp flush relaxed
+
+! 2.13.2 critical Construct
+
+ ! !$omp critical (first)
+ a = 3.14
+ ! !$omp end critical (first)
+
+! 2.9.1 task-clause -> if-clause |
+! final-clause |
+! untied-clause |
+! default-clause |
+! mergeable-clause |
+! private-clause |
+! firstprivate-clause |
+! shared-clause |
+! depend-clause |
+! priority-clause
+
+ !$omp task shared(a) default(none) if(task:a > 1.)
+ a = 1.
+ !$omp end task
+
+ !ERROR: Unmatched directive name modifier TASKLOOP on the IF clause
+ !$omp task private(a) if(taskloop:a.eq.1)
+ a = 1.
+ !$omp end task
+
+ !ERROR: LASTPRIVATE clause is not allowed on the TASK directive
+ !ERROR: At most one FINAL clause can appear on the TASK directive
+ !$omp task lastprivate(b) final(a.GE.1) final(.false.)
+ b = 1
+ !$omp end task
+
+ !ERROR: The parameter of the PRIORITY clause must be a positive integer expression
+ !$omp task priority(-1) firstprivate(a) mergeable
+ a = 3.14
+ !$omp end task
+
+! 2.9.3 taskloop-simd-clause -> taskloop-clause |
+! simd-clause
+
+ !$omp taskloop simd
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end taskloop simd
+
+ !$omp taskloop simd reduction(+:a)
+ do i = 1, N
+ a = a + 3.14
+ enddo
+ !ERROR: Unmatched END TASKLOOP directive
+ !$omp end taskloop
+
+ !ERROR: GRAINSIZE and NUM_TASKS clauses are mutually exclusive and may not appear on the same TASKLOOP SIMD directive
+ !$omp taskloop simd num_tasks(3) grainsize(2)
+ do i = 1,N
+ a = 3.14
+ enddo
+
+ allocate(allc)
+ !ERROR: The parameter of the SIMDLEN clause must be a constant positive integer expression
+ !ERROR: The parameter of the ALIGNED clause must be a constant positive integer expression
+ !$omp taskloop simd simdlen(-1) aligned(allc:-2)
+ do i = 1, N
+ allc = 3.14
+ enddo
+
+ !$omp target enter data map(alloc:A) device(0)
+ !$omp target exit data map(delete:A) device(0)
+
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/combined-constructs.f90 b/flang/test/SemanticsChecked/OpenMP/combined-constructs.f90
new file mode 100644
index 0000000000000..35ab6fcac58b9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/combined-constructs.f90
@@ -0,0 +1,511 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+program main
+ implicit none
+ integer :: N
+ integer :: i
+ real(8) :: a(256), b(256)
+ N = 256
+
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute simd
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end distribute simd
+
+ !$omp target parallel device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET PARALLEL directive
+ !$omp target parallel device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !$omp target parallel defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target parallel defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET PARALLEL directive
+ !$omp target parallel defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !$omp target parallel map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !ERROR: COPYIN clause is not allowed on the TARGET PARALLEL directive
+ !ERROR: Non-THREADPRIVATE object 'a' in COPYIN clause
+ !$omp target parallel copyin(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel
+
+ !$omp target parallel do device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET PARALLEL DO directive
+ !$omp target parallel do device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !$omp target parallel do defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target parallel do defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET PARALLEL DO directive
+ !$omp target parallel do defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !$omp target parallel do map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !ERROR: Non-THREADPRIVATE object 'a' in COPYIN clause
+ !$omp target parallel do copyin(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target parallel do
+
+ !$omp target teams map(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS directive
+ !$omp target teams device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: SCHEDULE clause is not allowed on the TARGET TEAMS directive
+ !$omp target teams schedule(static)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS directive
+ !$omp target teams defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS directive
+ !$omp target teams num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS directive
+ !$omp target teams thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS directive
+ !$omp target teams default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target teams map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+ !ERROR: Only the TO, FROM, TOFROM, ALLOC map types are permitted for MAP clauses on the TARGET TEAMS directive
+ !$omp target teams map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams
+
+
+ !$omp target teams distribute map(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams distribute defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams distribute num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams distribute thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !ERROR: Only the TO, FROM, TOFROM, ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE directive
+ !$omp target teams distribute map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute
+
+ !$omp target teams distribute parallel do device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams distribute parallel do defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams distribute parallel do num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams distribute parallel do thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+ !ERROR: Only the TO, FROM, TOFROM, ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE PARALLEL DO directive
+ !$omp target teams distribute parallel do map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do
+
+
+ !$omp target teams distribute parallel do simd map(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd device(0)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd device(0) device(1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target teams distribute parallel do simd defaultmap(tofrom)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd num_teams(2) num_teams(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp target teams distribute parallel do simd num_teams(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp target teams distribute parallel do simd thread_limit(-1)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: At most one DEFAULT clause can appear on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd default(shared) default(private)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd map(tofrom:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: Only the TO, FROM, TOFROM, ALLOC map types are permitted for MAP clauses on the TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD directive
+ !$omp target teams distribute parallel do simd map(delete:a)
+ do i = 1, N
+ a(i) = 3.14
+ enddo
+ !$omp end target teams distribute parallel do simd
+
+
+end program main
+
diff --git a/flang/test/SemanticsChecked/OpenMP/common-block.f90 b/flang/test/SemanticsChecked/OpenMP/common-block.f90
new file mode 100644
index 0000000000000..e1ddd120da857
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/common-block.f90
@@ -0,0 +1,18 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s
+
+program main
+ !CHECK: a size=4 offset=0: ObjectEntity type: REAL(4)
+ !CHECK: b size=8 offset=4: ObjectEntity type: INTEGER(4) shape: 1_8:2_8
+ !CHECK: c size=4 offset=12: ObjectEntity type: REAL(4)
+ !CHECK: blk size=16 offset=0: CommonBlockDetails alignment=4: a b c
+ real :: a, c
+ integer :: b(2)
+ common /blk/ a, b, c
+ !$omp parallel private(/blk/)
+ !CHECK: OtherConstruct scope: size=0 alignment=1
+ !CHECK: a (OmpPrivate): HostAssoc
+ !CHECK: b (OmpPrivate): HostAssoc
+ !CHECK: c (OmpPrivate): HostAssoc
+ call sub(a, b, c)
+ !$omp end parallel
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/compiler-directive.f90 b/flang/test/SemanticsChecked/OpenMP/compiler-directive.f90
new file mode 100644
index 0000000000000..5d3e9bae27fd8
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/compiler-directive.f90
@@ -0,0 +1,8 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! CompilerDirective with openmp tests
+
+!ERROR: !DIR$ IGNORE_TKR directive must appear in a subroutine or function
+!dir$ ignore_tkr
+
+program main
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/copyin01.f90 b/flang/test/SemanticsChecked/OpenMP/copyin01.f90
new file mode 100644
index 0000000000000..0051b5d441f05
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyin01.f90
@@ -0,0 +1,34 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A list item that appears in a copyin clause must be threadprivate
+
+program omp_copyin
+
+ integer :: i
+ integer, save :: k
+ integer :: a(10), b(10)
+ common /cmn/ j
+
+ k = 10
+
+ !ERROR: Non-THREADPRIVATE object 'k' in COPYIN clause
+ !$omp parallel do copyin(k)
+ do i = 1, 10
+ a(i) = k + i
+ j = j + a(i)
+ end do
+ !$omp end parallel do
+
+ print *, a
+
+ !ERROR: Non-THREADPRIVATE object 'j' in COPYIN clause
+ !$omp parallel do copyin(/cmn/)
+ do i = 1, 10
+ b(i) = a(i) + j
+ end do
+ !$omp end parallel do
+
+ print *, b
+
+end program omp_copyin
diff --git a/flang/test/SemanticsChecked/OpenMP/copyin02.f90 b/flang/test/SemanticsChecked/OpenMP/copyin02.f90
new file mode 100644
index 0000000000000..09b876677ea31
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyin02.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A common block name that appears in a copyin clause must be declared to be
+! a common block in the same scoping unit in which the copyin clause appears.
+
+subroutine copyin()
+ integer :: a = 10
+ common /cmn/ a
+
+ !$omp threadprivate(/cmn/)
+ call copyin_clause()
+
+ contains
+
+ subroutine copyin_clause()
+ !ERROR: COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears
+ !$omp parallel copyin(/cmn/)
+ print *, a
+ !$omp end parallel
+ end subroutine copyin_clause
+
+end subroutine copyin
diff --git a/flang/test/SemanticsChecked/OpenMP/copyin03.f90 b/flang/test/SemanticsChecked/OpenMP/copyin03.f90
new file mode 100644
index 0000000000000..7c3759aa2e116
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyin03.f90
@@ -0,0 +1,33 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A list item that appears in a copyin clause must be threadprivate.
+! Named variables appearing in a threadprivate common block may be specified
+! It is not necessary to specify the whole common block.
+
+program omp_copyin
+
+ integer :: a(10), b(10)
+ common /cmn/ j, k
+
+ !$omp threadprivate(/cmn/)
+
+ j = 20
+ k = 10
+
+ !$omp parallel copyin(/cmn/)
+ a(:5) = k
+ b(:5) = j
+ !$omp end parallel
+
+ j = j + k
+ k = k * j
+
+ !$omp parallel copyin(j, k)
+ a(6:) = j
+ b(6:) = k
+ !$omp end parallel
+
+ print *, a, b
+
+end program omp_copyin
diff --git a/flang/test/SemanticsChecked/OpenMP/copyin04.f90 b/flang/test/SemanticsChecked/OpenMP/copyin04.f90
new file mode 100644
index 0000000000000..6f5e8dfef217b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyin04.f90
@@ -0,0 +1,26 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A list item that appears in a copyin clause must be threadprivate
+
+program omp_copyin
+
+ integer :: i
+ integer, save :: j, k
+ integer :: a(10), b(10)
+
+ !$omp threadprivate(j, k)
+
+ j = 20
+ k = 10
+
+ !$omp parallel do copyin(j, k)
+ do i = 1, 10
+ a(i) = k + i
+ b(i) = j + i
+ end do
+ !$omp end parallel do
+
+ print *, a, b
+
+end program omp_copyin
diff --git a/flang/test/SemanticsChecked/OpenMP/copyin05.f90 b/flang/test/SemanticsChecked/OpenMP/copyin05.f90
new file mode 100644
index 0000000000000..142d5a7345c6e
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyin05.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.1 copyin Clause
+! A common block name that appears in a copyin clause must be declared to be
+! a common block in the same scoping unit in which the copyin clause appears.
+
+subroutine copyin()
+ call copyin_clause()
+
+ contains
+
+ subroutine copyin_clause()
+ integer :: a = 20
+ common /cmn/ a
+
+ !$omp threadprivate(/cmn/)
+
+ !$omp parallel copyin(/cmn/)
+ print *, a
+ !$omp end parallel
+ end subroutine copyin_clause
+
+end subroutine copyin
diff --git a/flang/test/SemanticsChecked/OpenMP/copying.f90 b/flang/test/SemanticsChecked/OpenMP/copying.f90
new file mode 100644
index 0000000000000..63fb39a0f26e5
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copying.f90
@@ -0,0 +1,52 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -Werror -pedantic
+! OpenMP Version 5.0
+! 2.19.4.4 firstprivate Clause
+! 2.19.4.5 lastprivate Clause
+! 2.19.6.1 copyin Clause
+! 2.19.6.2 copyprivate Clause
+! If the list item is a polymorphic variable with the allocatable attribute,
+! the behavior is unspecified.
+
+subroutine firstprivate()
+ class(*), allocatable, save :: x
+
+ !PORTABILITY: If a polymorphic variable with allocatable attribute 'x' is in FIRSTPRIVATE clause, the behavior is unspecified
+ !$omp parallel firstprivate(x)
+ call sub()
+ !$omp end parallel
+
+end
+
+subroutine lastprivate()
+ class(*), allocatable, save :: x
+
+ !PORTABILITY: If a polymorphic variable with allocatable attribute 'x' is in LASTPRIVATE clause, the behavior is unspecified
+ !$omp do lastprivate(x)
+ do i = 1, 10
+ call sub()
+ enddo
+ !$omp end do
+
+end
+
+subroutine copyin()
+ class(*), allocatable, save :: x
+ !$omp threadprivate(x)
+
+ !PORTABILITY: If a polymorphic variable with allocatable attribute 'x' is in COPYIN clause, the behavior is unspecified
+ !$omp parallel copyin(x)
+ call sub()
+ !$omp end parallel
+
+end
+
+subroutine copyprivate()
+ class(*), allocatable, save :: x
+ !$omp threadprivate(x)
+
+ !$omp single
+ call sub()
+ !PORTABILITY: If a polymorphic variable with allocatable attribute 'x' is in COPYPRIVATE clause, the behavior is unspecified
+ !$omp end single copyprivate(x)
+
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/copyprivate01.f90 b/flang/test/SemanticsChecked/OpenMP/copyprivate01.f90
new file mode 100644
index 0000000000000..d5cf273476078
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyprivate01.f90
@@ -0,0 +1,27 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.2 copyprivate Clause
+! A list item that appears in a copyprivate clause may not appear in a
+! private or firstprivate clause on the single construct.
+
+program omp_copyprivate
+ integer :: a(10), b(10), k
+
+ k = 10
+ a = 10
+ b = a * 10
+
+ !$omp parallel
+ !$omp single private(k)
+ a = a + k
+ !ERROR: COPYPRIVATE variable 'k' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
+ !$omp end single copyprivate(k)
+ !$omp single firstprivate(k)
+ b = a - k
+ !ERROR: COPYPRIVATE variable 'k' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
+ !$omp end single copyprivate(k)
+ !$omp end parallel
+
+ print *, a, b
+
+end program omp_copyprivate
diff --git a/flang/test/SemanticsChecked/OpenMP/copyprivate02.f90 b/flang/test/SemanticsChecked/OpenMP/copyprivate02.f90
new file mode 100644
index 0000000000000..35fd6dddd20c9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyprivate02.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.2 copyprivate Clause
+! Pointers with the INTENT(IN) attribute may not appear in a copyprivate clause.
+
+subroutine omp_copyprivate(p)
+ integer :: a(10), b(10), c(10)
+ integer, pointer, intent(in) :: p
+
+ a = 10
+ b = 20
+
+ !$omp parallel
+ !$omp single
+ c = a + b + p
+ !ERROR: COPYPRIVATE variable 'p' is not PRIVATE or THREADPRIVATE in outer context
+ !ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a COPYPRIVATE clause
+ !$omp end single copyprivate(p)
+ !$omp end parallel
+
+ print *, c
+
+end subroutine omp_copyprivate
diff --git a/flang/test/SemanticsChecked/OpenMP/copyprivate03.f90 b/flang/test/SemanticsChecked/OpenMP/copyprivate03.f90
new file mode 100644
index 0000000000000..9d39fdb6b13c8
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/copyprivate03.f90
@@ -0,0 +1,46 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.4.2 copyprivate Clause
+! All list items that appear in the copyprivate clause must be either
+! threadprivate or private in the enclosing context.
+
+program omp_copyprivate
+ integer :: a(10), b(10)
+ integer, save :: k
+
+ !$omp threadprivate(k)
+
+ k = 10
+ a = 10
+ b = a + 10
+
+ !$omp parallel
+ !$omp single
+ a = a + k
+ !$omp end single copyprivate(k)
+ !$omp single
+ b = b - a
+ !ERROR: COPYPRIVATE variable 'b' is not PRIVATE or THREADPRIVATE in outer context
+ !$omp end single copyprivate(b)
+ !$omp end parallel
+
+ !$omp parallel sections private(a)
+ !$omp section
+ !$omp parallel
+ !$omp single
+ a = a * b + k
+ !ERROR: COPYPRIVATE variable 'a' is not PRIVATE or THREADPRIVATE in outer context
+ !$omp end single copyprivate(a)
+ !$omp end parallel
+ !$omp end parallel sections
+
+ !The use of FIRSTPRIVATE with COPYPRIVATE is allowed
+ !$omp parallel firstprivate(a)
+ !$omp single
+ a = a + k
+ !$omp end single copyprivate(a)
+ !$omp end parallel
+
+ print *, a, b
+
+end program omp_copyprivate
diff --git a/flang/test/SemanticsChecked/OpenMP/critical-empty.f90 b/flang/test/SemanticsChecked/OpenMP/critical-empty.f90
new file mode 100644
index 0000000000000..2001c8a14a7ba
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/critical-empty.f90
@@ -0,0 +1,6 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! Test that there are no errors for an empty critical construct
+
+!$omp critical
+!$omp end critical
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/critical-hint-clause.f90 b/flang/test/SemanticsChecked/OpenMP/critical-hint-clause.f90
new file mode 100644
index 0000000000000..419187fa3bbfb
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/critical-hint-clause.f90
@@ -0,0 +1,120 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! Semantic checks on hint clauses, as they appear on critical construct
+
+program sample
+ use omp_lib
+ integer :: y
+ logical :: z
+ real :: k
+ integer :: p(1)
+
+ !$omp critical (name) hint(1)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(2)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp critical (name) hint(3)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(5)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp critical (name) hint(7)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp critical (name) hint(x)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(4)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(8)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_sync_hint_uncontended)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_lock_hint_speculative)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp critical (name) hint(omp_sync_hint_uncontended + omp_sync_hint)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_sync_hint_nonspeculative)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_sync_hint_none)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_sync_hint_uncontended + omp_lock_hint_speculative)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_lock_hint_nonspeculative + omp_lock_hint_uncontended)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_lock_hint_contended + omp_sync_hint_speculative)
+ y = 2
+ !$omp end critical (name)
+
+ !$omp critical (name) hint(omp_lock_hint_contended + omp_sync_hint_nonspeculative)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp critical (name) hint(omp_sync_hint_uncontended + omp_sync_hint_contended)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause value is not a valid OpenMP synchronization value
+ !$omp critical (name) hint(omp_sync_hint_nonspeculative + omp_lock_hint_speculative)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !$omp critical (name) hint(1.0)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Operands of + must be numeric; have LOGICAL(4) and INTEGER(4)
+ !$omp critical (name) hint(z + omp_sync_hint_nonspeculative)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp critical (name) hint(k + omp_sync_hint_speculative)
+ y = 2
+ !$omp end critical (name)
+
+ !ERROR: Hint clause must have non-negative constant integer expression
+ !ERROR: Must be a constant value
+ !$omp critical (name) hint(p(1) + omp_sync_hint_uncontended)
+ y = 2
+ !$omp end critical (name)
+end program
+
diff --git a/flang/test/SemanticsChecked/OpenMP/dealloc.f90 b/flang/test/SemanticsChecked/OpenMP/dealloc.f90
new file mode 100644
index 0000000000000..b25fa62377f68
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/dealloc.f90
@@ -0,0 +1,13 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+! Test to check that no errors are present when allocate statements
+! are applied on privatised variables.
+
+subroutine s
+ implicit none
+ double precision,allocatable,dimension(:) :: r
+ !$omp parallel private(r)
+ allocate(r(1))
+ deallocate(r)
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/declarative-directive.f90 b/flang/test/SemanticsChecked/OpenMP/declarative-directive.f90
new file mode 100644
index 0000000000000..4d10dc2d1b123
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declarative-directive.f90
@@ -0,0 +1,101 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! Check OpenMP declarative directives
+
+!TODO: all internal errors
+! enable declare-reduction example after name resolution
+
+! 2.4 requires
+
+subroutine requires_1(a)
+ real(8), intent(inout) :: a
+ !$omp requires reverse_offload, unified_shared_memory, atomic_default_mem_order(relaxed)
+ a = a + 0.01
+end subroutine requires_1
+
+subroutine requires_2(a)
+ real(8), intent(inout) :: a
+ !$omp requires unified_address
+ a = a + 0.01
+end subroutine requires_2
+
+! 2.8.2 declare-simd
+
+subroutine declare_simd_1(a, b)
+ real(8), intent(inout) :: a, b
+ !$omp declare simd(declare_simd_1) aligned(a)
+ a = 3.14 + b
+end subroutine declare_simd_1
+
+module m1
+ abstract interface
+ subroutine sub(x,y)
+ integer, intent(in)::x
+ integer, intent(in)::y
+ end subroutine sub
+ end interface
+end module m1
+
+subroutine declare_simd_2
+ use m1
+ procedure (sub) sub1
+ !ERROR: NOTINBRANCH and INBRANCH clauses are mutually exclusive and may not appear on the same DECLARE SIMD directive
+ !$omp declare simd(sub1) inbranch notinbranch
+ procedure (sub), pointer::p
+ p=>sub1
+ call p(5,10)
+end subroutine declare_simd_2
+
+subroutine sub1 (x,y)
+ integer, intent(in)::x, y
+ print *, x+y
+end subroutine sub1
+
+! 2.10.6 declare-target
+! 2.15.2 threadprivate
+
+module m2
+contains
+ subroutine foo
+ !$omp declare target
+ !WARNING: The entity with PARAMETER attribute is used in a DECLARE TARGET directive
+ !WARNING: The entity with PARAMETER attribute is used in a DECLARE TARGET directive
+ !$omp declare target (foo, N, M)
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target to(Q, S) link(R)
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target enter(Q, S) link(R)
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !ERROR: MAP clause is not allowed on the DECLARE TARGET directive
+ !$omp declare target to(Q) map(from:Q)
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !ERROR: MAP clause is not allowed on the DECLARE TARGET directive
+ !$omp declare target enter(Q) map(from:Q)
+ integer, parameter :: N=10000, M=1024
+ integer :: i
+ real :: Q(N, N), R(N,M), S(M,M)
+ !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp threadprivate(i)
+ end subroutine foo
+end module m2
+
+! 2.16 declare-reduction
+
+! subroutine declare_red_1()
+! use omp_lib
+! integer :: my_var
+! !$omp declare reduction (my_add_red : integer : omp_out = omp_out + omp_in) initializer (omp_priv=0)
+! my_var = 0
+! !$omp parallel reduction (my_add_red : my_var) num_threads(4)
+! my_var = omp_get_thread_num() + 1
+! !$omp end parallel
+! print *, "sum of thread numbers is ", my_var
+! end subroutine declare_red_1
+
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target-common-block.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target-common-block.f90
new file mode 100644
index 0000000000000..33a093a03a227
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target-common-block.f90
@@ -0,0 +1,10 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s
+
+PROGRAM main
+ !CHECK: one (OmpDeclareTarget) size=4 offset=0: ObjectEntity type: REAL(4)
+ !CHECK: two (OmpDeclareTarget) size=4 offset=4: ObjectEntity type: REAL(4)
+ !CHECK: numbers size=8 offset=0: CommonBlockDetails alignment=4: one two
+ REAL :: one, two
+ COMMON /numbers/ one, two
+ !$omp declare target(/numbers/)
+END
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target01.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target01.f90
new file mode 100644
index 0000000000000..2c50a9248280b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target01.f90
@@ -0,0 +1,169 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.14.7 Declare Target Directive
+
+module declare_target01
+ use omp_lib
+ type my_type(kind_param, len_param)
+ integer, KIND :: kind_param
+ integer, LEN :: len_param
+ integer :: t_i
+ integer :: t_arr(10)
+ end type my_type
+
+ type(my_type(2, 4)) :: my_var, my_var2
+ integer :: arr(10), arr2(10)
+ integer(kind=4) :: x, x2
+ character(len=32) :: w, w2
+ integer, dimension(:), allocatable :: y, y2
+
+ !$omp declare target (my_var)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target (my_var%t_i)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target (my_var%t_arr)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target (my_var%kind_param)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target (my_var%len_param)
+
+ !$omp declare target (arr)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target (arr(1))
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target (arr(1:2))
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target (x%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target (w%LEN)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target (y%KIND)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (my_var)
+
+ !$omp declare target enter (my_var)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (my_var) device_type(host)
+
+ !$omp declare target enter (my_var) device_type(host)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (my_var%t_i)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (my_var%t_i)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (my_var%t_arr)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (my_var%t_arr)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (my_var%kind_param)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (my_var%kind_param)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (my_var%len_param)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (my_var%len_param)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (arr)
+
+ !$omp declare target enter (arr)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (arr) device_type(nohost)
+
+ !$omp declare target enter (arr) device_type(nohost)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (arr(1))
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (arr(1))
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (arr(1:2))
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (arr(1:2))
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (x%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (x%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (w%LEN)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (w%LEN)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (y%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target enter (y%KIND)
+
+ !$omp declare target link (my_var2)
+
+ !$omp declare target link (my_var2) device_type(any)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (my_var2%t_i)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (my_var2%t_arr)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (my_var2%kind_param)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (my_var2%len_param)
+
+ !$omp declare target link (arr2)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (arr2(1))
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (arr2(1:2))
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (x2%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (w2%LEN)
+
+ !ERROR: A type parameter inquiry cannot appear on the DECLARE TARGET directive
+ !$omp declare target link (y2%KIND)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target02.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target02.f90
new file mode 100644
index 0000000000000..8166e10d702b8
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target02.f90
@@ -0,0 +1,206 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.14.7 Declare Target Directive
+
+program declare_target02
+ integer :: arr1(10), arr1_to(10), arr1_link(10)
+ common /blk1/ a1, a1_to, a1_link
+ real, save :: eq_a, eq_b, eq_c, eq_d
+
+
+ !$omp declare target (arr1)
+
+ !$omp declare target (blk1)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target (a1)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (arr1_to)
+
+ !$omp declare target enter (arr1_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (blk1_to)
+
+ !$omp declare target enter (blk1_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target to (a1_to)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target enter (a1_to)
+
+ !$omp declare target link (arr1_link)
+
+ !$omp declare target link (blk1_link)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target link (a1_link)
+
+ equivalence(eq_a, eq_b)
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target (eq_a)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target to (eq_a)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target enter (eq_a)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target link (eq_b)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target (eq_c)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target to (eq_c)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target enter (eq_c)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot appear in an EQUIVALENCE statement
+ !$omp declare target link (eq_d)
+ equivalence(eq_c, eq_d)
+
+contains
+ subroutine func()
+ integer :: arr2(10), arr2_to(10), arr2_link(10)
+ integer, save :: arr3(10), arr3_to(10), arr3_link(10)
+ common /blk2/ a2, a2_to, a2_link
+ common /blk3/ a3, a3_to, a3_link
+ save /blk3/
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target (arr2)
+
+ !$omp declare target (arr3)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target (a2)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target (a3)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target to (arr2_to)
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target enter (arr2_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (arr3_to)
+
+ !$omp declare target enter (arr3_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target to (a2_to)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target enter (a2_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target to (a3_to)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target enter (a3_to)
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target link (arr2_link)
+
+ !$omp declare target link (arr3_link)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target link (a2_link)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target link (a3_link)
+ end
+end
+
+module mod4
+ integer :: arr4(10), arr4_to(10), arr4_link(10)
+ common /blk4/ a4, a4_to, a4_link
+
+ !$omp declare target (arr4)
+
+ !$omp declare target (blk4)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target (a4)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (arr4_to)
+
+ !$omp declare target enter (arr4_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to (blk4_to)
+ !$omp declare target enter (blk4_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target to (a4_to)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target enter (a4_to)
+
+ !$omp declare target link (arr4_link)
+
+ !$omp declare target link (blk4_link)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target link (a4_link)
+end
+
+subroutine func5()
+ integer :: arr5(10), arr5_to(10), arr5_link(10)
+ common /blk5/ a5, a5_to, a5_link
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target (arr5)
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target (blk5)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target (a5)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target to (arr5_to)
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target enter (arr5_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target to (blk5_to)
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target enter (blk5_to)
+
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target to (a5_to)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target enter (a5_to)
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target link (arr5_link)
+
+ !ERROR: A variable that appears in a DECLARE TARGET directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp declare target link (blk5_link)
+
+ !ERROR: A variable in a DECLARE TARGET directive cannot be an element of a common block
+ !$omp declare target link (a5_link)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target03.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target03.f90
new file mode 100644
index 0000000000000..bb1ed90e390f3
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target03.f90
@@ -0,0 +1,22 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -pedantic
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.14.7 Declare Target Directive
+
+module mod1
+end
+
+subroutine bar
+ !$omp declare target (bar)
+end subroutine
+
+program main
+ use mod1
+
+ !ERROR: The module name or main program name cannot be in a DECLARE TARGET directive
+ !$omp declare target (mod1)
+
+ !PORTABILITY: Name 'main' declared in a main program should not have the same name as the main program
+ !ERROR: The module name or main program name cannot be in a DECLARE TARGET directive
+ !$omp declare target (main)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target04.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target04.f90
new file mode 100644
index 0000000000000..24f8b4abecd13
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target04.f90
@@ -0,0 +1,16 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.14.7 Declare Target Directive
+
+program main
+ integer, save :: x, y
+
+ !$omp threadprivate(x)
+
+ !ERROR: A THREADPRIVATE variable cannot appear in a DECLARE TARGET directive
+ !ERROR: A THREADPRIVATE variable cannot appear in a DECLARE TARGET directive
+ !$omp declare target (x, y)
+
+ !$omp threadprivate(y)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target05.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target05.f90
new file mode 100644
index 0000000000000..2334a8506b7e4
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target05.f90
@@ -0,0 +1,44 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.14.7 Declare Target Directive
+
+module mod0
+ integer :: mi
+
+contains
+ subroutine subm()
+ integer, save :: mmi
+
+ !ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp declare target (mi)
+ mi = 1
+ contains
+ subroutine subsubm()
+ !ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp declare target (mmi)
+ end
+ end
+end
+
+module mod1
+ integer :: mod_i
+end
+
+program main
+ use mod1
+ integer, save :: i
+ integer :: j
+
+ !ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp declare target (mod_i)
+
+contains
+ subroutine sub()
+ !ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp declare target (i, j)
+ i = 1
+ j = 1
+ end
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target06.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target06.f90
new file mode 100644
index 0000000000000..a1c55d39e1b68
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target06.f90
@@ -0,0 +1,28 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.14.7 Declare Target Directive
+! When used in an implicit none context.
+
+module test_0
+ implicit none
+!ERROR: The given DECLARE TARGET directive clause has an invalid argument
+!ERROR: No explicit type declared for 'no_implicit_materialization_1'
+!$omp declare target(no_implicit_materialization_1)
+
+!ERROR: The given DECLARE TARGET directive clause has an invalid argument
+!ERROR: No explicit type declared for 'no_implicit_materialization_2'
+!$omp declare target link(no_implicit_materialization_2)
+
+!ERROR: The given DECLARE TARGET directive clause has an invalid argument
+!WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+!ERROR: No explicit type declared for 'no_implicit_materialization_3'
+!$omp declare target to(no_implicit_materialization_3)
+
+!ERROR: The given DECLARE TARGET directive clause has an invalid argument
+!ERROR: No explicit type declared for 'no_implicit_materialization_3'
+!$omp declare target enter(no_implicit_materialization_3)
+
+INTEGER :: data_int = 10
+!$omp declare target(data_int)
+end module test_0
diff --git a/flang/test/SemanticsChecked/OpenMP/declare-target07.f90 b/flang/test/SemanticsChecked/OpenMP/declare-target07.f90
new file mode 100644
index 0000000000000..22b4a4bd081d7
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/declare-target07.f90
@@ -0,0 +1,49 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+module my_module
+ interface foo
+ subroutine foo_int(a)
+ integer :: a
+ end subroutine
+ subroutine foo_real(a)
+ real :: a
+ end subroutine
+ end interface
+contains
+ subroutine bar(N)
+ integer :: N
+ entry entry1(N)
+ end subroutine
+ subroutine foobar(N)
+ integer::N
+ !ERROR: The procedure 'entry1' in DECLARE TARGET construct cannot be an entry name.
+ !$omp declare target(bar, entry1)
+ call bar(N)
+ end subroutine
+end module
+
+module other_mod
+ abstract interface
+ integer function foo(a)
+ integer, intent(in) :: a
+ end function
+ end interface
+ procedure(foo), pointer :: procptr
+ !ERROR: The procedure 'procptr' in DECLARE TARGET construct cannot be a procedure pointer.
+ !$omp declare target(procptr)
+end module
+
+subroutine baz(x)
+ real, intent(inout) :: x
+ real :: res
+ stmtfunc(x) = 4.0 * (x**3)
+ !ERROR: The procedure 'stmtfunc' in DECLARE TARGET construct cannot be a statement function.
+ !$omp declare target (stmtfunc)
+ res = stmtfunc(x)
+end subroutine
+
+program main
+ use my_module
+ !ERROR: The procedure 'foo' in DECLARE TARGET construct cannot be a generic name.
+ !$omp declare target(foo)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/default-clause.f90 b/flang/test/SemanticsChecked/OpenMP/default-clause.f90
new file mode 100644
index 0000000000000..9cde77be2babe
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/default-clause.f90
@@ -0,0 +1,45 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s
+
+! Test symbols generated in block constructs in the
+! presence of `default(...)` clause
+
+program sample
+ !CHECK: a size=4 offset=20: ObjectEntity type: INTEGER(4)
+ !CHECK: k size=4 offset=16: ObjectEntity type: INTEGER(4)
+ !CHECK: w size=4 offset=12: ObjectEntity type: INTEGER(4)
+ !CHECK: x size=4 offset=0: ObjectEntity type: INTEGER(4)
+ !CHECK: y size=4 offset=4: ObjectEntity type: INTEGER(4)
+ !CHECK: z size=4 offset=8: ObjectEntity type: INTEGER(4)
+ integer x, y, z, w, k, a
+ !$omp parallel firstprivate(x) private(y) shared(w) default(private)
+ !CHECK: OtherConstruct scope: size=0 alignment=1
+ !CHECK: a (OmpPrivate): HostAssoc
+ !CHECK: k (OmpPrivate): HostAssoc
+ !CHECK: x (OmpFirstPrivate): HostAssoc
+ !CHECK: y (OmpPrivate): HostAssoc
+ !CHECK: z (OmpPrivate): HostAssoc
+ !$omp parallel default(private)
+ !CHECK: OtherConstruct scope: size=0 alignment=1
+ !CHECK: a (OmpPrivate): HostAssoc
+ !CHECK: x (OmpPrivate): HostAssoc
+ !CHECK: y (OmpPrivate): HostAssoc
+ y = 20
+ x = 10
+ !$omp parallel
+ !CHECK: OtherConstruct scope: size=0 alignment=1
+ a = 10
+ !$omp end parallel
+ !$omp end parallel
+
+ !$omp parallel default(firstprivate) shared(y) private(w)
+ !CHECK: OtherConstruct scope: size=0 alignment=1
+ !CHECK: k (OmpFirstPrivate): HostAssoc
+ !CHECK: w (OmpPrivate): HostAssoc
+ !CHECK: z (OmpFirstPrivate): HostAssoc
+ y = 30
+ w = 40
+ z = 50
+ k = 40
+ !$omp end parallel
+ !$omp end parallel
+end program sample
diff --git a/flang/test/SemanticsChecked/OpenMP/default-none.f90 b/flang/test/SemanticsChecked/OpenMP/default-none.f90
new file mode 100644
index 0000000000000..11ba878ea7794
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/default-none.f90
@@ -0,0 +1,49 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! Positive tests for default(none)
+subroutine sb2(x)
+ real :: x
+end subroutine
+
+subroutine sb1
+ integer :: i
+ real :: a(10), b(10), k
+ inc(x) = x + 1.0
+ abstract interface
+ function iface(a, b)
+ real, intent(in) :: a, b
+ real :: iface
+ end function
+ end interface
+ procedure(iface) :: compute
+ procedure(iface), pointer :: ptr => NULL()
+ ptr => fn2
+ !$omp parallel default(none) shared(a,b,k) private(i)
+ do i = 1, 10
+ b(i) = k + sin(a(i)) + inc(a(i)) + fn1(a(i)) + compute(a(i),k) + add(k, k)
+ call sb3(b(i))
+ call sb2(a(i))
+ end do
+ !$omp end parallel
+contains
+ function fn1(x)
+ real :: x, fn1
+ fn1 = x
+ end function
+ function fn2(x, y)
+ real, intent(in) :: x, y
+ real :: fn2
+ fn2 = x + y
+ end function
+ subroutine sb3(x)
+ real :: x
+ print *, x
+ end subroutine
+end subroutine
+
+!construct-name inside default(none)
+subroutine sb4
+ !$omp parallel default(none)
+ loop: do i = 1, 10
+ end do loop
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/default.f90 b/flang/test/SemanticsChecked/OpenMP/default.f90
new file mode 100644
index 0000000000000..94de7fa468692
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/default.f90
@@ -0,0 +1,34 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.1 default Clause
+program omp_default
+ integer :: a(10), b(10), c(10),i,k
+ !ERROR: At most one DEFAULT clause can appear on the PARALLEL directive
+ !$omp parallel default(shared), default(private)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ end do
+ !$omp end parallel
+
+ !ERROR: At most one DEFAULT clause can appear on the TASK directive
+ !$omp task default(shared), default(none), shared(a,b,c,k,i)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ end do
+ !$omp end task
+
+ !ERROR: At most one DEFAULT clause can appear on the TASKLOOP directive
+ !$omp taskloop default(shared), default(private)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ end do
+ !$omp end taskloop
+
+ !ERROR: At most one DEFAULT clause can appear on the TEAMS directive
+ !$omp teams default(shared), default(none), shared(i,a,b,k,c)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ end do
+ !$omp end teams
+
+end program omp_default
diff --git a/flang/test/SemanticsChecked/OpenMP/default02.f90 b/flang/test/SemanticsChecked/OpenMP/default02.f90
new file mode 100644
index 0000000000000..23f994bcc3920
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/default02.f90
@@ -0,0 +1,57 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.1 default Clause - a positive test case.
+
+!DEF: /omp_default MainProgram
+program omp_default
+ !DEF: /omp_default/a ObjectEntity INTEGER(4)
+ !DEF: /omp_default/b ObjectEntity INTEGER(4)
+ !DEF: /omp_default/c ObjectEntity INTEGER(4)
+ !DEF: /omp_default/i ObjectEntity INTEGER(4)
+ !DEF: /omp_default/k ObjectEntity INTEGER(4)
+ integer a(10), b(10), c(10), i, k
+!$omp parallel default(shared)
+ !DEF: /omp_default/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_default/c
+ !REF: /omp_default/Block1/i
+ !REF: /omp_default/a
+ !REF: /omp_default/b
+ !REF: /omp_default/k
+ c(i) = a(i)+b(i)+k
+ end do
+!$omp end parallel
+!$omp task default(shared)
+ !DEF: /omp_default/Block2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_default/c
+ !REF: /omp_default/Block2/i
+ !REF: /omp_default/a
+ !REF: /omp_default/b
+ !REF: /omp_default/k
+ c(i) = a(i)+b(i)+k
+ end do
+!$omp end task
+!$omp taskloop default(shared)
+ !DEF: /omp_default/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_default/c
+ !REF: /omp_default/Block3/i
+ !REF: /omp_default/a
+ !REF: /omp_default/b
+ !REF: /omp_default/k
+ c(i) = a(i)+b(i)+k
+ end do
+!$omp end taskloop
+!$omp teams default(shared)
+ !REF: /omp_default/i
+ do i=1,10
+ !REF: /omp_default/c
+ !REF: /omp_default/i
+ !REF: /omp_default/a
+ !REF: /omp_default/b
+ !REF: /omp_default/k
+ c(i) = a(i)+b(i)+k
+ end do
+!$omp end teams
+end program omp_default
diff --git a/flang/test/SemanticsChecked/OpenMP/depend01.f90 b/flang/test/SemanticsChecked/OpenMP/depend01.f90
new file mode 100644
index 0000000000000..29468f4358855
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/depend01.f90
@@ -0,0 +1,28 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.13.9 Depend Clause
+! List items used in depend clauses cannot be zero-length array sections.
+
+program omp_depend
+ integer :: a(10) , b(10,10)
+ a = 10
+ b = 20
+
+ !$omp parallel
+ !$omp single
+
+ !ERROR: 'a' in DEPEND clause is a zero size array section
+ !ERROR: 'b' in DEPEND clause is a zero size array section
+ !$omp task shared(a,b) depend(out: a(2:1), b(3:1, 1:-1))
+ a(2:1) = b(2, 2)
+ !$omp end task
+
+ !ERROR: Stride should not be specified for array section in DEPEND clause
+ !$omp task shared(x) depend(in: a(5:10:1))
+ print *, a(5:10), b
+ !$omp end task
+
+ !$omp end single
+ !$omp end parallel
+
+end program omp_depend
diff --git a/flang/test/SemanticsChecked/OpenMP/depend02.f90 b/flang/test/SemanticsChecked/OpenMP/depend02.f90
new file mode 100644
index 0000000000000..76c02c8f9cbab
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/depend02.f90
@@ -0,0 +1,49 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.13.9 Depend Clause
+! A variable that is part of another variable
+! (such as an element of a structure) but is not an array element or
+! an array section cannot appear in a DEPEND clause
+
+subroutine vec_mult(N)
+ implicit none
+ integer :: i, N
+ real, allocatable :: p(:), v1(:), v2(:)
+
+ type my_type
+ integer :: a(10)
+ end type my_type
+
+ type(my_type) :: my_var
+ allocate( p(N), v1(N), v2(N) )
+
+ !$omp parallel num_threads(2)
+ !$omp single
+
+ !$omp task depend(out:v1)
+ call init(v1, N)
+ !$omp end task
+
+ !$omp task depend(out:v2)
+ call init(v2, N)
+ !$omp end task
+
+ !ERROR: A variable that is part of another variable (such as an element of a structure) but is not an array element or an array section cannot appear in a DEPEND clause
+ !$omp target nowait depend(in:v1,v2, my_var%a) depend(out:p) &
+ !$omp& map(to:v1,v2) map(from: p)
+ !$omp parallel do
+ do i=1,N
+ p(i) = v1(i) * v2(i)
+ end do
+ !$omp end target
+
+ !$omp task depend(in:p)
+ call output(p, N)
+ !$omp end task
+
+ !$omp end single
+ !$omp end parallel
+
+ deallocate( p, v1, v2 )
+
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/depend03.f90 b/flang/test/SemanticsChecked/OpenMP/depend03.f90
new file mode 100644
index 0000000000000..e0eb683d252ef
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/depend03.f90
@@ -0,0 +1,24 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.13.9 Depend Clause
+! Coarrays are not supported in depend clause
+
+program omp_depend_coarray
+ integer :: a(3)[*], b(3) , k
+
+ a(:) = this_image()
+ b(:) = a(:)[1]
+ k = 10
+
+ !$omp parallel
+ !$omp single
+ !ERROR: Coarrays are not supported in DEPEND clause
+ !$omp task shared(b) depend(out: a(:)[1])
+ b = a + k
+ !$omp end task
+ !$omp end single
+ !$omp end parallel
+
+ print *, a, b
+
+end program omp_depend_coarray
diff --git a/flang/test/SemanticsChecked/OpenMP/device-clause01.f90 b/flang/test/SemanticsChecked/OpenMP/device-clause01.f90
new file mode 100644
index 0000000000000..6f95d162790d5
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/device-clause01.f90
@@ -0,0 +1,31 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.2
+! 13.2 Device clause
+
+subroutine foo
+
+ integer :: a
+
+ !$omp target device(ancestor:0)
+ !$omp end target
+ !$omp target device(device_num:0)
+ !$omp end target
+
+ !ERROR: The ANCESTOR device-modifier must not appear on the DEVICE clause on any directive other than the TARGET construct. Found on TARGET DATA construct.
+ !$omp target data device(ancestor:0) map(tofrom:a)
+ !$omp end target data
+ !$omp target data device(device_num:0) map(tofrom:a)
+ !$omp end target data
+
+
+ !ERROR: The ANCESTOR device-modifier must not appear on the DEVICE clause on any directive other than the TARGET construct. Found on TARGET ENTER DATA construct.
+ !$omp target enter data device(ancestor:0) map(to:a)
+ !$omp target exit data map(from:a)
+ !$omp target enter data device(device_num:0) map(to:a)
+ !$omp target exit data map(from:a)
+
+ !ERROR: The ANCESTOR device-modifier must not appear on the DEVICE clause on any directive other than the TARGET construct. Found on TARGET UPDATE construct.
+ !$omp target update device(ancestor:0) to(a)
+ !$omp target update device(device_num:0) to(a)
+
+end subroutine foo
diff --git a/flang/test/SemanticsChecked/OpenMP/device-constructs.f90 b/flang/test/SemanticsChecked/OpenMP/device-constructs.f90
new file mode 100644
index 0000000000000..1ac00ef922c6b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/device-constructs.f90
@@ -0,0 +1,271 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! Check OpenMP clause validity for the following directives:
+! 2.10 Device constructs
+program main
+ use iso_c_binding
+
+ real(8) :: arrayA(256), arrayB(256)
+ integer :: N
+ type(c_ptr) :: cptr
+
+ arrayA = 1.414
+ arrayB = 3.14
+ N = 256
+
+ !$omp target map(arrayA)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !$omp target device(0)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET directive
+ !$omp target device(0) device(1)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !ERROR: SCHEDULE clause is not allowed on the TARGET directive
+ !$omp target schedule(static)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !$omp target defaultmap(tofrom:scalar)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !ERROR: The argument TOFROM:SCALAR must be specified on the DEFAULTMAP clause
+ !$omp target defaultmap(tofrom)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !ERROR: At most one DEFAULTMAP clause can appear on the TARGET directive
+ !$omp target defaultmap(tofrom:scalar) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !$omp target thread_limit(4)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TARGET directive
+ !$omp target thread_limit(4) thread_limit(8)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !$omp teams num_teams(3) thread_limit(10) default(shared) private(i) shared(a)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end teams
+
+ !ERROR: At most one NUM_TEAMS clause can appear on the TEAMS directive
+ !$omp teams num_teams(2) num_teams(3)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end teams
+
+ !ERROR: The parameter of the NUM_TEAMS clause must be a positive integer expression
+ !$omp teams num_teams(-1)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end teams
+
+ !ERROR: At most one THREAD_LIMIT clause can appear on the TEAMS directive
+ !$omp teams thread_limit(2) thread_limit(3)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end teams
+
+ !ERROR: The parameter of the THREAD_LIMIT clause must be a positive integer expression
+ !$omp teams thread_limit(-1)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end teams
+
+ !ERROR: At most one DEFAULT clause can appear on the TEAMS directive
+ !$omp teams default(shared) default(private)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end teams
+
+ !$omp target teams num_teams(2) defaultmap(tofrom:scalar)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target teams
+
+ !$omp target map(tofrom:a)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !ERROR: Only the TO, FROM, TOFROM, ALLOC map types are permitted for MAP clauses on the TARGET directive
+ !$omp target map(delete:a)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !$omp target data device(0) map(to:a)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target data
+
+ !$omp target data device(0) use_device_addr(cptr)
+ cptr = c_null_ptr
+ !$omp end target data
+
+ !$omp target data device(0) use_device_addr(cptr)
+ cptr = c_null_ptr
+ !$omp end target data
+
+ !ERROR: At least one of MAP, USE_DEVICE_ADDR, USE_DEVICE_PTR clause must appear on the TARGET DATA directive
+ !$omp target data device(0)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end target data
+
+ !ERROR: The device expression of the DEVICE clause must be a positive integer expression
+ !$omp target enter data map(alloc:A) device(-2)
+
+ !ERROR: The device expression of the DEVICE clause must be a positive integer expression
+ !$omp target exit data map(delete:A) device(-2)
+
+ !ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive
+ !$omp target enter data map(to:a) if(.true.) if(.false.)
+
+ !ERROR: Only the TO, ALLOC map types are permitted for MAP clauses on the TARGET ENTER DATA directive
+ !$omp target enter data map(from:a)
+
+ !$omp target exit data map(delete:a)
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET EXIT DATA directive
+ !$omp target exit data map(from:a) device(0) device(1)
+
+ !ERROR: Only the FROM, RELEASE, DELETE map types are permitted for MAP clauses on the TARGET EXIT DATA directive
+ !$omp target exit data map(to:a)
+
+ !$omp target update if(.true.) device(1) to(a) from(b) depend(inout:c) nowait
+
+ !ERROR: At most one IF clause can appear on the TARGET UPDATE directive
+ !$omp target update to(a) if(.true.) if(.false.)
+
+ !ERROR: At most one DEVICE clause can appear on the TARGET UPDATE directive
+ !$omp target update device(0) device(1) from(b)
+
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end target
+
+ !$omp target
+ !$omp teams
+ !$omp distribute
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !ERROR: At most one COLLAPSE clause can appear on the DISTRIBUTE directive
+ !$omp distribute collapse(2) collapse(3)
+ do i = 1, N
+ do j = 1, N
+ do k = 1, N
+ a = 3.14
+ enddo
+ enddo
+ enddo
+ !$omp end distribute
+ !$omp end target
+
+ !$omp target
+ !$omp teams
+ !ERROR: At most one COLLAPSE clause can appear on the DISTRIBUTE directive
+ !$omp distribute collapse(2) collapse(3)
+ do i = 1, N
+ do j = 1, N
+ do k = 1, N
+ a = 3.14
+ enddo
+ enddo
+ enddo
+ !$omp end distribute
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute dist_schedule(static, 2)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end target
+
+ !$omp target
+ !$omp teams
+ !$omp distribute dist_schedule(static, 2)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !ERROR: At most one DIST_SCHEDULE clause can appear on the DISTRIBUTE directive
+ !$omp distribute dist_schedule(static, 2) dist_schedule(static, 3)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end target
+
+ !$omp target
+ !$omp teams
+ !ERROR: At most one DIST_SCHEDULE clause can appear on the DISTRIBUTE directive
+ !$omp distribute dist_schedule(static, 2) dist_schedule(static, 3)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end teams
+ !$omp end target
+
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/do-collapse-positivecases.f90 b/flang/test/SemanticsChecked/OpenMP/do-collapse-positivecases.f90
new file mode 100644
index 0000000000000..6ad14fa01bca0
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-collapse-positivecases.f90
@@ -0,0 +1,36 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Collapse Clause Positive cases
+
+!DEF: /omp_docollapse MainProgram
+program omp_docollapse
+ !DEF: /omp_docollapse/i ObjectEntity INTEGER(4)
+ !DEF: /omp_docollapse/j ObjectEntity INTEGER(4)
+ !DEF: /omp_docollapse/k ObjectEntity INTEGER(4)
+ integer i, j, k
+ !$omp do collapse(2)
+ !DEF: /omp_docollapse/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=1,10
+ !REF: /omp_docollapse/k
+ do k=1,10
+ print *, "hello"
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !REF: /omp_docollapse/i
+ do i=1,10
+ !$omp do collapse(2)
+ !DEF: /omp_docollapse/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=1,10
+ !DEF: /omp_docollapse/Block1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do k=1,10
+ print *, "hello"
+ end do
+ end do
+ !$omp end do
+ end do
+end program omp_docollapse
diff --git a/flang/test/SemanticsChecked/OpenMP/do-collapse.f90 b/flang/test/SemanticsChecked/OpenMP/do-collapse.f90
new file mode 100644
index 0000000000000..145b7b75d28df
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-collapse.f90
@@ -0,0 +1,33 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Collapse Clause
+program omp_doCollapse
+ integer:: i,j
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 1,10
+ do j = 1, 10
+ print *, "hello"
+ end do
+ end do
+ !$omp end do
+
+ do i = 1,10
+ do j = 1, 10
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(2)
+ do k = 1, 10
+ print *, "hello"
+ end do
+ !$omp end do
+ end do
+ end do
+
+ !$omp parallel do collapse(2)
+ do i = 1, 3
+ !ERROR: Loop control is not present in the DO LOOP
+ do
+ end do
+ end do
+end program omp_doCollapse
+
diff --git a/flang/test/SemanticsChecked/OpenMP/do-cycle.f90 b/flang/test/SemanticsChecked/OpenMP/do-cycle.f90
new file mode 100644
index 0000000000000..b6617acb0794a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-cycle.f90
@@ -0,0 +1,44 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! Check for cycle statements leaving an OpenMP structured block
+
+program omp_do
+ integer i, j, k
+
+ !$omp parallel
+ foo: do i = 0, 10
+ !$omp do
+ bar: do j = 0, 10
+ !ERROR: CYCLE to construct 'foo' outside of DO construct is not allowed
+ cycle foo
+ end do bar
+ !$omp end do
+ end do foo
+ !$omp end parallel
+
+ foo1: do i = 0, 10
+ !$omp parallel
+ foo2: do k = 0, 10
+ !$omp do
+ foo3: do j = 0, 10
+ !ERROR: CYCLE to construct 'foo1' outside of PARALLEL construct is not allowed
+ !ERROR: CYCLE to construct 'foo1' outside of DO construct is not allowed
+ cycle foo1
+ end do foo3
+ !$omp end do
+ end do foo2
+ !$omp end parallel
+ end do foo1
+
+ bar1: do i = 0, 10
+ !$omp parallel
+ bar2: do k = 0, 10
+ bar3: do j = 0, 10
+ !ERROR: CYCLE to construct 'bar1' outside of PARALLEL construct is not allowed
+ cycle bar1
+ end do bar3
+ end do bar2
+ !$omp end parallel
+ end do bar1
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do-ordered-positivecases.f90 b/flang/test/SemanticsChecked/OpenMP/do-ordered-positivecases.f90
new file mode 100644
index 0000000000000..d4c4e5b1bf2f4
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-ordered-positivecases.f90
@@ -0,0 +1,67 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Ordered Clause positive cases.
+
+!DEF: /omp_doordered MainProgram
+program omp_doordered
+ !DEF: /omp_doordered/i ObjectEntity INTEGER(4)
+ !DEF: /omp_doordered/j ObjectEntity INTEGER(4)
+ integer i, j
+ !$omp do ordered(2)
+ !DEF: /omp_doordered/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_doordered/Block1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=1,10
+ print *, "hello"
+ end do
+ end do
+ !$omp end do
+
+ !REF: /omp_doordered/i
+ do i=1,10
+ !REF: /omp_doordered/j
+ do j=1,10
+ !$omp do ordered(1)
+ !DEF: /omp_doordered/Block2/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do k=1,10
+ print *, "hello"
+ end do
+ !$omp end do
+ end do
+ end do
+
+ !$omp do ordered
+ !DEF: /omp_doordered/Block3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !$omp ordered
+ !REF: /omp_doordered/j
+ do j=1,10
+ print *, "hello"
+ end do
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp do collapse(1) ordered(2)
+ !DEF: /omp_doordered/Block4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_doordered/Block4/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=1,10
+ print *, "hello"
+ end do
+ end do
+ !$omp end do
+
+ !$omp parallel num_threads(4)
+ !$omp do ordered collapse(1)
+ !DEF: /omp_doordered/Block5/Block1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !$omp ordered
+ !DEF: /omp_doordered/Block5/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=1,10
+ print *, "hello"
+ end do
+ !$omp end ordered
+ end do
+ !$omp end parallel
+end program omp_doordered
diff --git a/flang/test/SemanticsChecked/OpenMP/do-ordered.f90 b/flang/test/SemanticsChecked/OpenMP/do-ordered.f90
new file mode 100644
index 0000000000000..79ded3e1b6fe6
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-ordered.f90
@@ -0,0 +1,60 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Ordered Clause
+
+program omp_doOrdered
+ integer:: i,j
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do ordered(3)
+ do i = 1,10
+ do j = 1, 10
+ print *, "hello"
+ end do
+ end do
+ !$omp end do
+
+ do i = 1,10
+ do j = 1, 10
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do ordered(2)
+ do k = 1, 10
+ print *, "hello"
+ end do
+ !$omp end do
+ end do
+ end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do ordered(2)
+ do i = 1,10
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ do j = 1, 10
+ print *, "hello"
+ end do
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(1) ordered(3)
+ do i = 1,10
+ do j = 1, 10
+ print *, "hello"
+ end do
+ end do
+ !$omp end do
+
+ !$omp parallel num_threads(4)
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do ordered(2) collapse(1)
+ do i = 1,10
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ do j = 1, 10
+ print *, "hello"
+ end do
+ !$omp end ordered
+ end do
+ !$omp end parallel
+end program omp_doOrdered
diff --git a/flang/test/SemanticsChecked/OpenMP/do-schedule01.f90 b/flang/test/SemanticsChecked/OpenMP/do-schedule01.f90
new file mode 100644
index 0000000000000..1e0a8a613135c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-schedule01.f90
@@ -0,0 +1,13 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Schedule Clause
+program omp_doSchedule
+ integer :: i,n
+ real :: a(100), y(100), z(100)
+ !ERROR: The chunk size of the SCHEDULE clause must be a positive integer expression
+ !$omp do schedule(static, -1)
+ do i=2,n+1
+ y(i) = z(i-1) + a(i)
+ end do
+ !$omp end do
+end program omp_doSchedule
diff --git a/flang/test/SemanticsChecked/OpenMP/do-schedule02.f90 b/flang/test/SemanticsChecked/OpenMP/do-schedule02.f90
new file mode 100644
index 0000000000000..a7cbdc24e83a2
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-schedule02.f90
@@ -0,0 +1,15 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Schedule Clause
+program omp_doSchedule
+ integer :: i,n
+ real :: a(100), y(100), z(100)
+ integer,parameter :: b = 10
+ integer,parameter :: c = 11
+ !ERROR: The chunk size of the SCHEDULE clause must be a positive integer expression
+ !$omp do schedule(static,b-c)
+ do i=2,n+1
+ y(i) = z(i-1) + a(i)
+ end do
+ !$omp end do
+end program omp_doSchedule
diff --git a/flang/test/SemanticsChecked/OpenMP/do-schedule03.f90 b/flang/test/SemanticsChecked/OpenMP/do-schedule03.f90
new file mode 100644
index 0000000000000..8787b094d581a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-schedule03.f90
@@ -0,0 +1,28 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Schedule Clause
+! Test that does not catch non constant integer expressions like xx - xx.
+ !DEF: /ompdoschedule MainProgram
+program ompdoschedule
+ !DEF: /ompdoschedule/a ObjectEntity REAL(4)
+ !DEF: /ompdoschedule/y ObjectEntity REAL(4)
+ !DEF: /ompdoschedule/z ObjectEntity REAL(4)
+ real a(100),y(100),z(100)
+ !DEF: /ompdoschedule/b ObjectEntity INTEGER(4)
+ !DEF: /ompdoschedule/i ObjectEntity INTEGER(4)
+ !DEF: /ompdoschedule/n ObjectEntity INTEGER(4)
+ integer b,i,n
+ !REF: /ompdoschedule/b
+ b = 10
+ !$omp do schedule(static,b-b)
+ !DEF: /ompdoschedule/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ !REF: /ompdoschedule/n
+ do i = 2,n+1
+ !REF: /ompdoschedule/y
+ !REF: /ompdoschedule/OtherConstruct1/i
+ !REF: /ompdoschedule/z
+ !REF: /ompdoschedule/a
+ y(i) = z(i-1) + a(i)
+ end do
+ !$omp end do
+end program ompdoschedule
diff --git a/flang/test/SemanticsChecked/OpenMP/do-schedule04.f90 b/flang/test/SemanticsChecked/OpenMP/do-schedule04.f90
new file mode 100644
index 0000000000000..0d1e189593eac
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do-schedule04.f90
@@ -0,0 +1,32 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Schedule Clause
+! Test that does not catch non constant integer expressions like xx - yy.
+
+ !DEF: /tds (Subroutine) Subprogram
+subroutine tds
+ implicit none
+ !DEF: /tds/a ObjectEntity REAL(4)
+ !DEF: /tds/y ObjectEntity REAL(4)
+ !DEF: /tds/z ObjectEntity REAL(4)
+ real a(100),y(100),z(100)
+ !DEF: /tds/i ObjectEntity INTEGER(4)
+ !DEF: /tds/j ObjectEntity INTEGER(4)
+ !DEF: /tds/k ObjectEntity INTEGER(4)
+ integer i,j,k
+
+ !REF: /tds/j
+ j = 11
+ !REF: /tds/k
+ k = 12
+ !$omp do schedule(static,j-k)
+ !DEF: /tds/OtherConstruct1/i (OmpPrivate,OmpPreDetermined) HostAssoc INTEGER(4)
+ do i = 1,10
+ !REF: /tds/y
+ !REF: /tds/OtherConstruct1/i
+ !REF: /tds/z
+ !REF: /tds/a
+ y(i) = z(i-1)+a(i)
+ end do
+ !$omp end do
+end subroutine tds
diff --git a/flang/test/SemanticsChecked/OpenMP/do01-positivecase.f90 b/flang/test/SemanticsChecked/OpenMP/do01-positivecase.f90
new file mode 100644
index 0000000000000..905fdbaf18476
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do01-positivecase.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! The loop iteration variable may not appear in a firstprivate directive.
+! A positive case
+
+!DEF: /omp_do MainProgram
+program omp_do
+ !DEF: /omp_do/i ObjectEntity INTEGER(4)
+ integer i
+
+ !$omp do firstprivate(k)
+ !DEF: /omp_do/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ print *, "Hello"
+ end do
+ !$omp end do
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do01.f90 b/flang/test/SemanticsChecked/OpenMP/do01.f90
new file mode 100644
index 0000000000000..78c3ba38bc873
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do01.f90
@@ -0,0 +1,18 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! The loop iteration variable may not appear in a firstprivate directive.
+
+program omp_do
+ integer i, j, k
+
+ !ERROR: DO iteration variable i is not allowed in FIRSTPRIVATE clause.
+ !$omp do firstprivate(k,i)
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ end do
+ end do
+ !$omp end do
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do02.f90 b/flang/test/SemanticsChecked/OpenMP/do02.f90
new file mode 100644
index 0000000000000..9749991e4f96b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do02.f90
@@ -0,0 +1,21 @@
+! RUN: %S/test_errors.sh %s %t %flang -fopenmp
+! XFAIL: *
+
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! Exit statement terminating !$OMP DO loop
+
+program omp_do
+ integer i, j, k
+
+ !$omp do
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ end do
+ !ERROR: EXIT statement terminating !$OMP DO loop
+ exit
+ end do
+ !$omp end do
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do03.f90 b/flang/test/SemanticsChecked/OpenMP/do03.f90
new file mode 100644
index 0000000000000..7ec84a0a34245
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do03.f90
@@ -0,0 +1,25 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! Semantic error for correct test case
+
+program omp_do
+ integer i, j, k
+ integer :: a(10), b(10)
+ a = 10
+ j = 0
+
+ !$omp parallel
+ !$omp do linear(j:1)
+ do i = 1, 10
+ j = j + 1
+ b(i) = a(i) * 2.0
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ print *, j
+ print *, b
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do04-positivecase.f90 b/flang/test/SemanticsChecked/OpenMP/do04-positivecase.f90
new file mode 100644
index 0000000000000..eb2d67bb8ceb2
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do04-positivecase.f90
@@ -0,0 +1,22 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Do Loop Constructs
+
+!DEF: /omp_do1 MainProgram
+program omp_do1
+ !DEF: /omp_do1/i ObjectEntity INTEGER(4)
+ !DEF: /omp_do1/j ObjectEntity INTEGER(4)
+ !DEF: /omp_do1/k (OmpThreadprivate) ObjectEntity INTEGER(4)
+ !DEF: /omp_do1/n (OmpThreadprivate) ObjectEntity INTEGER(4)
+ integer i, j, k, n
+ !$omp threadprivate (k,n)
+ !$omp do
+ !DEF: /omp_do1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_do1/j
+ do j=1,10
+ print *, "Hello"
+ end do
+ end do
+ !$omp end do
+end program omp_do1
diff --git a/flang/test/SemanticsChecked/OpenMP/do04.f90 b/flang/test/SemanticsChecked/OpenMP/do04.f90
new file mode 100644
index 0000000000000..6690f4927f6a9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do04.f90
@@ -0,0 +1,104 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! The loop iteration variable may not appear in a threadprivate directive.
+
+
+subroutine omp_do
+ integer, save:: i, j, k,n
+ !$omp threadprivate(k,j,i)
+ !$omp do collapse(2)
+ !ERROR: Loop iteration variable i is not allowed in THREADPRIVATE.
+ do i = 1, 10
+ !ERROR: Loop iteration variable j is not allowed in THREADPRIVATE.
+ do j = 1, 10
+ print *, "Hello"
+ end do
+ end do
+ !$omp end do
+end subroutine omp_do
+
+subroutine omp_do1
+ integer, save :: i, j, k
+ !$omp threadprivate(k,j,i)
+ !$omp do
+ !ERROR: Loop iteration variable i is not allowed in THREADPRIVATE.
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ end do
+ end do
+ !$omp end do
+
+end subroutine omp_do1
+
+subroutine omp_do2
+ integer, save :: k, j
+ !$omp threadprivate(k)
+ !$omp threadprivate(j)
+ call compute()
+ contains
+ subroutine compute()
+ !$omp do ordered(1) collapse(1)
+ !ERROR: Loop iteration variable k is not allowed in THREADPRIVATE.
+ foo: do k = 1, 10
+ do i = 1, 10
+ print *, "Hello"
+ end do
+ end do foo
+ !$omp end do
+ end subroutine
+
+end subroutine omp_do2
+
+subroutine omp_do3
+ integer, save :: i
+ !$omp threadprivate(i)
+ !$omp parallel
+ print *, "parallel"
+ !$omp end parallel
+ !$omp do
+ !ERROR: Loop iteration variable i is not allowed in THREADPRIVATE.
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ end do
+ end do
+ !$omp end do
+
+end subroutine omp_do3
+
+module tp
+ !integer i,j
+ integer, save:: i, j, k,n
+ !$omp threadprivate(i)
+ !$omp threadprivate(j)
+end module tp
+
+module usetp
+ use tp
+end module usetp
+
+subroutine main
+ use usetp
+ !$omp do
+ !ERROR: Loop iteration variable i is not allowed in THREADPRIVATE.
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ end do
+ end do
+ !$omp end do
+end subroutine
+
+subroutine main1
+ use tp
+ !$omp do
+ !ERROR: Loop iteration variable j is not allowed in THREADPRIVATE.
+ do j = 1, 10
+ do i = 1, 10
+ print *, "Hello"
+ end do
+ end do
+ !$omp end do
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/do05-positivecase.f90 b/flang/test/SemanticsChecked/OpenMP/do05-positivecase.f90
new file mode 100644
index 0000000000000..4e02235f58a1a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do05-positivecase.f90
@@ -0,0 +1,45 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct restrictions on single directive.
+! A positive case
+
+!DEF: /omp_do MainProgram
+program omp_do
+ !DEF: /omp_do/i ObjectEntity INTEGER(4)
+ !DEF: /omp_do/n ObjectEntity INTEGER(4)
+ integer i,n
+ !$omp parallel
+ !DEF: /omp_do/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !$omp single
+ print *, "hello"
+ !$omp end single
+ end do
+ !$omp end parallel
+
+ !$omp parallel default(shared)
+ !$omp do
+ !DEF: /omp_do/OtherConstruct2/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ !REF: /omp_do/n
+ do i=1,n
+ !$omp parallel
+ !$omp single
+ !DEF: /work EXTERNAL (Subroutine) ProcEntity
+ !REF: /omp_do/OtherConstruct2/OtherConstruct1/i
+ call work(i, 1)
+ !$omp end single
+ !$omp end parallel
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp parallel private(i)
+ !DEF: /omp_do/OtherConstruct3/i (OmpPrivate) HostAssoc INTEGER(4)
+ do i=1,10
+ !$omp single
+ print *, "hello"
+ !$omp end single
+ end do
+ !$omp end parallel
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do05.f90 b/flang/test/SemanticsChecked/OpenMP/do05.f90
new file mode 100644
index 0000000000000..c0f240db57b65
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do05.f90
@@ -0,0 +1,214 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct restrictions on single directive.
+
+
+program omp_do
+
+ integer n
+ integer i,j,k
+ !$omp do
+ do i=1,10
+ if( i == 5 ) then
+ cycle
+ end if
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end do
+
+ !$omp parallel do
+ do i=1,10
+ if( i == 9 ) then
+ end if
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do simd
+ do i=1,10
+ if( i == 5 ) then
+ cycle
+ end if
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end parallel do simd
+
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute parallel do
+ do i=1,10
+ if( i == 3 ) then
+ cycle
+ end if
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end distribute parallel do
+
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute parallel do simd
+ do i=1,10
+ if( i == 3 ) then
+ cycle
+ end if
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end distribute parallel do simd
+
+ !$omp target parallel do
+ do i=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end target parallel do
+
+ !$omp target parallel do simd
+ do i=1,10
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end target parallel do simd
+
+ !$omp target teams distribute parallel do
+ do i=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do simd
+ do i=1,10
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end target teams distribute parallel do simd
+
+ !$omp do
+ do i=1,10
+ !$omp task
+ do j=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end task
+ end do
+ !$omp end do
+
+ !$omp do
+ do i=1,10
+ !$omp parallel
+ do j=1,10
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end parallel
+ end do
+ !$omp end do
+
+!$omp do
+do i=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do j=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+ end do
+ !$omp end single
+
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end single
+
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do
+ do k=1,10
+ print *,"hello"
+ end do
+ !$omp end do
+end do
+!$omp end do
+
+ !$omp parallel default(shared)
+ !$omp do
+ do i = 1, n
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ call work(i, 1)
+ !$omp end single
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp parallel default(shared)
+ !$omp do
+ do i = 1, n
+ !$omp task
+ do j=1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ call work(i, 1)
+ !$omp end single
+ end do
+ !$omp end task
+ end do
+ !$omp end do
+ !$omp end parallel
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do06-positivecases.f90 b/flang/test/SemanticsChecked/OpenMP/do06-positivecases.f90
new file mode 100644
index 0000000000000..2713b55fa2ecb
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do06-positivecases.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! The ordered clause must be present on the loop construct if any ordered
+! region ever binds to a loop region arising from the loop construct.
+
+! A positive case
+!DEF: /omp_do MainProgram
+program omp_do
+ !DEF: /omp_do/i ObjectEntity INTEGER(4)
+ !DEF: /omp_do/j ObjectEntity INTEGER(4)
+ !DEF: /omp_do/k ObjectEntity INTEGER(4)
+ integer i, j, k
+ !$omp do ordered
+ !DEF: /omp_do/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !$omp ordered
+ !DEF: /my_func EXTERNAL (Subroutine) ProcEntity
+ call my_func
+ !$omp end ordered
+ end do
+ !$omp end do
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do06.f90 b/flang/test/SemanticsChecked/OpenMP/do06.f90
new file mode 100644
index 0000000000000..86790c2930e24
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do06.f90
@@ -0,0 +1,33 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! The ordered clause must be present on the loop construct if any ordered
+! region ever binds to a loop region arising from the loop construct.
+
+program omp_do
+ integer i, j, k
+
+ !$omp do
+ do i = 1, 10
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ call my_func()
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp do ordered private(i)
+ do i = 1, 10
+ !$omp parallel do
+ do j = 1, 10
+ print *,i
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ print *,i
+ !$omp end ordered
+ end do
+ !$omp end parallel do
+ end do
+ !$omp end do
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do07.f90 b/flang/test/SemanticsChecked/OpenMP/do07.f90
new file mode 100644
index 0000000000000..44fe5f86045ac
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do07.f90
@@ -0,0 +1,24 @@
+! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s
+! REQUIRES: shell
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! No statement in the associated loops other than the DO statements
+! can cause a branch out of the loops
+
+program omp_do
+ integer i, j, k
+
+ !$omp do
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ !CHECK: invalid branch leaving an OpenMP structured block
+ goto 10
+ end do
+ end do
+ !$omp end do
+
+ !CHECK: Outside the enclosing DO directive
+ 10 stop
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do08.f90 b/flang/test/SemanticsChecked/OpenMP/do08.f90
new file mode 100644
index 0000000000000..5143dff0dd315
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do08.f90
@@ -0,0 +1,169 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+
+program omp
+ integer i, j, k
+ logical cond(10,10,10)
+ cond = .false.
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (i .lt. 1) cycle
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (i .lt. 1) cycle
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(2)
+ do i = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (i .lt. 1) cycle
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (i .lt. 1) cycle foo
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do foo
+ !$omp end do
+
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do 60 i=2,200,2
+ do j=1,10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if(i==100) cycle
+ do k=1,10
+ print *,i
+ end do
+ end do
+ 60 continue
+ !$omp end do
+
+ !$omp do collapse(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (k .lt. 1) cycle foo
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !$omp do collapse(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (k .lt. 1) cycle foo1
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (k .lt. 1) cycle foo
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+
+ !$omp do ordered(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (k .lt. 1) cycle foo
+ foo2: do k = 0, 10
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(2) ordered(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ if (k .lt. 1) cycle foo
+ foo2: do k = 0, 10
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !$omp do collapse(3)
+ loopk: do k=1,10
+ loopj: do j=1,10
+ loopi: do i=1,10
+ ifi : if (.true.) then
+ !ERROR: EXIT statement terminates associated loop of an OpenMP DO construct
+ if (cond(i,j,k)) exit
+ if (cond(i,j,k)) exit ifi
+ !ERROR: EXIT statement terminates associated loop of an OpenMP DO construct
+ if (cond(i,j,k)) exit loopi
+ !ERROR: EXIT statement terminates associated loop of an OpenMP DO construct
+ if (cond(i,j,k)) exit loopj
+ end if ifi
+ end do loopi
+ end do loopj
+ end do loopk
+ !$omp end do
+
+ !$omp do collapse(2)
+ loopk: do k=1,10
+ loopj: do j=1,10
+ do i=1,10
+ end do
+ !ERROR: EXIT statement terminates associated loop of an OpenMP DO construct
+ if (cond(i,j,k)) exit
+ end do loopj
+ end do loopk
+ !$omp end do
+
+end program omp
diff --git a/flang/test/SemanticsChecked/OpenMP/do09.f90 b/flang/test/SemanticsChecked/OpenMP/do09.f90
new file mode 100644
index 0000000000000..af9f2e294ace9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do09.f90
@@ -0,0 +1,26 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! The do-loop cannot be a DO WHILE or a DO loop without loop control.
+
+program omp_do
+ integer :: i = 0,k
+ !$omp do
+ !ERROR: The DO loop cannot be a DO WHILE with DO directive.
+ do while (i <= 10)
+ print *, "it",i
+ i = i+1
+ end do
+ !$omp end do
+
+ !$omp do
+ !ERROR: The DO loop cannot be a DO WHILE with DO directive.
+ do while (i <= 10)
+ do while (j <= 10)
+ print *, "it",k
+ j = j+1
+ end do
+ i = i+1
+ end do
+ !$omp end do
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do10.f90 b/flang/test/SemanticsChecked/OpenMP/do10.f90
new file mode 100644
index 0000000000000..7e8105e125a92
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do10.f90
@@ -0,0 +1,39 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+! The DO loop iteration variable must be of type integer.
+
+program omp_do
+ real i, j, k
+ !$omp do
+ !ERROR: The DO loop iteration variable must be of the type integer.
+ do i = 1, 10
+ !ERROR: The DO loop iteration variable must be of the type integer.
+ do j = 1, 10
+ print *, "it", i, j
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ !ERROR: The DO loop iteration variable must be of the type integer.
+ do i = 1, 10
+ !ERROR: The DO loop iteration variable must be of the type integer.
+ do j = 1, 10
+ print *, "it", i, j
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(2)
+ !ERROR: The DO loop iteration variable must be of the type integer.
+ do i = 1, 10
+ !ERROR: The DO loop iteration variable must be of the type integer.
+ do j = 1, 10
+ print *, "it", i, j
+ end do
+ end do
+ !$omp end do
+
+end program omp_do
diff --git a/flang/test/SemanticsChecked/OpenMP/do11.f90 b/flang/test/SemanticsChecked/OpenMP/do11.f90
new file mode 100644
index 0000000000000..faab457efff3c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do11.f90
@@ -0,0 +1,36 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Do Loop Constructs
+
+!DEF: /omp_do MainProgram
+program omp_do
+ !DEF: /omp_do/i ObjectEntity INTEGER(4)
+ !DEF: /omp_do/j ObjectEntity INTEGER(4)
+ !DEF: /omp_do/k ObjectEntity INTEGER(4)
+ integer i, j, k
+ !$omp do
+ !DEF: /omp_do/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_do/j
+ do j=1,10
+ !REF: /omp_do/OtherConstruct1/i
+ !REF: /omp_do/j
+ print *, "it", i, j
+ end do
+ end do
+ !$omp end do
+end program omp_do
+
+!DEF: /omp_do2 (Subroutine)Subprogram
+subroutine omp_do2
+ !DEF: /omp_do2/i ObjectEntity INTEGER(4)
+ !DEF: /omp_do2/k ObjectEntity INTEGER(4)
+ integer :: i = 0, k
+ !$omp do
+ !DEF: /omp_do2/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_do2/OtherConstruct1/i
+ print *, "it", i
+ end do
+ !$omp end do
+end subroutine omp_do2
diff --git a/flang/test/SemanticsChecked/OpenMP/do12.f90 b/flang/test/SemanticsChecked/OpenMP/do12.f90
new file mode 100644
index 0000000000000..a057a246f7a99
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do12.f90
@@ -0,0 +1,96 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Do Loop constructs.
+
+!DEF: /omp_cycle MainProgram
+program omp_cycle
+ !$omp do collapse(1)
+ !DEF: /omp_cycle/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ !REF: /omp_cycle/OtherConstruct1/i
+ if (i<1) cycle
+ !DEF: /omp_cycle/j (Implicit) ObjectEntity INTEGER(4)
+ do j=0,10
+ !DEF: /omp_cycle/k (Implicit) ObjectEntity INTEGER(4)
+ do k=0,10
+ !REF: /omp_cycle/OtherConstruct1/i
+ !REF: /omp_cycle/j
+ !REF: /omp_cycle/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(1)
+ !DEF: /omp_cycle/OtherConstruct2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ !REF: /omp_cycle/j
+ do j=0,10
+ !REF: /omp_cycle/OtherConstruct2/i
+ if (i<1) cycle
+ !REF: /omp_cycle/k
+ do k=0,10
+ !REF: /omp_cycle/OtherConstruct2/i
+ !REF: /omp_cycle/j
+ !REF: /omp_cycle/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(2)
+ !DEF: /omp_cycle/OtherConstruct3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ !DEF: /omp_cycle/OtherConstruct3/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=0,10
+ !REF: /omp_cycle/k
+ do k=0,10
+ !REF: /omp_cycle/OtherConstruct3/i
+ if (i<1) cycle
+ !REF: /omp_cycle/OtherConstruct3/i
+ !REF: /omp_cycle/OtherConstruct3/j
+ !REF: /omp_cycle/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(3)
+ !DEF: /omp_cycle/OtherConstruct4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ !DEF: /omp_cycle/OtherConstruct4/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=0,10
+ !DEF: /omp_cycle/OtherConstruct4/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do k=0,10
+ !REF: /omp_cycle/OtherConstruct4/i
+ if (i<1) cycle
+ !REF: /omp_cycle/OtherConstruct4/i
+ !REF: /omp_cycle/OtherConstruct4/j
+ !REF: /omp_cycle/OtherConstruct4/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(3)
+ !DEF: /omp_cycle/OtherConstruct5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo:do i=0,10
+ !DEF: /omp_cycle/OtherConstruct5/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo1:do j=0,10
+ !DEF: /omp_cycle/OtherConstruct5/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo2:do k=0,10
+ !REF: /omp_cycle/OtherConstruct5/i
+ if (i<1) cycle foo2
+ !REF: /omp_cycle/OtherConstruct5/i
+ !REF: /omp_cycle/OtherConstruct5/j
+ !REF: /omp_cycle/OtherConstruct5/k
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+end program omp_cycle
diff --git a/flang/test/SemanticsChecked/OpenMP/do13.f90 b/flang/test/SemanticsChecked/OpenMP/do13.f90
new file mode 100644
index 0000000000000..6e9d1dddade4c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do13.f90
@@ -0,0 +1,185 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+
+program omp
+ integer i, j, k
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(2)
+ do i = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do foo
+ !$omp end do
+
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do 60 i=1,10
+ do j=1,10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ do k=1,10
+ print *,i
+ end do
+ end do
+ 60 continue
+ !$omp end do
+
+ !$omp do collapse(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !$omp do collapse(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo1
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ foo2: do k = 0, 10
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !$omp do ordered(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do collapse(1)
+ foo2: do k = 0, 10
+ print *, i, j, k
+ end do foo2
+ !$omp end do
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !$omp parallel
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ !$omp parallel
+ !$omp do collapse(2)
+ foo2: do k = 0, 10
+ foo3: do l = 0, 10
+ print *, i, j, k, l
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo2
+ end do foo3
+ end do foo2
+ !$omp end do
+ !$omp end parallel
+ end do foo1
+ end do foo
+ !$omp end do
+ !$omp end parallel
+
+ !$omp parallel
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp parallel do ordered(3) collapse(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ !$omp parallel
+ !$omp parallel do collapse(2)
+ foo2: do k = 0, 10
+ foo3: do l = 0, 10
+ print *, i, j, k, l
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo2
+ end do foo3
+ end do foo2
+ !$omp end parallel do
+ !$omp end parallel
+ end do foo1
+ end do foo
+!$omp end parallel do
+!$omp end parallel
+
+end program omp
diff --git a/flang/test/SemanticsChecked/OpenMP/do14.f90 b/flang/test/SemanticsChecked/OpenMP/do14.f90
new file mode 100644
index 0000000000000..5e8a5a64c2979
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do14.f90
@@ -0,0 +1,91 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Do Loop constructs.
+
+!DEF: /omp_cycle MainProgram
+program omp_cycle
+ !$omp do collapse(1)
+ !DEF: /omp_cycle/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ cycle
+ !DEF: /omp_cycle/j (Implicit) ObjectEntity INTEGER(4)
+ do j=0,10
+ !DEF: /omp_cycle/k (Implicit) ObjectEntity INTEGER(4)
+ do k=0,10
+ !REF: /omp_cycle/OtherConstruct1/i
+ !REF: /omp_cycle/j
+ !REF: /omp_cycle/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(1)
+ !DEF: /omp_cycle/OtherConstruct2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ !REF: /omp_cycle/j
+ do j=0,10
+ cycle
+ !REF: /omp_cycle/k
+ do k=0,10
+ !REF: /omp_cycle/OtherConstruct2/i
+ !REF: /omp_cycle/j
+ !REF: /omp_cycle/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(2)
+ !DEF: /omp_cycle/OtherConstruct3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ !DEF: /omp_cycle/OtherConstruct3/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=0,10
+ !REF: /omp_cycle/k
+ do k=0,10
+ cycle
+ !REF: /omp_cycle/OtherConstruct3/i
+ !REF: /omp_cycle/OtherConstruct3/j
+ !REF: /omp_cycle/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(3)
+ !DEF: /omp_cycle/OtherConstruct4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=0,10
+ !DEF: /omp_cycle/OtherConstruct4/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=0,10
+ !DEF: /omp_cycle/OtherConstruct4/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do k=0,10
+ cycle
+ !REF: /omp_cycle/OtherConstruct4/i
+ !REF: /omp_cycle/OtherConstruct4/j
+ !REF: /omp_cycle/OtherConstruct4/k
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do ordered(3)
+ !DEF: /omp_cycle/OtherConstruct5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo:do i=0,10
+ !DEF: /omp_cycle/OtherConstruct5/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo1:do j=0,10
+ !DEF: /omp_cycle/OtherConstruct5/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo2:do k=0,10
+ cycle foo2
+ !REF: /omp_cycle/OtherConstruct5/i
+ !REF: /omp_cycle/OtherConstruct5/j
+ !REF: /omp_cycle/OtherConstruct5/k
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+end program omp_cycle
diff --git a/flang/test/SemanticsChecked/OpenMP/do15.f90 b/flang/test/SemanticsChecked/OpenMP/do15.f90
new file mode 100644
index 0000000000000..45c591e66361c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do15.f90
@@ -0,0 +1,94 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+
+program omp
+ integer i, j, k
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ if (i .lt. 1) then
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ end if
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ do j = 0, 10
+ if (i .lt. 1) then
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ end if
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !!ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ if (i .lt. 1) then
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ else if (i .gt. 3) then
+ cycle foo1
+ end if
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do foo1
+ end do foo
+ !$omp end do
+
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ if (i .lt. 1) then
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ else if (i .gt. 3) then
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo1
+ end if
+ foo2: do k = 0, 10
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !$omp do ordered(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ if (i .lt. 1) then
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ else if (i .gt. 3) then
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo1
+ else
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ end if
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+end program omp
diff --git a/flang/test/SemanticsChecked/OpenMP/do16.f90 b/flang/test/SemanticsChecked/OpenMP/do16.f90
new file mode 100644
index 0000000000000..15d13f683cf12
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do16.f90
@@ -0,0 +1,77 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+
+program omp
+ integer i, j, k
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ select case (i)
+ case(1)
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ end select
+ do j = 0, 10
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: The value of the parameter in the COLLAPSE or ORDERED clause must not be larger than the number of nested loops following the construct.
+ !$omp do collapse(3)
+ do i = 0, 10
+ do j = 0, 10
+ select case (i)
+ case(1)
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle
+ end select
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do
+ end do
+ !$omp end do
+
+ !$omp do collapse(2)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ select case (i)
+ case(1)
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ case(5)
+ cycle foo1
+ end select
+ do k = 0, 10
+ print *, i, j, k
+ end do
+ end do foo1
+ end do foo
+ !$omp end do
+
+ !$omp do ordered(3)
+ foo: do i = 0, 10
+ foo1: do j = 0, 10
+ foo2: do k = 0, 10
+ select case (i)
+ case(1)
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo
+ case(5)
+ !ERROR: CYCLE statement to non-innermost associated loop of an OpenMP DO construct
+ cycle foo1
+ case(7)
+ cycle foo2
+ end select
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+ !$omp end do
+
+end program omp
diff --git a/flang/test/SemanticsChecked/OpenMP/do17.f90 b/flang/test/SemanticsChecked/OpenMP/do17.f90
new file mode 100644
index 0000000000000..c0c59f16dee1b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do17.f90
@@ -0,0 +1,57 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.1 Do Loop constructs.
+
+!DEF: /test MainProgram
+program test
+ !DEF: /test/i ObjectEntity INTEGER(4)
+ !DEF: /test/j ObjectEntity INTEGER(4)
+ !DEF: /test/k ObjectEntity INTEGER(4)
+ integer i, j, k
+ !$omp do collapse(2)
+ !DEF: /test/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo: do i=0,10
+ !DEF: /test/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo1: do j=0,10
+ !REF: /test/k
+ foo2: do k=0,10
+ !REF: /test/OtherConstruct1/i
+ select case (i)
+ case (5)
+ cycle foo1
+ case (7)
+ cycle foo2
+ end select
+ !REF: /test/OtherConstruct1/i
+ !REF: /test/OtherConstruct1/j
+ !REF: /test/k
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+
+ !$omp do collapse(2)
+ !DEF: /test/OtherConstruct2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo: do i=0,10
+ !DEF: /test/OtherConstruct2/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ foo1: do j=0,10
+ !REF: /test/k
+ foo2: do k=0,10
+ !REF: /test/OtherConstruct2/i
+ if (i<3) then
+ cycle foo1
+ !REF: /test/OtherConstruct2/i
+ else if (i>8) then
+ cycle foo1
+ else
+ cycle foo2
+ end if
+ !REF: /test/OtherConstruct2/i
+ !REF: /test/OtherConstruct2/j
+ !REF: /test/k
+ print *, i, j, k
+ end do foo2
+ end do foo1
+ end do foo
+!$omp end do
+end program test
diff --git a/flang/test/SemanticsChecked/OpenMP/do18.f90 b/flang/test/SemanticsChecked/OpenMP/do18.f90
new file mode 100644
index 0000000000000..cdac323240eeb
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do18.f90
@@ -0,0 +1,40 @@
+! RUN: %flang_fc1 -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -fopenmp -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
+! CHECK-NOT: do *[1-9]
+
+program P
+implicit none
+integer OMP_GET_NUM_THREADS, OMP_GET_THREAD_NUM
+integer NUMTHRDS, TID
+integer N, CSZ, CNUM, I
+parameter (N=100)
+parameter (CSZ=10)
+real A(N), B(N), C(N)
+
+do 10 I = 1, N
+ A(I) = I * 1.0
+10 continue
+
+B = A
+CNUM = CSZ
+
+!$OMP PARALLEL SHARED(A,B,C,NUMTHRDS,CNUM) PRIVATE(I,TID)
+TID = OMP_GET_THREAD_NUM()
+if (TID .EQ. 0) then
+ NUMTHRDS = OMP_GET_NUM_THREADS()
+ print *, "Number of threads =", NUMTHRDS
+end if
+print *, "Thread", TID, " is starting..."
+
+!$OMP DO SCHEDULE(DYNAMIC,CNUM)
+do 20 I = 1, N
+ C(I) = A(I) + B(I)
+ write (*,100) TID, I, C(I)
+20 continue
+!$OMP END DO NOWAIT
+
+print *, "Thread", TID, " done."
+
+!$OMP END PARALLEL
+100 format(" Thread", I2, ": C(", I3, ")=", F8.2)
+end program P
diff --git a/flang/test/SemanticsChecked/OpenMP/do19.f90 b/flang/test/SemanticsChecked/OpenMP/do19.f90
new file mode 100644
index 0000000000000..3dab59d615e5e
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do19.f90
@@ -0,0 +1,25 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-unparse-with-symbols %s 2>&1 | FileCheck %s
+! CHECK-NOT: do *[1-9]
+! CHECK: omp simd
+
+program P
+implicit none
+integer N, I
+parameter (N=100)
+real A(N), B(N), C(N)
+
+!$OMP SIMD
+do 10 I = 1, N
+ A(I) = I * 1.0
+10 continue
+
+B = A
+
+!$OMP SIMD
+do 20 I = 1, N
+ C(I) = A(I) + B(I)
+ write (*,100) I, C(I)
+20 continue
+
+100 format(" C(", I3, ")=", F8.2)
+end program P
diff --git a/flang/test/SemanticsChecked/OpenMP/do20.f90 b/flang/test/SemanticsChecked/OpenMP/do20.f90
new file mode 100644
index 0000000000000..915d01e69edd7
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/do20.f90
@@ -0,0 +1,18 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! OpenMP 5.2 5.1.1
+! Iteration variables of non-associated loops may be listed in DSA clauses.
+
+!DEF: /shared_iv (Subroutine)Subprogram
+subroutine shared_iv
+ !DEF: /shared_iv/i ObjectEntity INTEGER(4)
+ integer i
+
+ !$omp parallel shared(i)
+ !$omp single
+ !REF: /shared_iv/i
+ do i = 0, 1
+ end do
+ !$omp end single
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/firstprivate01.f90 b/flang/test/SemanticsChecked/OpenMP/firstprivate01.f90
new file mode 100644
index 0000000000000..0c576a9f07a42
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/firstprivate01.f90
@@ -0,0 +1,124 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.4 firstprivate Clause
+! Variables that appear in a firstprivate clause on a distribute or
+! worksharing constructs must not appear in the private or
+! reduction clause in a teams or parallel constructs in the outer context
+!
+! A list item may appear in a firstprivate or lastprivate clause but not both on
+! a distribute directive
+
+program omp_firstprivate
+ integer :: i, a(10), b(10), c(10)
+
+ a = 10
+ b = 20
+
+ !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct
+ !$omp target
+ !$omp teams private(a, b)
+ !ERROR: FIRSTPRIVATE variable 'a' is PRIVATE in outer context
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ a(i) = a(i) + b(i) - i
+ end do
+ !$omp end distribute
+ !$omp end teams
+ !$omp teams reduction(+:a)
+ !ERROR: FIRSTPRIVATE variable 'a' is PRIVATE in outer context
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ b(i) = b(i) + a(i) + i
+ end do
+ !$omp end distribute
+ !$omp end teams
+
+ !$omp teams distribute firstprivate(a) lastprivate(b)
+ do i = 1, 10
+ a(i) = a(i) + b(i) - i
+ end do
+ !$omp end teams distribute
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !$omp teams distribute firstprivate(a,b) lastprivate(b)
+ do i = 1, 10
+ a(i) = a(i) + b(i) - i
+ end do
+ !$omp end teams distribute
+ !ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !$omp teams distribute firstprivate(a,b) lastprivate(a,b)
+ do i = 1, 10
+ a(i) = a(i) + b(i) - i
+ end do
+ !$omp end teams distribute
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !$omp teams distribute lastprivate(a,b) firstprivate(b)
+ do i = 1, 10
+ a(i) = a(i) + b(i) - i
+ end do
+ !$omp end teams distribute
+ !ERROR: Variable 'b' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !ERROR: Variable 'a' may not appear on both FIRSTPRIVATE and LASTPRIVATE clauses on a TEAMS DISTRIBUTE construct
+ !$omp teams distribute lastprivate(a,b) firstprivate(b,a)
+ do i = 1, 10
+ a(i) = a(i) + b(i) - i
+ end do
+ !$omp end teams distribute
+ !$omp end target
+
+ print *, a, b
+
+ !$omp parallel private(a,b)
+ !ERROR: FIRSTPRIVATE variable 'b' is PRIVATE in outer context
+ !$omp do firstprivate(b)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + i
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp parallel reduction(*:a)
+ !ERROR: FIRSTPRIVATE variable 'a' is PRIVATE in outer context
+ !$omp do firstprivate(a,b)
+ do i = 1, 10
+ c(i) = c(i) * a(i) * b(i) * i
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp parallel reduction(+:a)
+ !ERROR: FIRSTPRIVATE variable 'a' is PRIVATE in outer context
+ !$omp sections firstprivate(a, b)
+ !$omp section
+ c = c * a + b
+ !$omp end sections
+ !$omp end parallel
+
+ !$omp parallel reduction(*:a)
+ !ERROR: FIRSTPRIVATE variable 'a' is PRIVATE in outer context
+ !$omp task firstprivate(a,b)
+ c = c * a * b
+ !$omp end task
+ !$omp end parallel
+
+ !$omp parallel reduction(+:b)
+ !ERROR: FIRSTPRIVATE variable 'b' is PRIVATE in outer context
+ !$omp taskloop firstprivate(b)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + i
+ a = a+i
+ b = b-i
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel firstprivate(a)
+ !ERROR: FIRSTPRIVATE variable 'a' is PRIVATE in outer context
+ !$omp single firstprivate(a)
+ print *, a
+ !$omp end single
+ !$omp end parallel
+
+ print *, c
+
+end program omp_firstprivate
diff --git a/flang/test/SemanticsChecked/OpenMP/firstprivate02.f90 b/flang/test/SemanticsChecked/OpenMP/firstprivate02.f90
new file mode 100644
index 0000000000000..eb2597cb1cc40
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/firstprivate02.f90
@@ -0,0 +1,20 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.2, Sections 3.2.1 & 5.3
+subroutine omp_firstprivate(init)
+ integer :: init
+ integer :: a(10)
+ type my_type
+ integer :: val
+ end type my_type
+ type(my_type) :: my_var
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a FIRSTPRIVATE clause
+ !$omp parallel firstprivate(a(2))
+ a(2) = init
+ !$omp end parallel
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a FIRSTPRIVATE clause
+ !$omp parallel firstprivate(my_var%val)
+ my_var%val = init
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/flush01.f90 b/flang/test/SemanticsChecked/OpenMP/flush01.f90
new file mode 100644
index 0000000000000..27324de4a8f7a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/flush01.f90
@@ -0,0 +1,36 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! 2.17.8 Flush construct [OpenMP 5.0]
+! memory-order-clause ->
+! acq_rel
+! release
+! acquire
+use omp_lib
+ implicit none
+
+ integer :: i, a, b
+ real, DIMENSION(10) :: array
+
+ a = 1.0
+ !$omp parallel num_threads(4)
+ !Only memory-order-clauses.
+ if (omp_get_thread_num() == 1) then
+ ! Allowed clauses.
+ !$omp flush acq_rel
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !$omp flush release
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !$omp flush acquire
+
+ !ERROR: expected end of line
+ !$omp flush private(array)
+ !ERROR: expected end of line
+ !$omp flush num_threads(4)
+
+ ! Mix allowed and not allowed clauses.
+ !ERROR: expected end of line
+ !$omp flush num_threads(4) acquire
+ end if
+ !$omp end parallel
+end
+
diff --git a/flang/test/SemanticsChecked/OpenMP/flush02.f90 b/flang/test/SemanticsChecked/OpenMP/flush02.f90
new file mode 100644
index 0000000000000..18a0d0356bbd7
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/flush02.f90
@@ -0,0 +1,88 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+
+! Check OpenMP 5.0 - 2.17.8 flush Construct
+! Restriction -
+! If memory-order-clause is release, acquire, or acq_rel, list items must not be specified on the flush directive.
+
+use omp_lib
+ implicit none
+
+ TYPE someStruct
+ REAL :: rr
+ end TYPE
+ integer :: i, a, b
+ real, DIMENSION(10) :: array
+ TYPE(someStruct) :: structObj
+
+ a = 1.0
+ !$omp parallel num_threads(4)
+ !No list flushes all.
+ if (omp_get_thread_num() == 1) THEN
+ !$omp flush
+ END IF
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !Only memory-order-clauses.
+ if (omp_get_thread_num() == 1) THEN
+ ! Not allowed clauses.
+ !ERROR: SEQ_CST clause is not allowed on the FLUSH directive
+ !$omp flush seq_cst
+ !ERROR: RELAXED clause is not allowed on the FLUSH directive
+ !$omp flush relaxed
+
+ ! Not allowed more than once.
+ !ERROR: At most one ACQ_REL clause can appear on the FLUSH directive
+ !$omp flush acq_rel acq_rel
+ !ERROR: At most one RELEASE clause can appear on the FLUSH directive
+ !$omp flush release release
+ !ERROR: At most one ACQUIRE clause can appear on the FLUSH directive
+ !$omp flush acquire acquire
+
+ ! Mix of allowed and not allowed.
+ !ERROR: SEQ_CST clause is not allowed on the FLUSH directive
+ !$omp flush seq_cst acquire
+ END IF
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ ! No memory-order-clause only list-items.
+ if (omp_get_thread_num() == 2) THEN
+ !$omp flush (a)
+ !$omp flush (i, a, b)
+ !$omp flush (array, structObj%rr)
+ ! Too many flush with repeating list items.
+ !$omp flush (i, a, b, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, b, b, b, b)
+ !ERROR: No explicit type declared for 'notpresentitem'
+ !$omp flush (notPresentItem)
+ END IF
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ if (omp_get_thread_num() == 3) THEN
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acq_rel (array)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acq_rel (array, a, i)
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush release (array)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush release (array, a)
+
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acquire (array)
+ !ERROR: If memory-order-clause is RELEASE, ACQUIRE, or ACQ_REL, list items must not be specified on the FLUSH directive
+ !$omp flush acquire (array, a, structObj%rr)
+ END IF
+ !$omp end parallel
+
+ !$omp parallel num_threads(4)
+ array = (/1, 2, 3, 4, 5, 6, 7, 8, 9, 10/)
+ !$omp master
+ !$omp flush (array)
+ !$omp end master
+ !$omp end parallel
+end
+
diff --git a/flang/test/SemanticsChecked/OpenMP/if-clause.f90 b/flang/test/SemanticsChecked/OpenMP/if-clause.f90
new file mode 100644
index 0000000000000..493c6c873bfbf
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/if-clause.f90
@@ -0,0 +1,624 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! Check OpenMP 'if' clause validity for all directives that can have it
+
+program main
+ integer :: i
+
+ ! ----------------------------------------------------------------------------
+ ! DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ !$omp teams
+ !$omp distribute parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !$omp distribute parallel do if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp distribute parallel do if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+
+ !ERROR: At most one IF clause can appear on the DISTRIBUTE PARALLEL DO directive
+ !$omp distribute parallel do if(.true.) if(parallel: .false.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do
+ !$omp end teams
+
+ ! ----------------------------------------------------------------------------
+ ! DISTRIBUTE PARALLEL DO SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp teams
+ !$omp distribute parallel do simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do simd
+
+ !$omp distribute parallel do simd if(parallel: .true.) if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp distribute parallel do simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute parallel do simd
+ !$omp end teams
+
+ ! ----------------------------------------------------------------------------
+ ! DISTRIBUTE SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp teams
+ !$omp distribute simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute simd
+
+ !$omp distribute simd if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp distribute simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end distribute simd
+
+ !ERROR: At most one IF clause can appear on the DISTRIBUTE SIMD directive
+ !$omp distribute simd if(.true.) if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end distribute simd
+ !$omp end teams
+
+ ! ----------------------------------------------------------------------------
+ ! DO SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp do simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end do simd
+
+ !$omp do simd if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end do simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp do simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end do simd
+
+ !ERROR: At most one IF clause can appear on the DO SIMD directive
+ !$omp do simd if(.true.) if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end do simd
+
+ ! ----------------------------------------------------------------------------
+ ! PARALLEL
+ ! ----------------------------------------------------------------------------
+ !$omp parallel if(.true.)
+ !$omp end parallel
+
+ !$omp parallel if(parallel: .true.)
+ !$omp end parallel
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp parallel if(target: .true.)
+ !$omp end parallel
+
+ !ERROR: At most one IF clause can appear on the PARALLEL directive
+ !$omp parallel if(.true.) if(parallel: .false.)
+ !$omp end parallel
+
+ ! ----------------------------------------------------------------------------
+ ! PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ !$omp parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end parallel do
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp parallel do if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end parallel do
+
+ !ERROR: At most one IF clause can appear on the PARALLEL DO directive
+ !$omp parallel do if(.true.) if(parallel: .false.)
+ do i = 1, 10
+ end do
+ !$omp end parallel do
+
+ ! ----------------------------------------------------------------------------
+ ! PARALLEL DO SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp parallel do simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end parallel do simd
+
+ !$omp parallel do simd if(parallel: .true.) if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end parallel do simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp parallel do simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end parallel do simd
+
+ ! ----------------------------------------------------------------------------
+ ! PARALLEL SECTIONS
+ ! ----------------------------------------------------------------------------
+ !$omp parallel sections if(.true.)
+ !$omp end parallel sections
+
+ !$omp parallel sections if(parallel: .true.)
+ !$omp end parallel sections
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp parallel sections if(target: .true.)
+ !$omp end parallel sections
+
+ !ERROR: At most one IF clause can appear on the PARALLEL SECTIONS directive
+ !$omp parallel sections if(.true.) if(parallel: .false.)
+ !$omp end parallel sections
+
+ ! ----------------------------------------------------------------------------
+ ! PARALLEL WORKSHARE
+ ! ----------------------------------------------------------------------------
+ !$omp parallel workshare if(.true.)
+ !$omp end parallel workshare
+
+ !$omp parallel workshare if(parallel: .true.)
+ !$omp end parallel workshare
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp parallel workshare if(target: .true.)
+ !$omp end parallel workshare
+
+ !ERROR: At most one IF clause can appear on the PARALLEL WORKSHARE directive
+ !$omp parallel workshare if(.true.) if(parallel: .false.)
+ !$omp end parallel workshare
+
+ ! ----------------------------------------------------------------------------
+ ! SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end simd
+
+ !$omp simd if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end simd
+
+ !ERROR: At most one IF clause can appear on the SIMD directive
+ !$omp simd if(.true.) if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end simd
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET
+ ! ----------------------------------------------------------------------------
+ !$omp target if(.true.)
+ !$omp end target
+
+ !$omp target if(target: .true.)
+ !$omp end target
+
+ !ERROR: Unmatched directive name modifier PARALLEL on the IF clause
+ !$omp target if(parallel: .true.)
+ !$omp end target
+
+ !ERROR: At most one IF clause can appear on the TARGET directive
+ !$omp target if(.true.) if(target: .false.)
+ !$omp end target
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET DATA
+ ! ----------------------------------------------------------------------------
+ !$omp target data map(tofrom: i) if(.true.)
+ !$omp end target data
+
+ !$omp target data map(tofrom: i) if(target data: .true.)
+ !$omp end target data
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp target data map(tofrom: i) if(target: .true.)
+ !$omp end target data
+
+ !ERROR: At most one IF clause can appear on the TARGET DATA directive
+ !$omp target data map(tofrom: i) if(.true.) if(target data: .false.)
+ !$omp end target data
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET ENTER DATA
+ ! ----------------------------------------------------------------------------
+ !$omp target enter data map(to: i) if(.true.)
+
+ !$omp target enter data map(to: i) if(target enter data: .true.)
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp target enter data map(to: i) if(target: .true.)
+
+ !ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive
+ !$omp target enter data map(to: i) if(.true.) if(target enter data: .false.)
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET EXIT DATA
+ ! ----------------------------------------------------------------------------
+ !$omp target exit data map(from: i) if(.true.)
+
+ !$omp target exit data map(from: i) if(target exit data: .true.)
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp target exit data map(from: i) if(target: .true.)
+
+ !ERROR: At most one IF clause can appear on the TARGET EXIT DATA directive
+ !$omp target exit data map(from: i) if(.true.) if(target exit data: .false.)
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET PARALLEL
+ ! ----------------------------------------------------------------------------
+ !$omp target parallel if(.true.)
+ !$omp end target parallel
+
+ !$omp target parallel if(target: .true.) if(parallel: .false.)
+ !$omp end target parallel
+
+ !ERROR: Unmatched directive name modifier SIMD on the IF clause
+ !$omp target parallel if(simd: .true.)
+ !$omp end target parallel
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ !$omp target parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target parallel do
+
+ !$omp target parallel do if(target: .true.) if(parallel: .false.)
+ do i = 1, 10
+ end do
+ !$omp end target parallel do
+
+ !ERROR: Unmatched directive name modifier SIMD on the IF clause
+ !$omp target parallel do if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target parallel do
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET PARALLEL DO SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp target parallel do simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target parallel do simd
+
+ !$omp target parallel do simd if(target: .true.) if(parallel: .false.) &
+ !$omp& if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target parallel do simd
+
+ !ERROR: Unmatched directive name modifier TEAMS on the IF clause
+ !$omp target parallel do simd if(teams: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target parallel do simd
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp target simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target simd
+
+ !$omp target simd if(target: .true.) if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end target simd
+
+ !ERROR: Unmatched directive name modifier PARALLEL on the IF clause
+ !$omp target simd if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target simd
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS
+ ! ----------------------------------------------------------------------------
+ !$omp target teams if(.true.)
+ !$omp end target teams
+
+ !$omp target teams if(target: .true.) if(teams: .false.)
+ !$omp end target teams
+
+ !ERROR: Unmatched directive name modifier PARALLEL on the IF clause
+ !$omp target teams if(parallel: .true.)
+ !$omp end target teams
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS DISTRIBUTE
+ ! ----------------------------------------------------------------------------
+ !$omp target teams distribute if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ !$omp target teams distribute if(target: .true.) if(teams: .false.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ !ERROR: Unmatched directive name modifier PARALLEL on the IF clause
+ !$omp target teams distribute if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ !$omp target teams distribute parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ !$omp target teams distribute parallel do &
+ !$omp& if(target: .true.) if(teams: .false.) if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ !ERROR: Unmatched directive name modifier SIMD on the IF clause
+ !$omp target teams distribute parallel do if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp target teams distribute parallel do simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd &
+ !$omp& if(target: .true.) if(teams: .false.) if(parallel: .true.) &
+ !$omp& if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do simd
+
+ !ERROR: Unmatched directive name modifier TASK on the IF clause
+ !$omp target teams distribute parallel do simd if(task: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute parallel do simd
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET TEAMS DISTRIBUTE SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp target teams distribute simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute simd
+
+ !$omp target teams distribute simd &
+ !$omp& if(target: .true.) if(teams: .false.) if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute simd
+
+ !ERROR: Unmatched directive name modifier PARALLEL on the IF clause
+ !$omp target teams distribute simd if(parallel: .true.)
+ do i = 1, 10
+ end do
+ !$omp end target teams distribute simd
+
+ ! ----------------------------------------------------------------------------
+ ! TARGET UPDATE
+ ! ----------------------------------------------------------------------------
+ !$omp target update to(i) if(.true.)
+
+ !$omp target update to(i) if(target update: .true.)
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp target update to(i) if(target: .true.)
+
+ !ERROR: At most one IF clause can appear on the TARGET UPDATE directive
+ !$omp target update to(i) if(.true.) if(target update: .false.)
+
+ ! ----------------------------------------------------------------------------
+ ! TASK
+ ! ----------------------------------------------------------------------------
+ !$omp task if(.true.)
+ !$omp end task
+
+ !$omp task if(task: .true.)
+ !$omp end task
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp task if(target: .true.)
+ !$omp end task
+
+ !ERROR: At most one IF clause can appear on the TASK directive
+ !$omp task if(.true.) if(task: .false.)
+ !$omp end task
+
+ ! ----------------------------------------------------------------------------
+ ! TASKLOOP
+ ! ----------------------------------------------------------------------------
+ !$omp taskloop if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end taskloop
+
+ !$omp taskloop if(taskloop: .true.)
+ do i = 1, 10
+ end do
+ !$omp end taskloop
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp taskloop if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end taskloop
+
+ !ERROR: At most one IF clause can appear on the TASKLOOP directive
+ !$omp taskloop if(.true.) if(taskloop: .false.)
+ do i = 1, 10
+ end do
+ !$omp end taskloop
+
+ ! ----------------------------------------------------------------------------
+ ! TASKLOOP SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp taskloop simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end taskloop simd
+
+ !$omp taskloop simd if(taskloop: .true.) if(simd: .false.)
+ do i = 1, 10
+ end do
+ !$omp end taskloop simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp taskloop simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end taskloop simd
+
+ ! ----------------------------------------------------------------------------
+ ! TEAMS
+ ! ----------------------------------------------------------------------------
+ !$omp teams if(.true.)
+ !$omp end teams
+
+ !$omp teams if(teams: .true.)
+ !$omp end teams
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp teams if(target: .true.)
+ !$omp end teams
+
+ !ERROR: At most one IF clause can appear on the TEAMS directive
+ !$omp teams if(.true.) if(teams: .false.)
+ !$omp end teams
+
+ ! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE
+ ! ----------------------------------------------------------------------------
+ !$omp teams distribute if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
+
+ !$omp teams distribute if(teams: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp teams distribute if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
+
+ !ERROR: At most one IF clause can appear on the TEAMS DISTRIBUTE directive
+ !$omp teams distribute if(.true.) if(teams: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute
+
+ ! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE PARALLEL DO
+ ! ----------------------------------------------------------------------------
+ !$omp teams distribute parallel do if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
+ !$omp teams distribute parallel do if(teams: .true.) if(parallel: .false.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp teams distribute parallel do if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do
+
+ ! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE PARALLEL DO SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp teams distribute parallel do simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do simd
+
+ !$omp teams distribute parallel do simd &
+ !$omp& if(teams: .true.) if(parallel: .true.) if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp teams distribute parallel do simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute parallel do simd
+
+ ! ----------------------------------------------------------------------------
+ ! TEAMS DISTRIBUTE SIMD
+ ! ----------------------------------------------------------------------------
+ !$omp teams distribute simd if(.true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute simd
+
+ !$omp teams distribute simd if(teams: .true.) if(simd: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute simd
+
+ !ERROR: Unmatched directive name modifier TARGET on the IF clause
+ !$omp teams distribute simd if(target: .true.)
+ do i = 1, 10
+ end do
+ !$omp end teams distribute simd
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/implicit-dsa.f90 b/flang/test/SemanticsChecked/OpenMP/implicit-dsa.f90
new file mode 100644
index 0000000000000..92d2421d06f97
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/implicit-dsa.f90
@@ -0,0 +1,158 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! Test symbols generated in block constructs that have implicitly
+! determined DSAs.
+
+! Basic cases.
+!DEF: /implicit_dsa_test1 (Subroutine) Subprogram
+subroutine implicit_dsa_test1
+ !DEF: /implicit_dsa_test1/i ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test1/x ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test1/y ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test1/z ObjectEntity INTEGER(4)
+ integer i, x, y, z
+
+ !$omp task private(y) shared(z)
+ !DEF: /implicit_dsa_test1/OtherConstruct1/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ !DEF: /implicit_dsa_test1/OtherConstruct1/y (OmpPrivate) HostAssoc INTEGER(4)
+ !REF: /implicit_dsa_test1/z
+ x = y + z
+ !$omp end task
+
+ !$omp task default(shared)
+ !REF: /implicit_dsa_test1/x
+ !REF: /implicit_dsa_test1/y
+ !REF: /implicit_dsa_test1/z
+ x = y + z
+ !$omp end task
+
+ !$omp taskloop
+ !DEF: /implicit_dsa_test1/OtherConstruct3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i = 0, 10
+ !DEF: /implicit_dsa_test1/OtherConstruct3/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ !DEF: /implicit_dsa_test1/OtherConstruct3/y (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ !REF: /implicit_dsa_test1/OtherConstruct3/i
+ x = y + i
+ end do
+ !$omp end taskloop
+end subroutine
+
+! Nested task with implicit firstprivate DSA variable.
+!DEF: /implicit_dsa_test2 (Subroutine) Subprogram
+subroutine implicit_dsa_test2
+ !DEF: /implicit_dsa_test2/x ObjectEntity INTEGER(4)
+ integer x
+
+ !$omp task
+ !$omp task
+ !DEF: /implicit_dsa_test2/OtherConstruct1/OtherConstruct1/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ x = 1
+ !$omp end task
+ !$omp end task
+end subroutine
+
+! Nested tasks with implicit shared DSA variables.
+!DEF: /implicit_dsa_test3 (Subroutine) Subprogram
+subroutine implicit_dsa_test3
+ !DEF: /implicit_dsa_test3/x ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test3/y ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test3/z ObjectEntity INTEGER(4)
+ integer x, y, z
+
+ !$omp parallel
+ !$omp task
+ !REF: /implicit_dsa_test3/x
+ x = 1
+ !REF: /implicit_dsa_test3/y
+ y = 1
+ !$omp end task
+
+ !$omp task firstprivate(x)
+ !DEF: /implicit_dsa_test3/OtherConstruct1/OtherConstruct2/x (OmpFirstPrivate) HostAssoc INTEGER(4)
+ x = 1
+ !REF: /implicit_dsa_test3/z
+ z = 1
+ !$omp end task
+ !$omp end parallel
+end subroutine
+
+! Task with implicit firstprivate DSA variables, enclosed in private context.
+!DEF: /implicit_dsa_test4 (Subroutine) Subprogram
+subroutine implicit_dsa_test4
+ !DEF: /implicit_dsa_test4/x ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test4/y ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test4/z ObjectEntity INTEGER(4)
+ integer x, y, z
+
+ !$omp parallel default(private)
+ !$omp task
+ !DEF: /implicit_dsa_test4/OtherConstruct1/OtherConstruct1/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ x = 0
+ !DEF: /implicit_dsa_test4/OtherConstruct1/OtherConstruct1/z (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ z = 1
+ !$omp end task
+
+ !$omp task
+ !DEF: /implicit_dsa_test4/OtherConstruct1/OtherConstruct2/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ x = 1
+ !DEF: /implicit_dsa_test4/OtherConstruct1/OtherConstruct2/y (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ y = 0
+ !$omp end task
+ !$omp end parallel
+end subroutine
+
+! Inner parallel using implicit firstprivate symbol.
+!DEF: /implicit_dsa_test5 (Subroutine) Subprogram
+subroutine implicit_dsa_test5
+ !DEF: /implicit_dsa_test5/x ObjectEntity INTEGER(4)
+ integer x
+
+ !$omp parallel default(private)
+ !$omp task
+ !$omp parallel
+ !DEF: /implicit_dsa_test5/OtherConstruct1/OtherConstruct1/OtherConstruct1/x HostAssoc INTEGER(4)
+ x = 1
+ !$omp end parallel
+ !$omp end task
+ !$omp end parallel
+end subroutine
+
+! Constructs nested inside a task with implicit DSA variables.
+!DEF: /implicit_dsa_test6 (Subroutine) Subprogram
+subroutine implicit_dsa_test6
+ !DEF: /implicit_dsa_test6/x ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test6/y ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test6/z ObjectEntity INTEGER(4)
+ integer x, y, z
+
+ !$omp task
+ !$omp parallel default(private)
+ !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct1/x (OmpPrivate) HostAssoc INTEGER(4)
+ !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct1/y (OmpPrivate) HostAssoc INTEGER(4)
+ x = y
+ !$omp end parallel
+
+ !$omp parallel default(firstprivate) shared(y)
+ !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct2/y HostAssoc INTEGER(4)
+ !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct2/x (OmpFirstPrivate) HostAssocINTEGER(4)
+ !DEF: /implicit_dsa_test6/OtherConstruct1/OtherConstruct2/z (OmpFirstPrivate) HostAssocINTEGER(4)
+ y = x + z
+ !$omp end parallel
+ !$omp end task
+end subroutine
+
+! Test taskgroup - it uses the same scope as task.
+!DEF: /implicit_dsa_test7 (Subroutine) Subprogram
+subroutine implicit_dsa_test7
+ !DEF: /implicit_dsa_test7/x ObjectEntity INTEGER(4)
+ !DEF: /implicit_dsa_test7/y ObjectEntity INTEGER(4)
+ integer x, y
+
+ !$omp task
+ !$omp taskgroup
+ !DEF: /implicit_dsa_test7/OtherConstruct1/x (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ !DEF: /implicit_dsa_test7/OtherConstruct1/y (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+ x = y
+ !$omp end taskgroup
+ !$omp end task
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/invalid-branch.f90 b/flang/test/SemanticsChecked/OpenMP/invalid-branch.f90
new file mode 100644
index 0000000000000..ed9e4d268f65a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/invalid-branch.f90
@@ -0,0 +1,108 @@
+! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s
+! REQUIRES: shell
+! OpenMP Version 4.5
+! Check invalid branches into or out of OpenMP structured blocks.
+
+subroutine omp_err_end_eor(a, b, x)
+ integer x
+
+ !$omp parallel
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing PARALLEL directive branched into
+
+ !CHECK: invalid branch leaving an OpenMP structured block
+ !CHECK: Outside the enclosing PARALLEL directive
+ open (10, file="myfile.dat", err=100)
+ !CHECK: invalid branch leaving an OpenMP structured block
+ !CHECK: Outside the enclosing PARALLEL directive
+
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing PARALLEL directive branched into
+
+ !CHECK: invalid branch leaving an OpenMP structured block
+ !CHECK: Outside the enclosing PARALLEL directive
+ read (10, 20, end=200, size=x, advance='no', eor=300) a
+ !$omp end parallel
+
+ goto 99
+ 99 close (10)
+ goto 40
+ !$omp parallel
+ 100 print *, "error opening"
+ !$omp end parallel
+ 101 return
+ 200 print *, "end of file"
+ 202 return
+
+ !$omp parallel
+ 300 print *, "end of record"
+ !$omp end parallel
+
+ 303 return
+ 20 format (1x,F5.1)
+ 30 format (2x,F6.2)
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing PARALLEL directive branched into
+ 40 open (11, file="myfile2.dat", err=100)
+ goto 50
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing PARALLEL directive branched into
+ 50 write (11, 30, err=100) b
+ close (11)
+end subroutine
+
+subroutine omp_alt_return_spec(n, *, *)
+ if (n .eq. 0) return
+ if (n .eq. 1) return 1
+ return 2
+end subroutine
+
+program omp_invalid_branch
+ integer :: n = 0, a = 3, b
+
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing PARALLEL directive branched into
+
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing PARALLEL directive branched into
+ goto (1, 2, 3) a
+
+ assign 2 to b
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing PARALLEL directive branched into
+ goto b (1, 2)
+
+ !$omp parallel
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing SINGLE directive branched into
+
+ !CHECK: invalid branch leaving an OpenMP structured block
+ !CHECK: Outside the enclosing PARALLEL directive
+ 3 if(n) 4, 5, 6
+
+ 6 print *, 6
+ 2 print *, 2
+
+ !$omp single
+ 4 print *, 4
+ !$omp end single
+ !$omp end parallel
+
+ 1 print *, 1
+ 5 print *, 5
+
+ !$omp parallel
+ !CHECK: invalid branch into an OpenMP structured block
+ !CHECK: In the enclosing SINGLE directive branched into
+
+ !CHECK: invalid branch leaving an OpenMP structured block
+ !CHECK: Outside the enclosing PARALLEL directive
+ call omp_alt_return_spec(n, *8, *9)
+ print *, "Normal Return"
+ !$omp single
+ 8 print *, "1st alternate return"
+ !$omp end single
+ !$omp end parallel
+ 9 print *, "2nd alternate return"
+
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/lastprivate01.f90 b/flang/test/SemanticsChecked/OpenMP/lastprivate01.f90
new file mode 100644
index 0000000000000..4fae4829d8862
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/lastprivate01.f90
@@ -0,0 +1,57 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.5 lastprivate Clause
+! A variable that appears in a lastprivate clause must be definable.
+
+module protected_var
+ integer, protected :: p
+end module protected_var
+
+program omp_lastprivate
+ use protected_var
+ integer :: i, a(10), b(10), c(10)
+ integer, parameter :: k = 10
+
+ a = 10
+ b = 20
+
+ !ERROR: Variable 'k' on the LASTPRIVATE clause is not definable
+ !BECAUSE: 'k' is not a variable
+ !$omp parallel do lastprivate(k)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ end do
+ !$omp end parallel do
+
+ !ERROR: Variable 'p' on the LASTPRIVATE clause is not definable
+ !BECAUSE: 'p' is protected in this scope
+ !$omp parallel do lastprivate(p)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ end do
+ !$omp end parallel do
+
+ call omp_lastprivate_sb(i)
+
+ print *, c
+
+end program omp_lastprivate
+
+subroutine omp_lastprivate_sb(m)
+ integer :: i, a(10), b(10), c(10)
+ integer, intent(in) :: m
+
+ a = 10
+ b = 20
+
+ !ERROR: Variable 'm' on the LASTPRIVATE clause is not definable
+ !BECAUSE: 'm' is an INTENT(IN) dummy argument
+ !$omp parallel do lastprivate(m)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + m
+ end do
+ !$omp end parallel do
+
+ print *, c
+
+end subroutine omp_lastprivate_sb
diff --git a/flang/test/SemanticsChecked/OpenMP/lastprivate02.f90 b/flang/test/SemanticsChecked/OpenMP/lastprivate02.f90
new file mode 100644
index 0000000000000..c5bf9d7f50d04
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/lastprivate02.f90
@@ -0,0 +1,35 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.5 lastprivate Clause
+! A list item that is private within a parallel region, or that appears in
+! reduction clause of a parallel construct, must not appear in a
+! lastprivate clause on a worksharing construct if any of the corresponding
+! worksharing regions ever binds to any of the corresponding parallel regions.
+
+program omp_lastprivate
+ integer :: a(10), b(10), c(10)
+
+ a = 10
+ b = 20
+
+ !$omp parallel reduction(+:a)
+ !ERROR: LASTPRIVATE variable 'a' is PRIVATE in outer context
+ !$omp sections lastprivate(a, b)
+ !$omp section
+ c = a + b
+ !$omp end sections
+ !$omp end parallel
+
+ !$omp parallel private(a,b)
+ !ERROR: LASTPRIVATE variable 'a' is PRIVATE in outer context
+ !ERROR: LASTPRIVATE variable 'b' is PRIVATE in outer context
+ !$omp do lastprivate(a,b)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + i
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ print *, c
+
+end program omp_lastprivate
diff --git a/flang/test/SemanticsChecked/OpenMP/lastprivate03.f90 b/flang/test/SemanticsChecked/OpenMP/lastprivate03.f90
new file mode 100644
index 0000000000000..d7fe0c162f27c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/lastprivate03.f90
@@ -0,0 +1,24 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.2, Sections 3.2.1 & 5.3
+subroutine omp_lastprivate(init)
+ integer :: init
+ integer :: i, a(10)
+ type my_type
+ integer :: val
+ end type my_type
+ type(my_type) :: my_var
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a LASTPRIVATE clause
+ !$omp do lastprivate(a(2))
+ do i=1, 10
+ a(2) = init
+ end do
+ !$omp end do
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a LASTPRIVATE clause
+ !$omp do lastprivate(my_var%val)
+ do i=1, 10
+ my_var%val = init
+ end do
+ !$omp end do
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/linear-iter.f90 b/flang/test/SemanticsChecked/OpenMP/linear-iter.f90
new file mode 100644
index 0000000000000..8102c1a03cd37
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/linear-iter.f90
@@ -0,0 +1,85 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! Various checks with the ordered construct
+
+SUBROUTINE LINEAR_GOOD(N)
+ INTEGER N, i, j, a, b(10)
+ !$omp target
+ !$omp teams
+ !$omp distribute parallel do simd linear(i)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute parallel do simd
+ !$omp end teams
+ !$omp end target
+END SUBROUTINE LINEAR_GOOD
+
+SUBROUTINE LINEAR_BAD(N)
+ INTEGER N, i, j, a, b(10)
+
+ !$omp target
+ !$omp teams
+ !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE`
+ !$omp distribute parallel do simd linear(j)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute parallel do simd
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !$omp teams
+ !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE`
+ !ERROR: Variable 'b' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE`
+ !$omp distribute parallel do simd linear(j) linear(b)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute parallel do simd
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !$omp teams
+ !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE`
+ !ERROR: Variable 'b' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE`
+ !$omp distribute parallel do simd linear(j, b)
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute parallel do simd
+ !$omp end teams
+ !$omp end target
+
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE`
+ !$omp distribute simd linear(i,j)
+ do i = 1, N
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end distribute simd
+
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE`
+ !$omp distribute simd linear(i,j) collapse(1)
+ do i = 1, N
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end distribute simd
+
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute simd linear(i,j) collapse(2)
+ do i = 1, N
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end distribute simd
+
+END SUBROUTINE LINEAR_BAD
diff --git a/flang/test/SemanticsChecked/OpenMP/loop-association.f90 b/flang/test/SemanticsChecked/OpenMP/loop-association.f90
new file mode 100644
index 0000000000000..d2167663c5dde
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/loop-association.f90
@@ -0,0 +1,134 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! Check the association between OpenMPLoopConstruct and DoConstruct
+
+ integer :: b = 128
+ integer :: c = 32
+ integer, parameter :: num = 16
+ N = 1024
+
+! Different DO loops
+
+ !$omp parallel
+ !$omp do
+ do 10 i=1, N
+ a = 3.14
+10 print *, a
+ !$omp end parallel
+
+ !$omp parallel do
+ DO CONCURRENT (i = 1:N)
+ a = 3.14
+ END DO
+
+ !$omp parallel do simd
+ outer: DO WHILE (c > 1)
+ inner: do while (b > 100)
+ a = 3.14
+ b = b - 1
+ enddo inner
+ c = c - 1
+ END DO outer
+
+ ! Accept directives between parallel do and actual loop.
+ !$OMP PARALLEL DO
+ !DIR$ VECTOR ALIGNED
+ DO 20 i=1,N
+ a = a + 0.5
+20 CONTINUE
+ !$OMP END PARALLEL DO
+
+ c = 16
+ !ERROR: DO loop after the PARALLEL DO directive must have loop control
+ !$omp parallel do
+ do
+ a = 3.14
+ c = c - 1
+ if (c < 1) exit
+ enddo
+
+! Loop association check
+
+ ! If an end do directive follows a do-construct in which several DO
+ ! statements share a DO termination statement, then a do directive
+ ! can only be specified for the outermost of these DO statements.
+ do 100 i=1, N
+ !$omp do
+ do 100 j=1, N
+ a = 3.14
+100 continue
+ !ERROR: The ENDDO directive must follow the DO loop associated with the loop construct
+ !$omp enddo
+
+ !$omp parallel do copyin(a)
+ do i = 1, N
+ !$omp parallel do
+ do j = 1, i
+ enddo
+ !$omp end parallel do
+ a = 3.
+ enddo
+ !$omp end parallel do
+
+ !$omp parallel do
+ do i = 1, N
+ enddo
+ !$omp end parallel do
+ !ERROR: The END PARALLEL DO directive must follow the DO loop associated with the loop construct
+ !$omp end parallel do
+
+ !$omp parallel
+ a = 3.0
+ !$omp do simd
+ do i = 1, N
+ enddo
+ !$omp end do simd
+
+ !$omp parallel do copyin(a)
+ do i = 1, N
+ enddo
+ !$omp end parallel
+
+ a = 0.0
+ !ERROR: The END PARALLEL DO directive must follow the DO loop associated with the loop construct
+ !$omp end parallel do
+ !$omp parallel do private(c)
+ do i = 1, N
+ do j = 1, N
+ !ERROR: A DO loop must follow the PARALLEL DO directive
+ !$omp parallel do shared(b)
+ a = 3.14
+ enddo
+ !ERROR: The END PARALLEL DO directive must follow the DO loop associated with the loop construct
+ !$omp end parallel do
+ enddo
+ a = 1.414
+ !ERROR: The END PARALLEL DO directive must follow the DO loop associated with the loop construct
+ !$omp end parallel do
+
+ do i = 1, N
+ !$omp parallel do
+ do j = 2*i*N, (2*i+1)*N
+ a = 3.14
+ enddo
+ enddo
+ !ERROR: The END PARALLEL DO directive must follow the DO loop associated with the loop construct
+ !$omp end parallel do
+
+ !ERROR: A DO loop must follow the PARALLEL DO directive
+ !$omp parallel do private(c)
+5 FORMAT (1PE12.4, I10)
+ do i=1, N
+ a = 3.14
+ enddo
+ !ERROR: The END PARALLEL DO directive must follow the DO loop associated with the loop construct
+ !$omp end parallel do
+
+ !$omp parallel do simd
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel do simd
+ !ERROR: The END PARALLEL DO SIMD directive must follow the DO loop associated with the loop construct
+ !$omp end parallel do simd
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/loop-simd01.f90 b/flang/test/SemanticsChecked/OpenMP/loop-simd01.f90
new file mode 100644
index 0000000000000..18878645c0c6f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/loop-simd01.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 4.5
+! 2.8.3 Loop simd Construct
+! Semantic error for correct test case.
+
+program omp_loop_simd
+ integer i, j, k, l
+ k = 0;
+ l = 0
+
+ !$omp parallel do simd linear(l)
+ do i = 1, 10
+ do j = 1, 10
+ print *, "omp loop simd"
+ k = k + 1
+ l = l + 1
+ end do
+ end do
+
+ print *, k, l
+
+end program omp_loop_simd
diff --git a/flang/test/SemanticsChecked/OpenMP/map-clause.f90 b/flang/test/SemanticsChecked/OpenMP/map-clause.f90
new file mode 100644
index 0000000000000..a7430c3edeb94
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/map-clause.f90
@@ -0,0 +1,35 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! Check OpenMP MAP clause validity. Section 5.8.3 OpenMP 5.2.
+
+subroutine sb(arr)
+ implicit none
+ real(8) :: arr(*)
+ real :: a
+ integer:: b, c, i
+ common /var/ b, c
+
+ !ERROR: Assumed-size whole arrays may not appear on the MAP clause
+ !$omp target map(arr)
+ do i = 1, 100
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !ERROR: Assumed-size array 'arr' must have explicit final subscript upper bound value
+ !$omp target map(arr(:))
+ do i = 1, 100
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !$omp target map(arr(3:5))
+ do i = 1, 100
+ a = 3.14
+ enddo
+ !$omp end target
+
+ !$omp target map(tofrom: /var/)
+ b = 1
+ c = 2
+ !$omp end target
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/modfile-threadprivate.f90 b/flang/test/SemanticsChecked/OpenMP/modfile-threadprivate.f90
new file mode 100644
index 0000000000000..74147c0494a54
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/modfile-threadprivate.f90
@@ -0,0 +1,35 @@
+! RUN: %python %S/../test_modfile.py %s %flang_fc1 -fopenmp
+! Check correct modfile generation for OpenMP threadprivate directive.
+
+module m
+ implicit none
+ type :: my_type(kind_param, len_param)
+ integer, KIND :: kind_param
+ integer, LEN :: len_param
+ integer :: t_i
+ integer :: t_arr(10)
+ end type
+ type(my_type(kind_param=2, len_param=4)) :: t
+ real, dimension(3) :: thrtest
+ real :: x
+ common /blk/ x
+
+ !$omp threadprivate(thrtest, t, /blk/)
+end
+
+!Expect: m.mod
+!module m
+!type::my_type(kind_param,len_param)
+!integer(4),kind::kind_param
+!integer(4),len::len_param
+!integer(4)::t_i
+!integer(4)::t_arr(1_8:10_8)
+!end type
+!type(my_type(kind_param=2_4,len_param=4_4))::t
+!!$omp threadprivate(t)
+!real(4)::thrtest(1_8:3_8)
+!!$omp threadprivate(thrtest)
+!real(4)::x
+!!$omp threadprivate(x)
+!common/blk/x
+!end
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-barrier.f90 b/flang/test/SemanticsChecked/OpenMP/nested-barrier.f90
new file mode 100644
index 0000000000000..cad31d7985607
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-barrier.f90
@@ -0,0 +1,166 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! Various checks with the nesting of BARRIER construct
+
+program omp_nest_barrier
+ integer i, k, j
+ k = 0;
+
+ !$omp do
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+
+ !$omp do simd
+ do i = 1, 10
+ k = k + 1
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+
+ !$omp parallel do
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+
+ !$omp parallel do simd
+ do i = 1, 10
+ k = k + 1
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+
+ !$omp parallel
+ do i = 1, 10
+ k = k + 1
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end parallel
+
+ !$omp task
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end task
+
+ !$omp taskloop
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end taskloop
+
+ !$omp critical
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end critical
+
+ !$omp master
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end master
+
+ !$omp ordered
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end ordered
+
+ !$omp ordered
+ do i = 1, 10
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end distribute
+ end do
+ !$omp end ordered
+
+ !$omp master
+ do i = 1, 10
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end distribute
+ end do
+ !$omp end master
+
+ !$omp critical
+ do i = 1, 10
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end distribute
+ end do
+ !$omp end critical
+
+ !$omp taskloop
+ do i = 1, 10
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end distribute
+ end do
+ !$omp end taskloop
+
+ !$omp task
+ do i = 1, 10
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !ERROR: `BARRIER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`,`CRITICAL`, `ORDERED`, `ATOMIC` or `MASTER` region.
+ !$omp barrier
+ j = j -1
+ end do
+ !$omp end distribute
+ end do
+ !$omp end task
+
+end program omp_nest_barrier
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-cancel.f90 b/flang/test/SemanticsChecked/OpenMP/nested-cancel.f90
new file mode 100644
index 0000000000000..afd94a591a067
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-cancel.f90
@@ -0,0 +1,249 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 5.0
+! Check OpenMP construct validity for the following directives:
+! 2.18.1 Cancel Construct
+
+program main
+ integer :: i, N = 10
+ real :: a
+
+ !ERROR: CANCEL TASKGROUP directive is not closely nested inside TASK or TASKLOOP
+ !$omp cancel taskgroup
+
+ !ERROR: CANCEL SECTIONS directive is not closely nested inside SECTION or SECTIONS
+ !$omp cancel sections
+
+ !ERROR: CANCEL DO directive is not closely nested inside the construct that matches the DO clause type
+ !$omp cancel do
+
+ !ERROR: CANCEL PARALLEL directive is not closely nested inside the construct that matches the PARALLEL clause type
+ !$omp cancel parallel
+
+ !$omp parallel
+ !$omp sections
+ !$omp cancel sections
+ !$omp section
+ a = 3.14
+ !$omp end sections
+ !$omp end parallel
+
+ !$omp sections
+ !$omp section
+ !$omp cancel sections
+ a = 3.14
+ !$omp end sections
+
+ !$omp parallel
+ !ERROR: With SECTIONS clause, CANCEL construct cannot be closely nested inside PARALLEL construct
+ !$omp cancel sections
+ a = 3.14
+ !$omp end parallel
+
+ !$omp parallel sections
+ !$omp cancel sections
+ a = 3.14
+ !$omp end parallel sections
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end do
+
+ !$omp parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end parallel do
+
+ !$omp target
+ !$omp teams
+ !$omp distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end distribute parallel do
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !$omp teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end teams distribute parallel do
+ !$omp end target
+
+ !$omp target teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end target teams distribute parallel do
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancel do
+ end do
+ !$omp end target parallel do
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !ERROR: With DO clause, CANCEL construct cannot be closely nested inside PARALLEL construct
+ !$omp cancel do
+ end do
+ !$omp end parallel
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancel parallel
+ end do
+ !$omp end parallel
+
+ !$omp target parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancel parallel
+ end do
+ !$omp end target parallel
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCEL construct cannot be closely nested inside TARGET PARALLEL DO construct
+ !$omp cancel parallel
+ end do
+ !$omp end target parallel do
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCEL construct cannot be closely nested inside DO construct
+ !$omp cancel parallel
+ end do
+ !$omp end do
+
+contains
+ subroutine sub1()
+ !$omp task
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+
+ !$omp taskloop
+ do i = 1, N
+ !$omp parallel
+ !$omp end parallel
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+
+ !$omp parallel
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end parallel
+
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp task
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end target parallel
+
+ !$omp parallel
+ !$omp taskloop private(j) nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskloop
+ do i = 1, N
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp taskloop nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCEL construct must be closely nested inside TASK or TASKLOOP construct and CANCEL region must be closely nested inside TASKGROUP region
+ !$omp cancel taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end target parallel
+ end subroutine sub1
+
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-cancellation-point.f90 b/flang/test/SemanticsChecked/OpenMP/nested-cancellation-point.f90
new file mode 100644
index 0000000000000..5392a31b23312
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-cancellation-point.f90
@@ -0,0 +1,249 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 5.0
+! Check OpenMP construct validity for the following directives:
+! 2.18.2 Cancellation Point Construct
+
+program main
+ integer :: i, N = 10
+ real :: a
+
+ !ERROR: CANCELLATION POINT TASKGROUP directive is not closely nested inside TASK or TASKLOOP
+ !$omp cancellation point taskgroup
+
+ !ERROR: CANCELLATION POINT SECTIONS directive is not closely nested inside SECTION or SECTIONS
+ !$omp cancellation point sections
+
+ !ERROR: CANCELLATION POINT DO directive is not closely nested inside the construct that matches the DO clause type
+ !$omp cancellation point do
+
+ !ERROR: CANCELLATION POINT PARALLEL directive is not closely nested inside the construct that matches the PARALLEL clause type
+ !$omp cancellation point parallel
+
+ !$omp parallel
+ !$omp sections
+ !$omp cancellation point sections
+ !$omp section
+ a = 3.14
+ !$omp end sections
+ !$omp end parallel
+
+ !$omp sections
+ !$omp section
+ !$omp cancellation point sections
+ a = 3.14
+ !$omp end sections
+
+ !$omp parallel
+ !ERROR: With SECTIONS clause, CANCELLATION POINT construct cannot be closely nested inside PARALLEL construct
+ !$omp cancellation point sections
+ a = 3.14
+ !$omp end parallel
+
+ !$omp parallel sections
+ !$omp cancellation point sections
+ a = 3.14
+ !$omp end parallel sections
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end do
+
+ !$omp parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end parallel do
+
+ !$omp target
+ !$omp teams
+ !$omp distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end distribute parallel do
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !$omp teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end teams distribute parallel do
+ !$omp end target
+
+ !$omp target teams distribute parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end target teams distribute parallel do
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point do
+ end do
+ !$omp end target parallel do
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !ERROR: With DO clause, CANCELLATION POINT construct cannot be closely nested inside PARALLEL construct
+ !$omp cancellation point do
+ end do
+ !$omp end parallel
+
+ !$omp parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point parallel
+ end do
+ !$omp end parallel
+
+ !$omp target parallel
+ do i = 1, N
+ a = 3.14
+ !$omp cancellation point parallel
+ end do
+ !$omp end target parallel
+
+ !$omp target parallel do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCELLATION POINT construct cannot be closely nested inside TARGET PARALLEL DO construct
+ !$omp cancellation point parallel
+ end do
+ !$omp end target parallel do
+
+ !$omp do
+ do i = 1, N
+ a = 3.14
+ !ERROR: With PARALLEL clause, CANCELLATION POINT construct cannot be closely nested inside DO construct
+ !$omp cancellation point parallel
+ end do
+ !$omp end do
+
+contains
+ subroutine sub1()
+ !$omp task
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+
+ !$omp taskloop
+ do i = 1, N
+ !$omp parallel
+ !$omp end parallel
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+
+ !$omp parallel
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end parallel
+
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp task
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp do
+ do i = 1, N
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp task
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ !$omp end task
+ !$omp end target parallel
+
+ !$omp parallel
+ !$omp taskloop private(j) nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskloop
+ do i = 1, N
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp taskgroup
+ !$omp taskloop nogroup
+ do i = 1, N
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !$omp target parallel
+ !$omp taskloop nogroup
+ do i = 1, N
+ !ERROR: With TASKGROUP clause, CANCELLATION POINT construct must be closely nested inside TASK or TASKLOOP construct and CANCELLATION POINT region must be closely nested inside TASKGROUP region
+ !$omp cancellation point taskgroup
+ a = 3.14
+ end do
+ !$omp end taskloop
+ !$omp end target parallel
+ end subroutine sub1
+
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-distribute.f90 b/flang/test/SemanticsChecked/OpenMP/nested-distribute.f90
new file mode 100644
index 0000000000000..ba8c3bf04b337
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-distribute.f90
@@ -0,0 +1,111 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! Check OpenMP clause validity for the following directives:
+! 2.10 Device constructs
+program main
+
+ real(8) :: arrayA(256), arrayB(256)
+ integer :: N
+
+ arrayA = 1.414
+ arrayB = 3.14
+ N = 256
+
+ !$omp task
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end task
+
+ !$omp teams
+ do i = 1, N
+ !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
+ !$omp task
+ do k = 1, N
+ a = 3.14
+ enddo
+ !$omp end task
+ enddo
+ !$omp end teams
+
+ !$omp teams
+ do i = 1, N
+ !$omp parallel
+ do k = 1, N
+ a = 3.14
+ enddo
+ !$omp end parallel
+ enddo
+ !$omp end teams
+
+ !$omp parallel
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do i = 1, N
+ a = 3.14
+ enddo
+ !$omp end distribute
+ !$omp end parallel
+
+ !$omp teams
+ !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
+ !$omp target
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end target
+ !$omp end teams
+
+ !$omp teams
+ !$omp parallel
+ do k = 1,10
+ print *, "hello"
+ end do
+ !$omp end parallel
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end teams
+
+ !$omp target teams
+ !$omp distribute
+ do i = 1, 10
+ end do
+ !$omp end distribute
+ !$omp end target teams
+
+ !$omp teams
+ !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
+ !$omp task
+ do k = 1,10
+ print *, "hello"
+ end do
+ !$omp end task
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end teams
+
+ !$omp task
+ !$omp parallel
+ do k = 1,10
+ print *, "hello"
+ end do
+ !$omp end parallel
+ !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
+ !$omp distribute firstprivate(a)
+ do i = 1, 10
+ j = j + 1
+ end do
+ !$omp end distribute
+ !$omp end task
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-master.f90 b/flang/test/SemanticsChecked/OpenMP/nested-master.f90
new file mode 100644
index 0000000000000..ef7d2cef6f88a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-master.f90
@@ -0,0 +1,153 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! Various checks with the nesting of MASTER construct
+
+program omp_nest_master
+ integer i, k, j
+ k = 0;
+
+ !$omp do
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+
+ !$omp sections
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end master
+ !$omp end sections
+
+ !$omp single
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end master
+ !$omp end single
+
+
+
+ !$omp task
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end task
+
+ !$omp taskloop
+ do i = 1, 10
+ k = k + 1
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end taskloop
+
+ !$omp target parallel do simd
+ do i = 1, 10
+ k = k + 1
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end target parallel do simd
+
+ !$omp critical
+ do i = 1, 10
+ k = k + 1
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end critical
+
+ !$omp ordered
+ do i = 1, 10
+ k = k + 1
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end ordered
+
+ !$omp ordered
+ do i = 1, 10
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end distribute
+ !$omp end teams
+ end do
+ !$omp end ordered
+
+ !$omp critical
+ do i = 1, 10
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end distribute
+ !$omp end teams
+ end do
+ !$omp end critical
+
+ !$omp taskloop
+ do i = 1, 10
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end distribute
+ !$omp end teams
+ end do
+ !$omp end taskloop
+
+ !$omp task
+ do i = 1, 10
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ !$omp distribute
+ do k =1, 10
+ print *, "hello"
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$omp master
+ j = j -1
+ !$omp end master
+ end do
+ !$omp end distribute
+ !$omp end teams
+ end do
+ !$omp end task
+
+end program omp_nest_master
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-simd.f90 b/flang/test/SemanticsChecked/OpenMP/nested-simd.f90
new file mode 100644
index 0000000000000..4149b6d97e9dc
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-simd.f90
@@ -0,0 +1,191 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! Various checks with the nesting of SIMD construct
+
+SUBROUTINE NESTED_GOOD(N)
+ INTEGER N, I, J, K, A(10), B(10)
+ !$OMP SIMD
+ DO I = 1,N
+ !$OMP ATOMIC
+ K = K + 1
+ IF (I <= 10) THEN
+ !$OMP ORDERED SIMD
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END ORDERED
+ ENDIF
+ END DO
+ !$OMP END SIMD
+
+ !$OMP SIMD
+ DO I = 1,N
+ IF (I <= 10) THEN
+ !$OMP SIMD
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END SIMD
+ ENDIF
+ END DO
+ !$OMP END SIMD
+END SUBROUTINE NESTED_GOOD
+
+SUBROUTINE NESTED_BAD(N)
+ INTEGER N, I, J, K, A(10), B(10)
+
+ !$OMP SIMD
+ DO I = 1,N
+ IF (I <= 10) THEN
+ !$OMP ORDERED SIMD
+ DO J = 1,N
+ print *, "Hi"
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ DO K = 1,N
+ print *, 'Hello'
+ END DO
+ !$omp end teams
+ END DO
+ !$OMP END ORDERED
+ ENDIF
+ END DO
+ !$OMP END SIMD
+
+ !$OMP SIMD
+ DO I = 1,N
+ !$OMP ATOMIC
+ K = K + 1
+ IF (I <= 10) THEN
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp task
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end task
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp target
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end target
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$OMP DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END DO
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$OMP PARALLEL DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END PARALLEL DO
+ ENDIF
+ END DO
+ !$OMP END SIMD
+
+ !$OMP DO SIMD
+ DO I = 1,N
+ !$OMP ATOMIC
+ K = K + 1
+ IF (I <= 10) THEN
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp task
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end task
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp target
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end target
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$OMP DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END DO
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$OMP PARALLEL DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END PARALLEL DO
+ ENDIF
+ END DO
+ !$OMP END DO SIMD
+
+ !$OMP PARALLEL DO SIMD
+ DO I = 1,N
+ !$OMP ATOMIC
+ K = K + 1
+ IF (I <= 10) THEN
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp task
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end task
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp target
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end target
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$OMP DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END DO
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$OMP PARALLEL DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END PARALLEL DO
+ ENDIF
+ END DO
+ !$OMP END PARALLEL DO SIMD
+
+ !$OMP TARGET SIMD
+ DO I = 1,N
+ !$OMP ATOMIC
+ K = K + 1
+ IF (I <= 10) THEN
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp task
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end task
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$omp target
+ do J = 1, N
+ K = 2
+ end do
+ !$omp end target
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$OMP DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END DO
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !$OMP PARALLEL DO
+ DO J = 1,N
+ A(J) = J
+ END DO
+ !$OMP END PARALLEL DO
+ ENDIF
+ END DO
+ !$OMP END TARGET SIMD
+
+
+END SUBROUTINE NESTED_BAD
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-target.f90 b/flang/test/SemanticsChecked/OpenMP/nested-target.f90
new file mode 100644
index 0000000000000..2267f70715d3e
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-target.f90
@@ -0,0 +1,53 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror -pedantic
+
+! OpenMP Version 5.0
+! Check OpenMP construct validity for the following directives:
+! 2.12.5 Target Construct
+
+program main
+ integer :: i, j, N = 10
+ real :: a, arrayA(512), arrayB(512), ai(10)
+ real, allocatable :: B(:)
+
+ !$omp target
+ !PORTABILITY: If TARGET UPDATE directive is nested inside TARGET region, the behaviour is unspecified
+ !$omp target update from(arrayA) to(arrayB)
+ do i = 1, 512
+ arrayA(i) = arrayB(i)
+ end do
+ !$omp end target
+
+ !$omp parallel
+ !$omp target
+ !$omp parallel
+ !PORTABILITY: If TARGET UPDATE directive is nested inside TARGET region, the behaviour is unspecified
+ !$omp target update from(arrayA) to(arrayB)
+ do i = 1, 512
+ arrayA(i) = arrayB(i)
+ end do
+ !$omp end parallel
+ !$omp end target
+ !$omp end parallel
+
+ !$omp target
+ !PORTABILITY: If TARGET DATA directive is nested inside TARGET region, the behaviour is unspecified
+ !$omp target data map(to: a)
+ do i = 1, N
+ a = 3.14
+ end do
+ !$omp end target data
+ !$omp end target
+
+ allocate(B(N))
+ !$omp target
+ !PORTABILITY: If TARGET ENTER DATA directive is nested inside TARGET region, the behaviour is unspecified
+ !$omp target enter data map(alloc:B)
+ !$omp end target
+
+ !$omp target
+ !PORTABILITY: If TARGET EXIT DATA directive is nested inside TARGET region, the behaviour is unspecified
+ !$omp target exit data map(delete:B)
+ !$omp end target
+ deallocate(B)
+
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/nested-teams.f90 b/flang/test/SemanticsChecked/OpenMP/nested-teams.f90
new file mode 100644
index 0000000000000..80c59e07fbaa6
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested-teams.f90
@@ -0,0 +1,112 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 5.0
+! Check OpenMP construct validity for the following directives:
+! 2.7 Teams Construct
+
+program main
+ integer :: i, j, N = 10
+ real :: a, b, c
+
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+
+ !$omp target
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end target
+
+ !$omp target
+ !$omp parallel
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end parallel
+ !$omp end target
+
+ !$omp parallel
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end parallel
+
+ !$omp do
+ do i = 1, N
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ end do
+
+ !$omp master
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end master
+
+ !$omp target parallel
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end target parallel
+
+ !$omp target
+ !$omp teams
+ !ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end teams
+ !$omp end target
+
+ !$omp target teams
+ !ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end target teams
+
+ !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct
+ !$omp target
+ do i = 1, N
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ enddo
+ !$omp end target
+
+ !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct
+ !$omp target
+ if (i .GT. 1) then
+ if (j .GT. 1) then
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ end if
+ end if
+ !$omp end target
+
+ !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct
+ !$omp target
+ b = 3.14
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ !$omp end target
+
+ !ERROR: TARGET construct with nested TEAMS region contains statements or directives outside of the TEAMS construct
+ !$omp target
+ !$omp teams
+ a = 3.14
+ !$omp end teams
+ c = 3.14
+ !$omp end target
+
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/nested01.f90 b/flang/test/SemanticsChecked/OpenMP/nested01.f90
new file mode 100644
index 0000000000000..49c964ab86aa6
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nested01.f90
@@ -0,0 +1,40 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! Check OpenMP 2.17 Nesting of Regions
+
+ N = 1024
+ !$omp do
+ do i = 1, N
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+
+ !$omp do
+ do i = 1, N
+ !$omp target
+ do k = 1,N
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end target
+ enddo
+
+
+ !$omp do
+ do i = 1, N
+ !$omp parallel
+ do k = 1,N
+ !$omp do
+ do j = 1, N
+ a = 3.14
+ enddo
+ enddo
+ !$omp end parallel
+ enddo
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/no-dowhile-in-parallel.f90 b/flang/test/SemanticsChecked/OpenMP/no-dowhile-in-parallel.f90
new file mode 100644
index 0000000000000..fb864fd32ef00
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/no-dowhile-in-parallel.f90
@@ -0,0 +1,28 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+subroutine bug48308(x,i)
+ real :: x(:)
+ integer :: i
+ !$omp parallel firstprivate(i)
+ do while (i>0)
+ x(i) = i
+ i = i - 1
+ end do
+ !$omp end parallel
+end subroutine
+
+subroutine s1(x,i)
+ real :: x(:)
+ integer :: i
+ !$omp parallel firstprivate(i)
+ do i = 10, 1, -1
+ x(i) = i
+ end do
+ !$omp end parallel
+
+ !$omp parallel firstprivate(i)
+ do concurrent (i = 1:10:1)
+ x(i) = i
+ end do
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/nontemporal.f90 b/flang/test/SemanticsChecked/OpenMP/nontemporal.f90
new file mode 100644
index 0000000000000..6d24849575ee9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/nontemporal.f90
@@ -0,0 +1,95 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! REQUIRES: shell
+! Check OpenMP clause validity for NONTEMPORAL clause
+
+program omp_simd
+ integer i
+ integer, allocatable :: a(:)
+
+ allocate(a(10))
+
+ !$omp simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ !$omp parallel do simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end parallel do simd
+
+ !$omp parallel do simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end parallel do simd
+
+ !ERROR: NONTEMPORAL clause is not allowed on the DO SIMD directive
+ !$omp do simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end do simd
+
+ !$omp taskloop simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end taskloop simd
+
+ !$omp teams
+ !$omp distribute parallel do simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end distribute parallel do simd
+ !$omp end teams
+
+ !$omp teams
+ !$omp distribute simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end distribute simd
+ !$omp end teams
+
+ !$omp target parallel do simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end target parallel do simd
+
+ !$omp target simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end target simd
+
+ !$omp teams distribute simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end teams distribute simd
+
+ !$omp teams distribute parallel do simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end teams distribute parallel do simd
+
+ !$omp target teams distribute parallel do simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end target teams distribute parallel do simd
+
+ !$omp target teams distribute simd nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end target teams distribute simd
+
+
+end program omp_simd
diff --git a/flang/test/SemanticsChecked/OpenMP/omp-atomic-assignment-stmt.f90 b/flang/test/SemanticsChecked/OpenMP/omp-atomic-assignment-stmt.f90
new file mode 100644
index 0000000000000..a346056dee383
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/omp-atomic-assignment-stmt.f90
@@ -0,0 +1,87 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! Semantic checks for various assignments related to atomic constructs
+
+program sample
+ use omp_lib
+ integer :: x, v
+ integer :: y(10)
+ integer, allocatable :: k
+ integer a(10)
+ type sample_type
+ integer :: y
+ integer :: m
+ endtype
+ type(sample_type) :: z
+ !$omp atomic read
+ v = x
+
+ !$omp atomic read
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar INTEGER(4) and rank 1 array of INTEGER(4)
+ !ERROR: Expected scalar expression on the RHS of atomic assignment statement
+ v = y(1:3)
+
+ !$omp atomic read
+ !ERROR: Expected scalar variable of intrinsic type on RHS of atomic assignment statement
+ v = x * (10 + x)
+
+ !$omp atomic read
+ !ERROR: Expected scalar variable of intrinsic type on RHS of atomic assignment statement
+ v = 4
+
+ !$omp atomic read
+ !ERROR: k must not have ALLOCATABLE attribute
+ v = k
+
+ !$omp atomic write
+ !ERROR: k must not have ALLOCATABLE attribute
+ k = x
+
+ !$omp atomic update
+ !ERROR: k must not have ALLOCATABLE attribute
+ k = k + x * (v * x)
+
+ !$omp atomic
+ !ERROR: k must not have ALLOCATABLE attribute
+ k = v * k
+
+ !$omp atomic write
+ !ERROR: RHS expression on atomic assignment statement cannot access 'z%y'
+ z%y = x + z%y
+
+ !$omp atomic write
+ !ERROR: RHS expression on atomic assignment statement cannot access 'x'
+ x = x
+
+ !$omp atomic write
+ !ERROR: RHS expression on atomic assignment statement cannot access 'm'
+ m = min(m, x, z%m) + k
+
+ !$omp atomic read
+ !ERROR: RHS expression on atomic assignment statement cannot access 'x'
+ x = x
+
+ !$omp atomic read
+ !ERROR: Expected scalar variable of intrinsic type on RHS of atomic assignment statement
+ !ERROR: RHS expression on atomic assignment statement cannot access 'm'
+ m = min(m, x, z%m) + k
+
+ !$omp atomic read
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar INTEGER(4) and rank 1 array of INTEGER(4)
+ !ERROR: Expected scalar expression on the RHS of atomic assignment statement
+ x = a
+
+ !$omp atomic read
+ !ERROR: Expected scalar variable on the LHS of atomic assignment statement
+ a = x
+
+ !$omp atomic write
+ !ERROR: No intrinsic or user-defined ASSIGNMENT(=) matches scalar INTEGER(4) and rank 1 array of INTEGER(4)
+ !ERROR: Expected scalar expression on the RHS of atomic assignment statement
+ x = a
+
+ !$omp atomic write
+ !ERROR: Expected scalar variable on the LHS of atomic assignment statement
+ a = x
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/omp-do-collapse1.f90 b/flang/test/SemanticsChecked/OpenMP/omp-do-collapse1.f90
new file mode 100644
index 0000000000000..81f87d8239e53
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/omp-do-collapse1.f90
@@ -0,0 +1,14 @@
+! RUN: not %flang_fc1 -fdebug-unparse-with-symbols -fopenmp %s 2>&1 | FileCheck %s
+! OpenMP Version 4.5
+! 2.7.1 Loop Construct
+program omp_doCollapse
+ integer:: i
+ !$omp parallel do collapse(2)
+ do i = 1, 3
+ !CHECK: Loop control is not present in the DO LOOP
+ !CHECK: associated with the enclosing LOOP construct
+ do
+ end do
+ end do
+end program omp_doCollapse
+
diff --git a/flang/test/SemanticsChecked/OpenMP/order-clause01.f90 b/flang/test/SemanticsChecked/OpenMP/order-clause01.f90
new file mode 100644
index 0000000000000..247791fac15b4
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/order-clause01.f90
@@ -0,0 +1,10 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+subroutine omp_order()
+ integer :: i, j = 1
+ !ERROR: At most one ORDER clause can appear on the SIMD directive
+ !$omp simd order(concurrent) order(concurrent)
+ do i=1,10
+ j = j + 1
+ end do
+end subroutine omp_order
diff --git a/flang/test/SemanticsChecked/OpenMP/ordered-simd.f90 b/flang/test/SemanticsChecked/OpenMP/ordered-simd.f90
new file mode 100644
index 0000000000000..c33ec745f2dda
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/ordered-simd.f90
@@ -0,0 +1,148 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! Various checks with the ordered construct
+
+SUBROUTINE WORK(I)
+ INTEGER I
+END SUBROUTINE WORK
+
+SUBROUTINE ORDERED_GOOD(N)
+ INTEGER N, I, A(10), B(10), C(10)
+ !$OMP SIMD
+ DO I = 1,N
+ IF (I <= 10) THEN
+ !$OMP ORDERED SIMD
+ CALL WORK(I)
+ !$OMP END ORDERED
+ ENDIF
+ END DO
+ !$OMP END SIMD
+END SUBROUTINE ORDERED_GOOD
+
+SUBROUTINE ORDERED_BAD(N)
+ INTEGER N, I, A(10), B(10), C(10)
+
+ !$OMP DO SIMD
+ DO I = 1,N
+ IF (I <= 10) THEN
+ !ERROR: The only OpenMP constructs that can be encountered during execution of a 'SIMD' region are the `ATOMIC` construct, the `LOOP` construct, the `SIMD` construct and the `ORDERED` construct with the `SIMD` clause.
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ ENDIF
+ END DO
+ !$OMP END DO SIMD
+
+ !$OMP PARALLEL DO
+ DO I = 1,N
+ IF (I <= 10) THEN
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ ENDIF
+ END DO
+ !$OMP END PARALLEL DO
+
+ !$OMP CRITICAL
+ DO I = 1,N
+ IF (I <= 10) THEN
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ ENDIF
+ END DO
+ !$OMP END CRITICAL
+
+ !$OMP CRITICAL
+ WRITE(*,*) I
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ !$OMP END CRITICAL
+
+ !$OMP ORDERED
+ WRITE(*,*) I
+ IF (I <= 10) THEN
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ ENDIF
+ !$OMP END ORDERED
+
+ !$OMP TASK
+ C = C - A * B
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ !$OMP END TASK
+
+ !$OMP TASKLOOP
+ DO I = 1,N
+ IF (I <= 10) THEN
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ ENDIF
+ END DO
+ !$OMP END TASKLOOP
+
+ !$OMP CRITICAL
+ C = C - A * B
+ !$OMP MASTER
+ DO I = 1,N
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ END DO
+ !$OMP END MASTER
+ !$OMP END CRITICAL
+
+ !$OMP ORDERED
+ C = C - A * B
+ !$OMP MASTER
+ DO I = 1,N
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ END DO
+ !$OMP END MASTER
+ !$OMP END ORDERED
+
+ !$OMP TASK
+ C = C - A * B
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$OMP MASTER
+ DO I = 1,N
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ END DO
+ !$OMP END MASTER
+ !$OMP END TASK
+
+ !$OMP TASKLOOP
+ DO J= 1,N
+ C = C - A * B
+ !ERROR: `MASTER` region may not be closely nested inside of `WORKSHARING`, `LOOP`, `TASK`, `TASKLOOP`, or `ATOMIC` region.
+ !$OMP MASTER
+ DO I = 1,N
+ !ERROR: `ORDERED` region may not be closely nested inside of `CRITICAL`, `ORDERED`, explicit `TASK` or `TASKLOOP` region.
+ !$OMP ORDERED
+ CALL WORK(I)
+ !$OMP END ORDERED
+ END DO
+ !$OMP END MASTER
+ END DO
+ !$OMP END TASKLOOP
+
+END SUBROUTINE ORDERED_BAD
diff --git a/flang/test/SemanticsChecked/OpenMP/ordered01.f90 b/flang/test/SemanticsChecked/OpenMP/ordered01.f90
new file mode 100644
index 0000000000000..9433120fab10f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/ordered01.f90
@@ -0,0 +1,80 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.19.9 Ordered Construct
+
+program main
+ integer :: i, N = 10
+ real :: a, arrayA(10), arrayB(10), arrayC(10)
+ real, external :: foo, bar, baz
+
+ !$omp do ordered
+ do i = 1, N
+ !ERROR: At most one THREADS clause can appear on the ORDERED directive
+ !$omp ordered threads threads
+ arrayA(i) = i
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp simd
+ do i = 1, N
+ !ERROR: At most one SIMD clause can appear on the ORDERED directive
+ !$omp ordered simd simd
+ arrayA(i) = i
+ !$omp end ordered
+ end do
+ !$omp end simd
+
+ !$omp do simd ordered
+ do i = 1, N
+ !ERROR: At most one SIMD clause can appear on the ORDERED directive
+ !$omp ordered simd simd
+ arrayA(i) = i
+ !$omp end ordered
+ end do
+ !$omp end do simd
+
+ !$omp do ordered(1)
+ do i = 2, N
+ !ERROR: Only DEPEND(SOURCE) or DEPEND(SINK: vec) are allowed when ORDERED construct is a standalone construct with no ORDERED region
+ !ERROR: At most one DEPEND(SOURCE) clause can appear on the ORDERED directive
+ !$omp ordered depend(source) depend(inout: arrayA) depend(source)
+ arrayA(i) = foo(i)
+ !ERROR: DEPEND(SOURCE) is not allowed when DEPEND(SINK: vec) is present on ORDERED directive
+ !ERROR: DEPEND(SOURCE) is not allowed when DEPEND(SINK: vec) is present on ORDERED directive
+ !ERROR: At most one DEPEND(SOURCE) clause can appear on the ORDERED directive
+ !$omp ordered depend(sink: i - 1) depend(source) depend(source)
+ arrayB(i) = bar(arrayA(i), arrayB(i-1))
+ !ERROR: Only DEPEND(SOURCE) or DEPEND(SINK: vec) are allowed when ORDERED construct is a standalone construct with no ORDERED region
+ !ERROR: Only DEPEND(SOURCE) or DEPEND(SINK: vec) are allowed when ORDERED construct is a standalone construct with no ORDERED region
+ !$omp ordered depend(out: arrayC) depend(in: arrayB)
+ arrayC(i) = baz(arrayB(i-1))
+ end do
+ !$omp end do
+
+ !$omp do ordered(1)
+ do i = 2, N
+ !ERROR: DEPEND(*) clauses are not allowed when ORDERED construct is a block construct with an ORDERED region
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ !ERROR: DEPEND(*) clauses are not allowed when ORDERED construct is a block construct with an ORDERED region
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(arrayA(i), arrayB(i-1))
+ !$omp end ordered
+ end do
+ !$omp end do
+
+contains
+ subroutine work1()
+ !ERROR: THREADS, SIMD clauses are not allowed when ORDERED construct is a standalone construct with no ORDERED region
+ !$omp ordered simd
+ end subroutine work1
+
+ subroutine work2()
+ !ERROR: THREADS, SIMD clauses are not allowed when ORDERED construct is a standalone construct with no ORDERED region
+ !$omp ordered threads
+ end subroutine work2
+
+end program main
diff --git a/flang/test/SemanticsChecked/OpenMP/ordered02.f90 b/flang/test/SemanticsChecked/OpenMP/ordered02.f90
new file mode 100644
index 0000000000000..ed320c82a9794
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/ordered02.f90
@@ -0,0 +1,146 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.19.9 Ordered Construct
+
+subroutine sub1()
+ integer :: i, j, N = 10
+ real :: arrayA(10), arrayB(10)
+ real, external :: foo, bar
+
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+
+ !$omp ordered threads
+ arrayA(i) = foo(i)
+ !$omp end ordered
+
+ !$omp ordered simd
+ arrayA(i) = foo(i)
+ !$omp end ordered
+
+ !$omp sections
+ do i = 1, N
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end sections
+
+ !$omp do ordered
+ do i = 1, N
+ arrayB(i) = bar(i)
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp sections
+ do i = 1, N
+ !ERROR: An ORDERED directive with SIMD clause must be closely nested in a SIMD or worksharing-loop SIMD region
+ !$omp ordered simd
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end sections
+
+ !$omp do ordered
+ do i = 1, N
+ !$omp parallel
+ do j = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a SIMD, worksharing-loop, or worksharing-loop SIMD region
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end parallel
+ end do
+ !$omp end do
+
+ !$omp do ordered
+ do i = 1, N
+ !$omp target parallel
+ do j = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a SIMD, worksharing-loop, or worksharing-loop SIMD region
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end target parallel
+ end do
+ !$omp end do
+
+ !$omp do
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp do
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered threads
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp do ordered(1)
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp do ordered(1)
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered threads
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end do
+
+ !$omp parallel do ordered(1)
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do ordered(1)
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered threads
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end parallel do
+
+ !$omp target parallel do ordered(1)
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end target parallel do
+
+ !$omp target parallel do ordered(1)
+ do i = 1, N
+ !ERROR: An ORDERED directive without the DEPEND clause must be closely nested in a worksharing-loop (or worksharing-loop SIMD) region with ORDERED clause without the parameter
+ !$omp ordered threads
+ arrayA(i) = foo(i)
+ !$omp end ordered
+ end do
+ !$omp end target parallel do
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/ordered03.f90 b/flang/test/SemanticsChecked/OpenMP/ordered03.f90
new file mode 100644
index 0000000000000..8dd4d035212d8
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/ordered03.f90
@@ -0,0 +1,122 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.19.9 Ordered Construct
+
+subroutine sub1()
+ integer :: i, j, N = 10
+ real :: arrayA(10), arrayB(10)
+ real, external :: foo, bar
+
+ !$omp do ordered(1)
+ do i = 1, N
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end do
+
+ !$omp do ordered(1)
+ do i = 1, N
+ !$omp target
+ do j = 1, N
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end target
+ end do
+ !$omp end do
+
+ !$omp target
+ !$omp parallel do ordered(1)
+ do i = 1, N
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end parallel do
+ !$omp end target
+
+ !$omp target parallel do ordered(1)
+ do i = 1, N
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end target parallel do
+
+ !$omp target teams distribute parallel do ordered(1)
+ do i = 1, N
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end target teams distribute parallel do
+
+ !$omp do ordered
+ do i = 1, N
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end do
+
+ !$omp parallel do ordered
+ do i = 1, N
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end parallel do
+
+ !$omp target parallel do ordered
+ do i = 1, N
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(source)
+ arrayA(i) = foo(i)
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(sink: i - 1)
+ arrayB(i) = bar(i - 1)
+ end do
+ !$omp end target parallel do
+
+ !$omp do ordered(1)
+ do i = 1, N
+ !ERROR: The number of variables in DEPEND(SINK: vec) clause does not match the parameter specified in ORDERED clause
+ !$omp ordered depend(sink: i - 1) depend(sink: i - 1, j)
+ arrayB(i) = bar(i - 1, j)
+ end do
+ !$omp end do
+
+ !$omp do ordered(2)
+ do i = 1, N
+ do j = 1, N
+ !ERROR: The number of variables in DEPEND(SINK: vec) clause does not match the parameter specified in ORDERED clause
+ !$omp ordered depend(sink: i - 1) depend(sink: i - 1, j)
+ arrayB(i) = foo(i - 1) + bar(i - 1, j)
+ end do
+ end do
+ !$omp end do
+
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(source)
+
+ !ERROR: An ORDERED construct with the DEPEND clause must be closely nested in a worksharing-loop (or parallel worksharing-loop) construct with ORDERED clause with a parameter
+ !$omp ordered depend(sink: i - 1)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-critical-do.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-critical-do.f90
new file mode 100644
index 0000000000000..6e10b46dea9a0
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-critical-do.f90
@@ -0,0 +1,18 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! Check that loop iteration variables are private and predetermined, even when
+! nested inside parallel/critical constructs.
+
+!DEF: /test1 (Subroutine) Subprogram
+subroutine test1
+ !DEF: /test1/i ObjectEntity INTEGER(4)
+ integer i
+
+ !$omp parallel default(none)
+ !$omp critical
+ !DEF: /test1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i = 1, 10
+ end do
+ !$omp end critical
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private01.f90
new file mode 100644
index 0000000000000..a3d332c95ed25
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-private01.f90
@@ -0,0 +1,20 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.3 parallel private Clause
+program omp_parallel_private
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ type my_type
+ integer :: array(10)
+ end type my_type
+
+ type(my_type) :: my_var
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause
+ !$omp parallel private(my_var%array)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ my_var%array(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_private
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private02.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private02.f90
new file mode 100644
index 0000000000000..8cb72159d6ab5
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-private02.f90
@@ -0,0 +1,20 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.3 parallel private Clause
+program omp_parallel_private
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ integer :: array(10)
+
+ do i = 1, 10
+ array(i) = i
+ end do
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause
+ !$omp parallel private(array(i))
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ array(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_private
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private03.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private03.f90
new file mode 100644
index 0000000000000..24a096302e53d
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-private03.f90
@@ -0,0 +1,28 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.3 parallel private Clause
+program omp_parallel_private
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ type my_type
+ integer :: array(10)
+ end type my_type
+
+ type(my_type) :: my_var
+
+ real :: arr(10)
+ integer :: intx = 10
+
+ do i = 1, 10
+ arr(i) = 0.0
+ end do
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause
+ !$omp parallel private(arr(i),intx)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ my_var%array(i) = k+intx
+ arr(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_private
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-private04.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-private04.f90
new file mode 100644
index 0000000000000..67a669c9882a5
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-private04.f90
@@ -0,0 +1,28 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.3 parallel private Clause
+program omp_parallel_private
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ type my_type
+ integer :: array(10)
+ end type my_type
+
+ type(my_type) :: my_var
+
+ real :: arr(10)
+ integer :: intx = 10
+
+ do i = 1, 10
+ arr(i) = 0.0
+ end do
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause
+ !$omp parallel private(arr,intx,my_var%array(1))
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ my_var%array(i) = k+intx
+ arr(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_private
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-sections-do.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-sections-do.f90
new file mode 100644
index 0000000000000..39102175299ba
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-sections-do.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! Check that loop iteration variables are private and predetermined, even when
+! nested inside parallel/sections constructs.
+
+!DEF: /test1 (Subroutine) Subprogram
+subroutine test1
+ !DEF: /test1/i ObjectEntity INTEGER(4)
+ integer i
+
+ !$omp parallel default(none)
+ !$omp sections
+ !$omp section
+ !DEF: /test1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i = 1, 10
+ end do
+ !$omp end sections
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-sections01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-sections01.f90
new file mode 100644
index 0000000000000..6c5a053bf49c9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-sections01.f90
@@ -0,0 +1,155 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
+! OpenMP version 5.0.0
+! 2.13.3 parallel sections Construct
+! The restrictions for the parallel construct and the sections construct apply
+program OmpConstructSections01
+ use omp_lib
+ integer :: section_count = 0
+ integer, parameter :: NT = 4
+ integer :: i, array(10)
+ type my_type
+ integer :: array(10)
+ end type my_type
+ type(my_type) :: my_var
+ print *, 'section_count', section_count
+ do i = 1, 10
+ array(i) = i
+ end do
+!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause
+!$omp parallel sections shared(array(i))
+!$omp end parallel sections
+!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause
+!$omp parallel sections shared(my_var%array)
+!$omp end parallel sections
+
+!ERROR: invalid branch into an OpenMP structured block
+!ERROR: invalid branch into an OpenMP structured block
+!ERROR: invalid branch into an OpenMP structured block
+ if (NT) 20, 30, 40
+!ERROR: invalid branch into an OpenMP structured block
+ goto 20
+!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause
+!$omp parallel sections private(my_var%array)
+ !$omp section
+ print *, "This is a single statement structured block"
+ !$omp section
+ open (10, file="random-file-name.txt", err=30)
+ !ERROR: invalid branch into an OpenMP structured block
+ !ERROR: invalid branch leaving an OpenMP structured block
+ open (10, file="random-file-name.txt", err=40)
+ !$omp section
+ section_count = section_count + 1
+20 print *, 'Entering into section'
+ call calledFromWithinSection()
+ print *, 'section_count', section_count
+ !$omp section
+ section_count = section_count + 1
+ print *, 'section_count', section_count
+ !ERROR: invalid branch leaving an OpenMP structured block
+ goto 10
+ !$omp section
+30 print *, "Error in opening file"
+!$omp end parallel sections
+10 print *, 'Jump from section'
+!ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a PRIVATE clause
+!$omp parallel sections private(array(i))
+ !$omp section
+40 print *, 'Error in opening file'
+!$omp end parallel sections
+end program OmpConstructSections01
+
+function returnFromSections()
+ !$omp parallel sections
+ !$omp section
+ !ERROR: RETURN statement is not allowed in a PARALLEL SECTIONS construct
+ RETURN
+ !$omp end parallel sections
+end function
+
+subroutine calledFromWithinSection()
+ print *, "I am called from within a 'section' structured block"
+ return
+end subroutine calledFromWithinSection
+
+subroutine continueWithinSections()
+ integer i
+ do i = 1, 10
+ print *, "Statement within loop but outside section construct"
+ !$omp parallel sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: CYCLE to construct outside of PARALLEL SECTIONS construct is not allowed
+ CYCLE
+ END IF
+ !$omp end parallel sections
+ print *, "Statement within loop but outside section contruct"
+ end do
+
+ !$omp parallel sections
+ !$omp section
+ do i = 1, 10
+ CYCLE
+ end do
+ !$omp end parallel sections
+
+ !$omp parallel sections
+ !$omp section
+ loop_1: do i = 1, 10
+ IF (i .EQ. 5) THEN
+ CYCLE loop_1
+ END IF
+ end do loop_1
+ !$omp end parallel sections
+
+ loop_2: do i = 1, 10
+ !$omp parallel sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: CYCLE to construct 'loop_2' outside of PARALLEL SECTIONS construct is not allowed
+ CYCLE loop_2
+ END IF
+ !$omp end parallel sections
+ end do loop_2
+end subroutine continueWithinSections
+
+subroutine breakWithinSections()
+ loop_3: do i = 1, 10
+ !$omp parallel sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: EXIT to construct 'loop_3' outside of PARALLEL SECTIONS construct is not allowed
+ EXIT loop_3
+ END IF
+ !$omp end parallel sections
+ end do loop_3
+
+ loop_4: do i = 1, 10
+ !$omp parallel sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: EXIT to construct outside of PARALLEL SECTIONS construct is not allowed
+ EXIT
+ END IF
+ !$omp end parallel sections
+ end do loop_4
+
+ !$omp parallel sections
+ !$omp section
+ do i = 1, 10
+ IF (i .EQ. 5) THEN
+ EXIT
+ END IF
+ end do
+ !$omp end parallel sections
+
+ !$omp parallel sections
+ !$omp section
+ loop_5: do i = 1, 10
+ IF (i .EQ. 5) THEN
+ EXIT loop_5
+ END IF
+ end do loop_5
+ !$omp end parallel sections
+end subroutine breakWithinSections
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared01.f90
new file mode 100644
index 0000000000000..7abfe1f7b1637
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared01.f90
@@ -0,0 +1,20 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.2 parallel shared Clause
+program omp_parallel_shared
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ type my_type
+ integer :: array(10)
+ end type my_type
+
+ type(my_type) :: my_var
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause
+ !$omp parallel shared(my_var%array)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ my_var%array(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_shared
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared02.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared02.f90
new file mode 100644
index 0000000000000..f59f5236dfd93
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared02.f90
@@ -0,0 +1,20 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.2 parallel shared Clause
+program omp_parallel_shared
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ integer :: array(10)
+
+ do i = 1, 10
+ array(i) = i
+ end do
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause
+ !$omp parallel shared(array(i))
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ array(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_shared
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared03.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared03.f90
new file mode 100644
index 0000000000000..3d9111c7aaf10
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared03.f90
@@ -0,0 +1,28 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.2 parallel shared Clause
+program omp_parallel_shared
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ type my_type
+ integer :: array(10)
+ end type my_type
+
+ type(my_type) :: my_var
+
+ real :: arr(10)
+ integer :: intx = 10
+
+ do i = 1, 10
+ arr(i) = 0.0
+ end do
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause
+ !$omp parallel shared(arr(i),intx)
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ my_var%array(i) = k+intx
+ arr(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_shared
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel-shared04.f90 b/flang/test/SemanticsChecked/OpenMP/parallel-shared04.f90
new file mode 100644
index 0000000000000..06b7fcfa01d7a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel-shared04.f90
@@ -0,0 +1,28 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.2 parallel shared Clause
+program omp_parallel_shared
+ integer :: i, j, a(10), b(10), c(10)
+ integer :: k = 10
+ type my_type
+ integer :: array(10)
+ end type my_type
+
+ type(my_type) :: my_var
+
+ real :: arr(10)
+ integer :: intx = 10
+
+ do i = 1, 10
+ arr(i) = 0.0
+ end do
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear in a SHARED clause
+ !$omp parallel shared(arr,intx,my_var%array(1))
+ do i = 1, 10
+ c(i) = a(i) + b(i) + k
+ my_var%array(i) = k+intx
+ arr(i) = k
+ end do
+ !$omp end parallel
+end program omp_parallel_shared
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel01.f90 b/flang/test/SemanticsChecked/OpenMP/parallel01.f90
new file mode 100644
index 0000000000000..6d5dd581a9f23
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel01.f90
@@ -0,0 +1,23 @@
+! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s
+! OpenMP Version 4.5
+! 2.5 parallel construct.
+! A program that branches into or out of a parallel region
+! is non-conforming.
+
+program omp_parallel
+ integer i, j, k
+
+ !$omp parallel
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ !CHECK: invalid branch leaving an OpenMP structured block
+ goto 10
+ end do
+ end do
+ !$omp end parallel
+
+ !CHECK: Outside the enclosing PARALLEL directive
+ 10 stop
+
+end program omp_parallel
diff --git a/flang/test/SemanticsChecked/OpenMP/parallel02.f90 b/flang/test/SemanticsChecked/OpenMP/parallel02.f90
new file mode 100644
index 0000000000000..eff0e7c70d1a0
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/parallel02.f90
@@ -0,0 +1,23 @@
+! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s
+! OpenMP Version 4.5
+! 2.5 parallel construct.
+! A program that branches into or out of a parallel region
+! is non-conforming.
+
+program omp_parallel
+ integer i, j, k
+
+ !CHECK: invalid branch into an OpenMP structured block
+ goto 10
+
+ !$omp parallel
+ do i = 1, 10
+ do j = 1, 10
+ print *, "Hello"
+ !CHECK: In the enclosing PARALLEL directive branched into
+ 10 stop
+ end do
+ end do
+ !$omp end parallel
+
+end program omp_parallel
diff --git a/flang/test/SemanticsChecked/OpenMP/private-is-pointer-allocatable-check.f90 b/flang/test/SemanticsChecked/OpenMP/private-is-pointer-allocatable-check.f90
new file mode 100644
index 0000000000000..7b3915d9a1104
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/private-is-pointer-allocatable-check.f90
@@ -0,0 +1,18 @@
+! RUN: %flang_fc1 -fopenmp -fsyntax-only %s
+
+subroutine s
+ integer, pointer :: p
+ integer, target :: t
+ real(4), allocatable :: arr
+
+ !$omp parallel private(p)
+ p=>t
+ !$omp end parallel
+
+ allocate(arr)
+ !$omp parallel private(arr)
+ if (.not. allocated(arr)) then
+ print *, 'not allocated'
+ endif
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/private01.f90 b/flang/test/SemanticsChecked/OpenMP/private01.f90
new file mode 100644
index 0000000000000..052823a9f78a6
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/private01.f90
@@ -0,0 +1,20 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.3 private Clause
+! Pointers with the INTENT(IN) attribute may not appear in a private clause.
+
+subroutine omp_private(p)
+ integer :: a(10), b(10), c(10)
+ integer, pointer, intent(in) :: p
+
+ a = 10
+ b = 20
+
+ !ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a PRIVATE clause
+ !$omp parallel private(p)
+ c = a + b + p
+ !$omp end parallel
+
+ print *, c
+
+end subroutine omp_private
diff --git a/flang/test/SemanticsChecked/OpenMP/private02.f90 b/flang/test/SemanticsChecked/OpenMP/private02.f90
new file mode 100644
index 0000000000000..a81e31998eebb
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/private02.f90
@@ -0,0 +1,46 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.3 private Clause
+! Variables that appear in namelist statements may not appear in a private clause.
+
+module test
+ integer :: a, b, c
+ namelist /nlist1/ a, b
+end module
+
+program omp_private
+ use test
+
+ integer :: p(10) ,q(10)
+ namelist /nlist2/ c, d
+
+ a = 5
+ b = 10
+ c = 100
+
+ !ERROR: Variable 'a' in NAMELIST cannot be in a PRIVATE clause
+ !ERROR: Variable 'c' in NAMELIST cannot be in a PRIVATE clause
+ !$omp parallel private(a, c)
+ d = a + b
+ !$omp end parallel
+
+ call sb()
+
+ contains
+ subroutine sb()
+ namelist /nlist3/ p, q
+
+ !ERROR: Variable 'p' in NAMELIST cannot be in a PRIVATE clause
+ !ERROR: Variable 'd' in NAMELIST cannot be in a PRIVATE clause
+ !$omp parallel private(p, d)
+ p = c * b
+ q = p * d
+ !$omp end parallel
+
+ write(*, nlist1)
+ write(*, nlist2)
+ write(*, nlist3)
+
+ end subroutine
+
+end program omp_private
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction-subtract.f90 b/flang/test/SemanticsChecked/OpenMP/reduction-subtract.f90
new file mode 100644
index 0000000000000..d4034743a14dc
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction-subtract.f90
@@ -0,0 +1,13 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.2
+! Minus operation is deprecated in reduction
+
+subroutine reduction_subtract
+ integer :: x
+ !ERROR: The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause.
+ !$omp do reduction(-:x)
+ do i=1, 100
+ x = x - i
+ end do
+ !$omp end do
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction01.f90 b/flang/test/SemanticsChecked/OpenMP/reduction01.f90
new file mode 100644
index 0000000000000..0e1a8a571c584
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction01.f90
@@ -0,0 +1,14 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+program omp_reduction
+ integer :: i
+ integer :: k = 10
+
+ !ERROR: Invalid reduction operator in REDUCTION clause.
+ !$omp parallel do reduction(**:k)
+ do i = 1, 10
+ k = k ** 1
+ end do
+ !$omp end parallel do
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction02.f90 b/flang/test/SemanticsChecked/OpenMP/reduction02.f90
new file mode 100644
index 0000000000000..4fd9fbe2d8a53
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction02.f90
@@ -0,0 +1,43 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+program omp_reduction
+
+ integer :: i
+ integer :: k = 10
+ integer :: j = 10
+
+ !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive
+ !$omp parallel do reduction(+:k), reduction(*:k)
+ do i = 1, 10
+ k = k + 1
+ k = k * 3
+ end do
+ !$omp end parallel do
+
+ !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive
+ !$omp parallel do reduction(+:k), reduction(*:j), reduction(+:k)
+ do i = 1, 10
+ k = k + 1
+ j = j * 3
+ end do
+ !$omp end parallel do
+
+ !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive
+ !$omp parallel do reduction(+:j), reduction(*:k), reduction(+:k)
+ do i = 1, 10
+ j = j + 1
+ k = k + 1
+ k = k * 3
+ end do
+ !$omp end parallel do
+
+ !ERROR: 'k' appears in more than one data-sharing clause on the same OpenMP directive
+ !$omp parallel do reduction(+:j), reduction(*:k), private(k)
+ do i = 1, 10
+ j = j + 1
+ k = k + 1
+ k = k * 3
+ end do
+ !$omp end parallel do
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction03.f90 b/flang/test/SemanticsChecked/OpenMP/reduction03.f90
new file mode 100644
index 0000000000000..1ddc2903fecc4
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction03.f90
@@ -0,0 +1,18 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+
+subroutine omp_target(p)
+ integer, pointer, intent(in) :: p
+
+ integer :: i
+ integer :: k = 10
+
+ !ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a REDUCTION clause
+ !$omp parallel do reduction(+:p)
+ do i = 1, 10
+ k= k + 1
+ end do
+ !$omp end parallel do
+
+end subroutine omp_target
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction04.f90 b/flang/test/SemanticsChecked/OpenMP/reduction04.f90
new file mode 100644
index 0000000000000..319ed9f245abe
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction04.f90
@@ -0,0 +1,24 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+program omp_Reduction
+ integer :: i
+ integer, parameter :: k = 10
+ common /c/ a, b
+
+ !ERROR: Variable 'k' on the REDUCTION clause is not definable
+ !BECAUSE: 'k' is not a variable
+ !$omp parallel do reduction(+:k)
+ do i = 1, 10
+ l = k + 1
+ end do
+ !$omp end parallel do
+
+ !ERROR: Variable 'c' on the REDUCTION clause is not definable
+ !BECAUSE: 'c' is not a variable
+ !$omp parallel do reduction(*:/c/)
+ do i = 1, 10
+ l = k + 1
+ end do
+ !$omp end parallel do
+end program omp_Reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction05.f90 b/flang/test/SemanticsChecked/OpenMP/reduction05.f90
new file mode 100644
index 0000000000000..aa115ed7454ba
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction05.f90
@@ -0,0 +1,38 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+
+program omp_reduction
+
+ integer :: i
+ integer :: k = 10
+ integer :: a(10),b(10,10,10)
+
+ !ERROR: 'a' in REDUCTION clause is a zero size array section
+ !$omp parallel do reduction(+:a(1:0:2))
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end parallel do
+
+ !ERROR: 'a' in REDUCTION clause is a zero size array section
+ !$omp parallel do reduction(+:a(1:0))
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end parallel do
+
+ !ERROR: 'b' in REDUCTION clause is a zero size array section
+ !$omp parallel do reduction(+:b(1:6,5,1:0))
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end parallel do
+
+ !ERROR: 'b' in REDUCTION clause is a zero size array section
+ !$omp parallel do reduction(+:b(1:6,1:0:5,1:10))
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end parallel do
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction06.f90 b/flang/test/SemanticsChecked/OpenMP/reduction06.f90
new file mode 100644
index 0000000000000..58290c61cae86
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction06.f90
@@ -0,0 +1,31 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+
+program omp_reduction
+
+ integer :: i
+ integer :: k = 10
+ integer :: a(10), b(10,10,10)
+
+ !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section.
+ !$omp parallel do reduction(+:a(1:10:3))
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end parallel do
+
+ !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section.
+ !$omp parallel do reduction(+:b(1:10:3,1:8:1,1:5:1))
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end parallel do
+
+ !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section.
+ !$omp parallel do reduction(+:b(1:10:1,1:8:2,1:5:1))
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end parallel do
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction07.f90 b/flang/test/SemanticsChecked/OpenMP/reduction07.f90
new file mode 100644
index 0000000000000..98ed69a8d846d
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction07.f90
@@ -0,0 +1,101 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+program omp_reduction
+
+ integer :: a,i,j,l
+ integer :: k = 10
+ !$omp parallel private(k)
+ !ERROR: REDUCTION variable 'k' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+ !$omp do reduction(+:k)
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end do
+ !$omp end parallel
+
+
+ !$omp parallel private(j),reduction(+:k)
+ !ERROR: REDUCTION variable 'k' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+ !$omp do reduction(+:k)
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp parallel private(j),firstprivate(k)
+ !ERROR: REDUCTION variable 'k' is FIRSTPRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+ !$omp do reduction(min:k)
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end do
+ !$omp end parallel
+
+
+ !$omp parallel private(l,j),firstprivate(k)
+ !ERROR: REDUCTION variable 'k' is FIRSTPRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+ !ERROR: REDUCTION variable 'j' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+ !$omp sections reduction(ior:k) reduction(*:j)
+ do i = 1, 10
+ k = ior(k, 1)
+ j = j * 3
+ end do
+ !$omp end sections
+ !$omp end parallel
+
+!$omp sections private(k)
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !ERROR: REDUCTION variable 'k' is PRIVATE in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+ !$omp do reduction(+:k) reduction(max:j)
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end do
+!$omp end sections
+
+!$omp sections private(k)
+ !$omp target
+ do j = 1,10
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp do reduction(+:k) reduction(max:j)
+ do i = 1, 10
+ k = k + 1
+ end do
+ !$omp end do
+ end do
+ !$omp end target
+!$omp end sections
+
+!$omp parallel reduction(+:a)
+!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+!$omp sections reduction(*:a)
+a = a + 10
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel reduction(*:a)
+!$omp end parallel
+
+!$omp parallel reduction(ieor:a)
+!ERROR: REDUCTION variable 'a' is REDUCTION in outer context must be shared in the parallel regions to which any of the worksharing regions arising from the worksharing construct bind.
+!$omp sections reduction(+:a)
+a = ieor(a, 10)
+!$omp end sections
+!$omp end parallel
+
+!$omp parallel private(a)
+!$omp parallel reduction(ieor:a)
+!$omp end parallel
+!$omp end parallel
+
+!$omp task firstprivate(a)
+!$omp parallel do reduction(+:a)
+do i=1,10
+ a=a+j
+end do
+!$omp end parallel do
+!$omp end task
+
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction08.f90 b/flang/test/SemanticsChecked/OpenMP/reduction08.f90
new file mode 100644
index 0000000000000..99163327cdafa
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction08.f90
@@ -0,0 +1,63 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause Positive cases
+
+!DEF: /omp_reduction MainProgram
+program omp_reduction
+ !DEF: /omp_reduction/i ObjectEntity INTEGER(4)
+ integer i
+ !DEF: /omp_reduction/k ObjectEntity INTEGER(4)
+ integer :: k = 10
+ !DEF: /omp_reduction/m ObjectEntity INTEGER(4)
+ integer :: m = 12
+ !$omp parallel do reduction(max:k)
+ !DEF: /omp_reduction/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct1/k (OmpReduction) HostAssoc INTEGER(4)
+ !DEF: /omp_reduction/max ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity
+ !REF: /omp_reduction/m
+ k = max(k, m)
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do reduction(min:k)
+ !DEF: /omp_reduction/OtherConstruct2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct2/k (OmpReduction) HostAssoc INTEGER(4)
+ !DEF: /omp_reduction/min ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity
+ !REF: /omp_reduction/m
+ k = min(k, m)
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do reduction(iand:k)
+ !DEF: /omp_reduction/OtherConstruct3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct3/k (OmpReduction) HostAssoc INTEGER(4)
+ !DEF: /omp_reduction/iand ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity
+ !REF: /omp_reduction/m
+ k = iand(k, m)
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do reduction(ior:k)
+ !DEF: /omp_reduction/OtherConstruct4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct4/k (OmpReduction) HostAssoc INTEGER(4)
+ !DEF: /omp_reduction/ior ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity
+ !REF: /omp_reduction/m
+ k = ior(k, m)
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do reduction(ieor:k)
+ !DEF: /omp_reduction/OtherConstruct5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct5/k (OmpReduction) HostAssoc INTEGER(4)
+ !DEF: /omp_reduction/ieor ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity
+ !REF: /omp_reduction/m
+ k = ieor(k,m)
+ end do
+ !$omp end parallel do
+
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction09.f90 b/flang/test/SemanticsChecked/OpenMP/reduction09.f90
new file mode 100644
index 0000000000000..095b49ba0c400
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction09.f90
@@ -0,0 +1,86 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause Positive cases.
+!DEF: /omp_reduction MainProgram
+program omp_reduction
+ !DEF: /omp_reduction/i ObjectEntity INTEGER(4)
+ integer i
+ !DEF: /omp_reduction/k ObjectEntity INTEGER(4)
+ integer :: k = 10
+ !DEF: /omp_reduction/a ObjectEntity INTEGER(4)
+ integer a(10)
+ !DEF: /omp_reduction/b ObjectEntity INTEGER(4)
+ integer b(10,10,10)
+
+ !$omp parallel shared(k)
+ !$omp do reduction(+:k)
+ !DEF: /omp_reduction/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct1/OtherConstruct1/k (OmpReduction) HostAssoc INTEGER(4)
+ k = k+1
+ end do
+ !$omp end do
+ !$omp end parallel
+
+
+ !$omp parallel do reduction(+:a(10))
+ !DEF: /omp_reduction/OtherConstruct2/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_reduction/k
+ k = k+1
+ end do
+ !$omp end parallel do
+
+
+ !$omp parallel do reduction(+:a(1:10:1))
+ !DEF: /omp_reduction/OtherConstruct3/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_reduction/k
+ k = k+1
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do reduction(+:b(1:10:1,1:5,2))
+ !DEF: /omp_reduction/OtherConstruct4/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_reduction/k
+ k = k+1
+ end do
+ !$omp end parallel do
+
+ !$omp parallel do reduction(+:b(1:10:1,1:5,2:5:1))
+ !DEF: /omp_reduction/OtherConstruct5/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /omp_reduction/k
+ k = k+1
+ end do
+ !$omp end parallel do
+
+ !$omp parallel private(i)
+ !$omp do reduction(+:k) reduction(+:j)
+ !DEF: /omp_reduction/OtherConstruct6/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct6/OtherConstruct1/k (OmpReduction) HostAssoc INTEGER(4)
+ k = k+1
+ end do
+ !$omp end do
+ !$omp end parallel
+
+ !$omp do reduction(+:k) reduction(*:j) reduction(+:l)
+ !DEF: /omp_reduction/OtherConstruct7/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct7/k (OmpReduction) HostAssoc INTEGER(4)
+ k = k+1
+ end do
+ !$omp end do
+
+
+ !$omp do reduction(.and.:k) reduction(.or.:j) reduction(.eqv.:l)
+ !DEF: /omp_reduction/OtherConstruct8/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /omp_reduction/OtherConstruct8/k (OmpReduction) HostAssoc INTEGER(4)
+ k = k+1
+ end do
+ !$omp end do
+
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction10.f90 b/flang/test/SemanticsChecked/OpenMP/reduction10.f90
new file mode 100644
index 0000000000000..0f94594408b88
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction10.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.15.3.6 Reduction Clause
+program omp_reduction
+
+ integer :: i
+ integer :: k = 10
+
+ !ERROR: Invalid reduction identifier in REDUCTION clause.
+ !$omp parallel do reduction(foo:k)
+ do i = 1, 10
+ k = foo(k)
+ end do
+ !$omp end parallel do
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction11.f90 b/flang/test/SemanticsChecked/OpenMP/reduction11.f90
new file mode 100644
index 0000000000000..3893fe70b407f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction11.f90
@@ -0,0 +1,22 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols -o - %s 2>&1 | FileCheck %s
+! Check intrinsic reduction symbols (in this case "max" are marked as INTRINSIC
+
+! CHECK: MainProgram scope: omp_reduction
+program omp_reduction
+ ! CHECK: i size=4 offset=0: ObjectEntity type: INTEGER(4)
+ integer i
+ ! CHECK: k size=4 offset=4: ObjectEntity type: INTEGER(4) init:10_4
+ integer :: k = 10
+ ! CHECK: m size=4 offset=8: ObjectEntity type: INTEGER(4) init:12_4
+ integer :: m = 12
+
+ ! CHECK: OtherConstruct scope
+ ! CHECK: i (OmpPrivate, OmpPreDetermined): HostAssoc
+ ! CHECK: k (OmpReduction): HostAssoc
+ ! CHECK: max, INTRINSIC: ProcEntity
+ !$omp parallel do reduction(max:k)
+ do i=1,10
+ k = i
+ end do
+ !$omp end parallel do
+end program omp_reduction
diff --git a/flang/test/SemanticsChecked/OpenMP/reduction12.f90 b/flang/test/SemanticsChecked/OpenMP/reduction12.f90
new file mode 100644
index 0000000000000..f896ca4aa60b6
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/reduction12.f90
@@ -0,0 +1,16 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+! OpenMP 5.2: Section 5.5.5 : A procedure pointer must not appear in a
+! reduction clause.
+
+ procedure(foo), pointer :: ptr
+ integer :: i
+ ptr => foo
+!ERROR: A procedure pointer 'ptr' must not appear in a REDUCTION clause.
+!$omp do reduction (+ : ptr)
+ do i = 1, 10
+ end do
+contains
+ subroutine foo
+ end subroutine
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/requires-atomic01.f90 b/flang/test/SemanticsChecked/OpenMP/requires-atomic01.f90
new file mode 100644
index 0000000000000..b39c9cdcc0bb3
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires-atomic01.f90
@@ -0,0 +1,109 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s
+! Ensure that requires atomic_default_mem_order is used to update atomic
+! operations with no explicit memory order set.
+program requires
+ implicit none
+ !$omp requires atomic_default_mem_order(seq_cst)
+ integer :: i, j
+
+ ! ----------------------------------------------------------------------------
+ ! READ
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ !$omp atomic read
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed read
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic read relaxed
+ i = j
+
+ ! ----------------------------------------------------------------------------
+ ! WRITE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ !$omp atomic write
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed write
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic write relaxed
+ i = j
+
+ ! ----------------------------------------------------------------------------
+ ! UPDATE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ !$omp atomic update
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed update
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic update relaxed
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ !$omp atomic
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed
+ i = i + j
+
+ ! ----------------------------------------------------------------------------
+ ! CAPTURE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ !$omp atomic capture
+ i = j
+ i = j
+ !$omp end atomic
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed capture
+ i = j
+ i = j
+ !$omp end atomic
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> SeqCst
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic capture relaxed
+ i = j
+ i = j
+ !$omp end atomic
+end program requires
diff --git a/flang/test/SemanticsChecked/OpenMP/requires-atomic02.f90 b/flang/test/SemanticsChecked/OpenMP/requires-atomic02.f90
new file mode 100644
index 0000000000000..3af83970e7927
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires-atomic02.f90
@@ -0,0 +1,109 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s
+! Ensure that requires atomic_default_mem_order is used to update atomic
+! operations with no explicit memory order set. ACQ_REL clause tested here.
+program requires
+ implicit none
+ !$omp requires atomic_default_mem_order(acq_rel)
+ integer :: i, j
+
+ ! ----------------------------------------------------------------------------
+ ! READ
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Acquire
+ !$omp atomic read
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Acquire
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed read
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicRead
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Acquire
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic read relaxed
+ i = j
+
+ ! ----------------------------------------------------------------------------
+ ! WRITE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Release
+ !$omp atomic write
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed write
+ i = j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicWrite
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic write relaxed
+ i = j
+
+ ! ----------------------------------------------------------------------------
+ ! UPDATE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Release
+ !$omp atomic update
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed update
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicUpdate
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic update relaxed
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Release
+ !$omp atomic
+ i = i + j
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomic
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> Release
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed
+ i = i + j
+
+ ! ----------------------------------------------------------------------------
+ ! CAPTURE
+ ! ----------------------------------------------------------------------------
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> AcqRel
+ !$omp atomic capture
+ i = j
+ i = j
+ !$omp end atomic
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> AcqRel
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic relaxed capture
+ i = j
+ i = j
+ !$omp end atomic
+
+ ! CHECK-LABEL: OpenMPAtomicConstruct -> OmpAtomicCapture
+ ! CHECK-NOT: OmpMemoryOrderClause -> OmpClause -> AcqRel
+ ! CHECK: OmpMemoryOrderClause -> OmpClause -> Relaxed
+ !$omp atomic capture relaxed
+ i = j
+ i = j
+ !$omp end atomic
+end program requires
diff --git a/flang/test/SemanticsChecked/OpenMP/requires01.f90 b/flang/test/SemanticsChecked/OpenMP/requires01.f90
new file mode 100644
index 0000000000000..007135749cc82
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires01.f90
@@ -0,0 +1,7 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+!$omp requires reverse_offload unified_shared_memory
+
+!ERROR: NOWAIT clause is not allowed on the REQUIRES directive
+!$omp requires nowait
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/requires02.f90 b/flang/test/SemanticsChecked/OpenMP/requires02.f90
new file mode 100644
index 0000000000000..974bcceb10c6f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires02.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! All atomic_default_mem_order clauses in 'requires' directives must come
+! strictly before any atomic directives on which the memory_order clause is not
+! specified.
+
+subroutine f
+ integer :: a = 0
+ !$omp atomic
+ a = a + 1
+end subroutine f
+
+subroutine g
+ !ERROR: REQUIRES directive with 'ATOMIC_DEFAULT_MEM_ORDER' clause found lexically after atomic operation without a memory order clause
+ !$omp requires atomic_default_mem_order(relaxed)
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/requires03.f90 b/flang/test/SemanticsChecked/OpenMP/requires03.f90
new file mode 100644
index 0000000000000..4a23a6a4105fe
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires03.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! Target-related clauses in 'requires' directives must come strictly before any
+! device constructs, such as target regions.
+
+subroutine f
+ !$omp target
+ !$omp end target
+end subroutine f
+
+subroutine g
+ !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct
+ !$omp requires dynamic_allocators
+ !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct
+ !$omp requires reverse_offload
+ !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct
+ !$omp requires unified_address
+ !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct
+ !$omp requires unified_shared_memory
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/requires04.f90 b/flang/test/SemanticsChecked/OpenMP/requires04.f90
new file mode 100644
index 0000000000000..bb4101c1cbd6c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires04.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! Target-related clauses in 'requires' directives must come strictly before any
+! device constructs, such as declare target with device_type=nohost|any.
+
+subroutine f
+ integer, save :: x
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to(x) device_type(nohost)
+ !$omp declare target enter(x) device_type(nohost)
+end subroutine f
+
+subroutine g
+ !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct
+ !$omp requires dynamic_allocators
+ !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct
+ !$omp requires reverse_offload
+ !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct
+ !$omp requires unified_address
+ !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct
+ !$omp requires unified_shared_memory
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/requires05.f90 b/flang/test/SemanticsChecked/OpenMP/requires05.f90
new file mode 100644
index 0000000000000..dd27e3895e394
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires05.f90
@@ -0,0 +1,22 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! Target-related clauses in 'requires' directives must come strictly before any
+! device constructs, such as declare target with 'to' clause and no device_type.
+
+subroutine f
+ !WARNING: The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead.
+ !$omp declare target to(f)
+ !$omp declare target enter(f)
+end subroutine f
+
+subroutine g
+ !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct
+ !$omp requires dynamic_allocators
+ !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct
+ !$omp requires reverse_offload
+ !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct
+ !$omp requires unified_address
+ !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct
+ !$omp requires unified_shared_memory
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/requires06.f90 b/flang/test/SemanticsChecked/OpenMP/requires06.f90
new file mode 100644
index 0000000000000..ba9bbf31b6e07
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires06.f90
@@ -0,0 +1,20 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! Target-related clauses in 'requires' directives must come strictly before any
+! device constructs, such as declare target with extended list.
+
+subroutine f
+ !$omp declare target (f)
+end subroutine f
+
+subroutine g
+ !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct
+ !$omp requires dynamic_allocators
+ !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct
+ !$omp requires reverse_offload
+ !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct
+ !$omp requires unified_address
+ !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct
+ !$omp requires unified_shared_memory
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/requires07.f90 b/flang/test/SemanticsChecked/OpenMP/requires07.f90
new file mode 100644
index 0000000000000..2a36b4def9199
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires07.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! Target-related clauses in 'requires' directives must come strictly before any
+! device constructs, such as target parallel regions.
+
+subroutine f
+ !$omp target parallel
+ !$omp end target parallel
+end subroutine f
+
+subroutine g
+ !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct
+ !$omp requires dynamic_allocators
+ !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct
+ !$omp requires reverse_offload
+ !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct
+ !$omp requires unified_address
+ !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct
+ !$omp requires unified_shared_memory
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/requires08.f90 b/flang/test/SemanticsChecked/OpenMP/requires08.f90
new file mode 100644
index 0000000000000..5f3b084078ccf
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires08.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! Target-related clauses in 'requires' directives must come strictly before any
+! device constructs, such as target teams distribute parallel do loops.
+
+subroutine f
+ !$omp target teams distribute parallel do
+ do i=1, 10
+ end do
+ !$omp end target teams distribute parallel do
+end subroutine f
+
+subroutine g
+ !ERROR: REQUIRES directive with 'DYNAMIC_ALLOCATORS' clause found lexically after device construct
+ !$omp requires dynamic_allocators
+ !ERROR: REQUIRES directive with 'REVERSE_OFFLOAD' clause found lexically after device construct
+ !$omp requires reverse_offload
+ !ERROR: REQUIRES directive with 'UNIFIED_ADDRESS' clause found lexically after device construct
+ !$omp requires unified_address
+ !ERROR: REQUIRES directive with 'UNIFIED_SHARED_MEMORY' clause found lexically after device construct
+ !$omp requires unified_shared_memory
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/requires09.f90 b/flang/test/SemanticsChecked/OpenMP/requires09.f90
new file mode 100644
index 0000000000000..2fa5d950b9c2d
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/requires09.f90
@@ -0,0 +1,14 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.4 Requires directive
+! All atomic_default_mem_order clauses in 'requires' directives found within a
+! compilation unit must specify the same ordering.
+
+subroutine f
+ !$omp requires atomic_default_mem_order(seq_cst)
+end subroutine f
+
+!ERROR: Conflicting 'ATOMIC_DEFAULT_MEM_ORDER' REQUIRES clauses found in compilation unit
+subroutine g
+ !$omp requires atomic_default_mem_order(relaxed)
+end subroutine g
diff --git a/flang/test/SemanticsChecked/OpenMP/resolve01.f90 b/flang/test/SemanticsChecked/OpenMP/resolve01.f90
new file mode 100644
index 0000000000000..79b67885b8b9c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/resolve01.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! 2.4 An array section designates a subset of the elements in an array. Although
+! Substring shares similar syntax but cannot be treated as valid array section.
+
+ character*8 c, b
+ character a
+
+ b = "HIFROMPGI"
+ c = b(2:7)
+ !ERROR: Substrings are not allowed on OpenMP directives or clauses
+ !$omp parallel private(c(1:3))
+ a = c(1:1)
+ !$omp end parallel
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/resolve02.f90 b/flang/test/SemanticsChecked/OpenMP/resolve02.f90
new file mode 100644
index 0000000000000..7c3d6331c82ae
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/resolve02.f90
@@ -0,0 +1,18 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! Test the effect to name resolution from illegal clause
+
+ !a = 1.0
+ b = 2
+ !$omp parallel private(a) shared(b)
+ a = 3.
+ b = 4
+ !ERROR: LASTPRIVATE clause is not allowed on the PARALLEL directive
+ !ERROR: 'a' appears in more than one data-sharing clause on the same OpenMP directive
+ !$omp parallel private(a) shared(b) lastprivate(a)
+ a = 5.
+ b = 6
+ !$omp end parallel
+ !$omp end parallel
+ print *,a, b
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/resolve03.f90 b/flang/test/SemanticsChecked/OpenMP/resolve03.f90
new file mode 100644
index 0000000000000..ebc66ca12ebf4
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/resolve03.f90
@@ -0,0 +1,47 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! 2.15.3 Although variables in common blocks can be accessed by use association
+! or host association, common block names cannot. As a result, a common block
+! name specified in a data-sharing attribute clause must be declared to be a
+! common block in the same scoping unit in which the data-sharing attribute
+! clause appears.
+
+ common /c/ a, b
+ integer a(3), b
+ common /tc/ x
+ integer x
+ !$omp threadprivate(/tc/)
+
+ A = 1
+ B = 2
+ block
+ !ERROR: COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears
+ !$omp parallel shared(/c/)
+ a(1:2) = 3
+ B = 4
+ !$omp end parallel
+ end block
+ print *, a, b
+
+ !$omp parallel
+ block
+ !$omp single
+ x = 18
+ !ERROR: COMMON block must be declared in the same scoping unit in which the OpenMP directive or clause appears
+ !$omp end single copyprivate(/tc/)
+ end block
+ !$omp end parallel
+
+ ! Common block names may be used inside nested OpenMP directives.
+ !$omp parallel
+ !$omp parallel copyin(/tc/)
+ x = x + 10
+ !$omp end parallel
+ !$omp end parallel
+
+ !$omp parallel
+ !$omp single
+ x = 18
+ !$omp end single copyprivate(/tc/)
+ !$omp end parallel
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/resolve04.f90 b/flang/test/SemanticsChecked/OpenMP/resolve04.f90
new file mode 100644
index 0000000000000..7c61950c57f66
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/resolve04.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! 2.15.3 Data-Sharing Attribute Clauses
+! A list item that specifies a given variable may not appear in more than
+! one clause on the same directive, except that a variable may be specified
+! in both firstprivate and lastprivate clauses.
+
+ common /c/ a, b
+ integer a(3), b
+
+ A = 1
+ B = 2
+ !ERROR: 'c' appears in more than one data-sharing clause on the same OpenMP directive
+ !$omp parallel shared(/c/,c) private(/c/)
+ a(1:2) = 3
+ B = 4
+ !$omp end parallel
+ print *, a, b, c
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/resolve05.f90 b/flang/test/SemanticsChecked/OpenMP/resolve05.f90
new file mode 100644
index 0000000000000..c4cebb48ac5c2
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/resolve05.f90
@@ -0,0 +1,36 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! 2.15.3 Data-Sharing Attribute Clauses
+! 2.15.3.1 default Clause
+
+subroutine default_none()
+ integer a(3)
+ integer, parameter :: D=10
+ A = 1
+ B = 2
+ !$omp parallel default(none) private(c)
+ !ERROR: The DEFAULT(NONE) clause requires that 'a' must be listed in a data-sharing attribute clause
+ A(1:2) = 3
+ !ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-sharing attribute clause
+ B = 4
+ C = 5 + D
+ !$omp end parallel
+end subroutine default_none
+
+! Test that indices of sequential loops are privatised and hence do not error
+! for DEFAULT(NONE)
+subroutine default_none_seq_loop
+ integer :: i
+
+ !$omp parallel do default(none)
+ do i = 1, 10
+ do j = 1, 20
+ enddo
+ enddo
+end subroutine
+
+program mm
+ call default_none()
+ call default_none_seq_loop()
+ !TODO: private, firstprivate, shared
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/resolve06.f90 b/flang/test/SemanticsChecked/OpenMP/resolve06.f90
new file mode 100644
index 0000000000000..358b1b1cc2826
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/resolve06.f90
@@ -0,0 +1,56 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+use omp_lib
+!2.11.4 Allocate Clause
+!For any list item that is specified in the allocate
+!clause on a directive, a data-sharing attribute clause
+!that may create a private copy of that list item must be
+!specified on the same directive.
+
+ integer :: N = 2
+
+ !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : x)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'y' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : y) firstprivate(x)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+ !ERROR: The ALLOCATE clause requires that 'x' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : x) allocate(omp_default_mem_space : x)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'f' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : f) shared(f)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'q' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel private(t) allocate(omp_default_mem_space : z, t, q, r) firstprivate(z, r)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+
+ !ERROR: The ALLOCATE clause requires that 'b' must be listed in a private data-sharing attribute clause on the same directive
+ !ERROR: The ALLOCATE clause requires that 'c' must be listed in a private data-sharing attribute clause on the same directive
+ !$omp parallel allocate(omp_default_mem_space : a, b, c, d) firstprivate(a, d)
+ do i = 1, N
+ x = 2
+ enddo
+ !$omp end parallel
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/sections01.f90 b/flang/test/SemanticsChecked/OpenMP/sections01.f90
new file mode 100644
index 0000000000000..c26cc88dcc7af
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/sections01.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 4.5
+! 2.7.2 sections Construct
+! Only a single nowait clause can appear on a sections directive.
+
+program omp_sections
+
+ !$omp sections
+ !$omp section
+ print *, "omp section"
+ !ERROR: At most one NOWAIT clause can appear on the END SECTIONS directive
+ !$omp end sections nowait nowait
+
+end program omp_sections
diff --git a/flang/test/SemanticsChecked/OpenMP/sections02.f90 b/flang/test/SemanticsChecked/OpenMP/sections02.f90
new file mode 100644
index 0000000000000..ee29922a72c08
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/sections02.f90
@@ -0,0 +1,139 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
+! OpenMP version 5.0.0
+! 2.8.1 sections construct
+! The code enclosed in a sections construct must be a structured block.
+program OmpConstructSections01
+ use omp_lib
+ integer :: section_count = 0
+ integer, parameter :: NT = 4
+ print *, 'section_count', section_count
+!ERROR: invalid branch into an OpenMP structured block
+!ERROR: invalid branch into an OpenMP structured block
+!ERROR: invalid branch into an OpenMP structured block
+ if (NT) 20, 30, 40
+!ERROR: invalid branch into an OpenMP structured block
+ goto 20
+!$omp sections
+ !$omp section
+ print *, "This is a single statement structured block"
+ !$omp section
+ open (10, file="random-file-name.txt", err=30)
+ !ERROR: invalid branch into an OpenMP structured block
+ !ERROR: invalid branch leaving an OpenMP structured block
+ open (10, file="random-file-name.txt", err=40)
+ !$omp section
+ section_count = section_count + 1
+20 print *, 'Entering into section'
+ call calledFromWithinSection()
+ print *, 'section_count', section_count
+ !$omp section
+ section_count = section_count + 1
+ print *, 'section_count', section_count
+ !ERROR: invalid branch leaving an OpenMP structured block
+ goto 10
+ !$omp section
+30 print *, "Error in opening file"
+!$omp end sections
+10 print *, 'Jump from section'
+
+!$omp sections
+ !$omp section
+40 print *, 'Error in opening file'
+!$omp end sections
+end program OmpConstructSections01
+
+function returnFromSections()
+ !$omp sections
+ !$omp section
+ !ERROR: RETURN statement is not allowed in a SECTIONS construct
+ RETURN
+ !$omp end sections
+end function
+
+subroutine calledFromWithinSection()
+ print *, "I am called from within a 'section' structured block"
+ return
+end subroutine calledFromWithinSection
+
+subroutine continueWithinSections()
+ integer i
+ do i = 1, 10
+ print *, "Statement within loop but outside section construct"
+ !$omp sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: CYCLE to construct outside of SECTIONS construct is not allowed
+ CYCLE
+ END IF
+ !$omp end sections
+ print *, "Statement within loop but outside section contruct"
+ end do
+
+ !$omp sections
+ !$omp section
+ do i = 1, 10
+ CYCLE
+ end do
+ !$omp end sections
+
+ !$omp sections
+ !$omp section
+ loop_1: do i = 1, 10
+ IF (i .EQ. 5) THEN
+ CYCLE loop_1
+ END IF
+ end do loop_1
+ !$omp end sections
+
+ loop_2: do i = 1, 10
+ !$omp sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: CYCLE to construct 'loop_2' outside of SECTIONS construct is not allowed
+ CYCLE loop_2
+ END IF
+ !$omp end sections
+ end do loop_2
+end subroutine continueWithinSections
+
+subroutine breakWithinSections()
+ loop_3: do i = 1, 10
+ !$omp sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: EXIT to construct 'loop_3' outside of SECTIONS construct is not allowed
+ EXIT loop_3
+ END IF
+ !$omp end sections
+ end do loop_3
+
+ loop_4: do i = 1, 10
+ !$omp sections
+ !$omp section
+ IF (i .EQ. 5) THEN
+ !ERROR: EXIT to construct outside of SECTIONS construct is not allowed
+ EXIT
+ END IF
+ !$omp end sections
+ end do loop_4
+
+ !$omp sections
+ !$omp section
+ do i = 1, 10
+ IF (i .EQ. 5) THEN
+ EXIT
+ END IF
+ end do
+ !$omp end sections
+
+ !$omp sections
+ !$omp section
+ loop_5: do i = 1, 10
+ IF (i .EQ. 5) THEN
+ EXIT loop_5
+ END IF
+ end do loop_5
+ !$omp end sections
+end subroutine breakWithinSections
diff --git a/flang/test/SemanticsChecked/OpenMP/sections03.f90 b/flang/test/SemanticsChecked/OpenMP/sections03.f90
new file mode 100644
index 0000000000000..69775013ea823
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/sections03.f90
@@ -0,0 +1,27 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+!XFAIL: *
+! OpenMP version 5.0.0
+! 2.8.1 sections construct
+! Orphaned section directives are prohibited. That is, the section directives must appear within the sections construct and must not be encountered elsewhere in the sections region
+!TODO: Error in parsing. Make parser errors more informative. Until then, the test is XFAIL
+
+program OmpOrphanedSections
+ use omp_lib
+ integer counter
+ counter = 0
+ !CHECK: expected 'END'
+ !CHECK: END PROGRAM statement
+ !CHECK: in the context: main program
+ !CHECK: expected 'END PROGRAM'
+ !CHECK: in the context: END PROGRAM statement
+ !CHECK: in the context: main program
+ !$omp section
+ print *, "An orphaned section containing a single statement"
+ !$omp section
+ counter = counter + 1
+ print *, "An orphaned section containing multiple statements"
+!$omp sections
+ !$omp section
+ print *, "Not an orphan structured block"
+!$omp end sections
+end program OmpOrphanedSections
diff --git a/flang/test/SemanticsChecked/OpenMP/simd-aligned.f90 b/flang/test/SemanticsChecked/OpenMP/simd-aligned.f90
new file mode 100644
index 0000000000000..0a9f95833e22e
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/simd-aligned.f90
@@ -0,0 +1,68 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 4.5
+! 2.8.1 simd Construct
+! Semantic error for correct test case
+
+program omp_simd
+ integer i, j, k, c, d(100)
+ integer, allocatable :: a(:), b(:)
+ common /cmn/ c
+
+ allocate(a(10))
+ allocate(b(10))
+
+ !ERROR: List item 'a' present at multiple ALIGNED clauses
+ !$omp simd aligned(a, a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple ALIGNED clauses
+ !ERROR: List item 'b' present at multiple ALIGNED clauses
+ !$omp simd aligned(a,a) aligned(b) aligned(b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple ALIGNED clauses
+ !$omp simd aligned(a) aligned(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ !$omp simd aligned(a) aligned(b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple ALIGNED clauses
+ !$omp simd aligned(a) private(a) aligned(a)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ print *, a
+
+ !ERROR: 'c' is a common block name and can not appear in an ALIGNED clause
+ !$omp simd aligned(c)
+ do i = 1, 10
+ c = 5
+ end do
+ !$omp end simd
+
+ !ERROR: 'd' in ALIGNED clause must be of type C_PTR, POINTER or ALLOCATABLE
+ !$omp simd aligned(d:100)
+ do i = 1, 100
+ d(i) = i
+ end do
+
+end program omp_simd
diff --git a/flang/test/SemanticsChecked/OpenMP/simd-nontemporal.f90 b/flang/test/SemanticsChecked/OpenMP/simd-nontemporal.f90
new file mode 100644
index 0000000000000..a488edd98cdc3
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/simd-nontemporal.f90
@@ -0,0 +1,63 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 4.5
+! 2.8.1 simd Construct
+! Semantic error for correct test case
+
+program omp_simd
+ integer i, j, k
+ integer, allocatable :: a(:), b(:)
+
+ allocate(a(10))
+ allocate(b(10))
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a, a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !ERROR: List item 'b' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a,a) nontemporal(b) nontemporal(b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a) nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ !$omp simd nontemporal(a) nontemporal(b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a) private(a) nontemporal(a)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ !ERROR: List item 'a' present at multiple NONTEMPORAL clauses
+ !ERROR: List item 'b' present at multiple NONTEMPORAL clauses
+ !$omp simd nontemporal(a,a,b,b)
+ do i = 1, 10
+ a(i) = i
+ b(i) = i
+ end do
+ !$omp end simd
+
+ print *, a
+
+end program omp_simd
diff --git a/flang/test/SemanticsChecked/OpenMP/simd01.f90 b/flang/test/SemanticsChecked/OpenMP/simd01.f90
new file mode 100644
index 0000000000000..1aa2880cda831
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/simd01.f90
@@ -0,0 +1,40 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 5.0
+! 2.9.3.1 simd Construct
+! - A program that branches into or out of a simd region is non-conforming.
+! - The associated loops must be structured blocks
+
+program omp_simd
+ integer i, j
+
+ !$omp simd
+ do i = 1, 10
+ do j = 1, 10
+ print *, "omp simd"
+ !ERROR: invalid branch leaving an OpenMP structured block
+ goto 10
+ end do
+ if (i .EQ. 5) THEN
+ call function1()
+ else if (i .EQ. 7) THEN
+ open (10, file="random-file-name.txt", err=20)
+20 print *, "Error message doesn't branch out of the loop's structured block"
+ else
+ !ERROR: invalid branch leaving an OpenMP structured block
+ open (10, file="random-file-name.txt", err=10)
+ end if
+ end do
+ !$omp end simd
+10 stop
+
+end program omp_simd
+
+subroutine function1()
+ integer i, option
+ option = 1
+ !$omp simd
+ do i = 1, 10
+ print *, "CORRECT SIMD LOOP"
+ end do
+ !$omp end simd
+end subroutine function1
diff --git a/flang/test/SemanticsChecked/OpenMP/simd02.f90 b/flang/test/SemanticsChecked/OpenMP/simd02.f90
new file mode 100644
index 0000000000000..a627e2ac2d67c
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/simd02.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 4.5
+! 2.8.1 simd Construct
+! Semantic error for correct test case
+
+program omp_simd
+ integer i, j, k
+ integer, allocatable :: a(:)
+
+ allocate(a(10))
+
+ !$omp simd aligned(a)
+ do i = 1, 10
+ a(i) = i
+ end do
+ !$omp end simd
+
+ print *, a
+
+end program omp_simd
diff --git a/flang/test/SemanticsChecked/OpenMP/simd03.f90 b/flang/test/SemanticsChecked/OpenMP/simd03.f90
new file mode 100644
index 0000000000000..38f45da47748f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/simd03.f90
@@ -0,0 +1,26 @@
+! RUN: %S/test_errors.sh %s %t %flang -fopenmp
+! XFAIL: *
+
+! OpenMP Version 4.5
+! 2.8.1 simd Construct
+! An ordered construct with the simd clause is the only OpenMP construct
+! that can be encountered during execution of a simd region.
+
+program omp_simd
+ integer i, j, k
+ integer, allocatable :: a(:)
+
+ allocate(a(10))
+
+ !$omp simd
+ do i = 1, 10
+ !ERROR: Invalid OpenMP construct inside simd region
+ !$omp single
+ a(i) = i
+ !$omp end single
+ end do
+ !$omp end simd
+
+ print *, a
+
+end program omp_simd
diff --git a/flang/test/SemanticsChecked/OpenMP/single01.f90 b/flang/test/SemanticsChecked/OpenMP/single01.f90
new file mode 100644
index 0000000000000..2e40bec56e9c2
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/single01.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.3 single Construct
+! Symbol present on multiple clauses
+
+program omp_single
+ integer i
+ i = 10
+
+ !$omp single private(i)
+ print *, "omp single", i
+ !ERROR: COPYPRIVATE variable 'i' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
+ !$omp end single copyprivate(i)
+
+end program omp_single
diff --git a/flang/test/SemanticsChecked/OpenMP/single02.f90 b/flang/test/SemanticsChecked/OpenMP/single02.f90
new file mode 100644
index 0000000000000..03cf7fbb6ad38
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/single02.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+! 2.7.3 single Construct
+! Copyprivate variable is not thread private or private in outer context
+
+program omp_single
+ integer i
+ i = 10
+
+ !$omp parallel
+ !$omp single
+ print *, "omp single", i
+ !ERROR: COPYPRIVATE variable 'i' is not PRIVATE or THREADPRIVATE in outer context
+ !$omp end single copyprivate(i)
+ !$omp end parallel
+
+end program omp_single
diff --git a/flang/test/SemanticsChecked/OpenMP/struct.f90 b/flang/test/SemanticsChecked/OpenMP/struct.f90
new file mode 100644
index 0000000000000..8ae1fbe4da86f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/struct.f90
@@ -0,0 +1,7 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! Check OpenMP compatibility with the DEC STRUCTURE extension
+
+structure /s/
+end structure
+
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol01.f90 b/flang/test/SemanticsChecked/OpenMP/symbol01.f90
new file mode 100644
index 0000000000000..0b435a9ab9850
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol01.f90
@@ -0,0 +1,68 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! Test clauses that accept list.
+! 2.1 Directive Format
+! A list consists of a comma-separated collection of one or more list items.
+! A list item is a variable, array section or common block name (enclosed in
+! slashes).
+
+!DEF: /md Module
+module md
+ !DEF: /md/myty PUBLIC DerivedType
+ type :: myty
+ !DEF: /md/myty/a ObjectEntity REAL(4)
+ real :: a
+ !DEF: /md/myty/b ObjectEntity INTEGER(4)
+ integer :: b
+ end type myty
+end module md
+!DEF: /mm MainProgram
+program mm
+ !REF: /md
+ use :: md
+ !DEF: /mm/c CommonBlockDetails
+ !DEF: /mm/x ObjectEntity REAL(4)
+ !DEF: /mm/y ObjectEntity REAL(4)
+ common /c/x, y
+ !REF: /mm/x
+ !REF: /mm/y
+ real x, y
+ !DEF: /mm/myty Use
+ !DEF: /mm/t ObjectEntity TYPE(myty)
+ type(myty) :: t
+ !DEF: /mm/b ObjectEntity INTEGER(4)
+ integer b(10)
+ !REF: /mm/t
+ !REF: /md/myty/a
+ t%a = 3.14
+ !REF: /mm/t
+ !REF: /md/myty/b
+ t%b = 1
+ !REF: /mm/b
+ b = 2
+ !DEF: /mm/a (Implicit) ObjectEntity REAL(4)
+ a = 1.0
+ !DEF: /mm/c (Implicit) ObjectEntity REAL(4)
+ c = 2.0
+!$omp parallel do private(a,t,/c/) shared(c)
+ !DEF: /mm/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /mm/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
+ !REF: /mm/b
+ !REF: /mm/OtherConstruct1/i
+ a = a+b(i)
+ !DEF: /mm/OtherConstruct1/t (OmpPrivate) HostAssoc TYPE(myty)
+ !REF: /md/myty/a
+ !REF: /mm/OtherConstruct1/i
+ t%a = i
+ !DEF: /mm/OtherConstruct1/y (OmpPrivate) HostAssoc REAL(4)
+ y = 0.
+ !DEF: /mm/OtherConstruct1/x (OmpPrivate) HostAssoc REAL(4)
+ !REF: /mm/OtherConstruct1/a
+ !REF: /mm/OtherConstruct1/i
+ !REF: /mm/OtherConstruct1/y
+ x = a+i+y
+ !REF: /mm/c
+ c = 3.0
+ end do
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol02.f90 b/flang/test/SemanticsChecked/OpenMP/symbol02.f90
new file mode 100644
index 0000000000000..f6ffc5500d0a4
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol02.f90
@@ -0,0 +1,25 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! 1.4.1 Structure of the OpenMP Memory Model
+
+! Test implicit declaration in the OpenMP directive enclosing scope
+! through clause; also test to avoid creating multiple symbols for
+! the same variable
+
+ !DEF: /MainProgram1/b (Implicit) ObjectEntity REAL(4)
+ b = 2
+ !DEF: /MainProgram1/c (Implicit) ObjectEntity REAL(4)
+ c = 0
+ !$omp parallel private(a,b) shared(c,d)
+ !DEF: /MainProgram1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
+ a = 3.
+ !DEF: /MainProgram1/OtherConstruct1/b (OmpPrivate) HostAssoc REAL(4)
+ b = 4
+ !REF: /MainProgram1/c
+ c = 5
+ !DEF: /MainProgram1/d (Implicit) ObjectEntity REAL(4)
+ d = 6
+ !$omp end parallel
+ !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4)
+ print *, a
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol03.f90 b/flang/test/SemanticsChecked/OpenMP/symbol03.f90
new file mode 100644
index 0000000000000..93e9b7a3eae6b
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol03.f90
@@ -0,0 +1,24 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! 1.4.1 Structure of the OpenMP Memory Model
+! In the inner OpenMP region, SHARED `a` refers to the `a` in the outer OpenMP
+! region; PRIVATE `b` refers to the new `b` in the same OpenMP region
+
+ !DEF: /MainProgram1/b (Implicit) ObjectEntity REAL(4)
+ b = 2
+ !$omp parallel private(a) shared(b)
+ !DEF: /MainProgram1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
+ a = 3.
+ !REF: /MainProgram1/b
+ b = 4
+ !$omp parallel private(b) shared(a)
+ !REF: /MainProgram1/OtherConstruct1/a
+ a = 5.
+ !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/b (OmpPrivate) HostAssoc REAL(4)
+ b = 6
+ !$omp end parallel
+ !$omp end parallel
+ !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4)
+ !REF: /MainProgram1/b
+ print *, a, b
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol04.f90 b/flang/test/SemanticsChecked/OpenMP/symbol04.f90
new file mode 100644
index 0000000000000..808d1e0dd09be
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol04.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! 2.15.3 Data-Sharing Attribute Clauses
+! Both PARALLEL and DO (worksharing) directives need to create new scope,
+! so PRIVATE `a` will have new symbol in each region
+
+ !DEF: /MainProgram1/a ObjectEntity REAL(8)
+ real*8 a
+ !REF: /MainProgram1/a
+ a = 3.14
+ !$omp parallel private(a)
+ !DEF: /MainProgram1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(8)
+ a = 2.
+ !$omp do private(a)
+ !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /MainProgram1/OtherConstruct1/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(8)
+ a = 1.
+ end do
+ !$omp end parallel
+ !REF: /MainProgram1/a
+ print *, a
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol05.f90 b/flang/test/SemanticsChecked/OpenMP/symbol05.f90
new file mode 100644
index 0000000000000..fa0a8f65a4294
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol05.f90
@@ -0,0 +1,40 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! 2.15.2 threadprivate Directive
+! The threadprivate directive specifies that variables are replicated,
+! with each thread having its own copy. When threadprivate variables are
+! referenced in the OpenMP region, we know they are already private to
+! their threads, so no new symbol needs to be created.
+
+!DEF: /mm Module
+module mm
+ !$omp threadprivate (i)
+contains
+ !DEF: /mm/foo PUBLIC (Subroutine) Subprogram
+ subroutine foo
+ !DEF: /mm/foo/a ObjectEntity INTEGER(4)
+ integer :: a = 3
+ !$omp parallel
+ !REF: /mm/foo/a
+ a = 1
+ !DEF: /mm/i PUBLIC (Implicit, OmpThreadprivate) ObjectEntity INTEGER(4)
+ !REF: /mm/foo/a
+ i = a
+ !$omp end parallel
+ !REF: /mm/foo/a
+ print *, a
+ block
+ !DEF: /mm/foo/BlockConstruct1/i ObjectEntity REAL(4)
+ real i
+ !REF: /mm/foo/BlockConstruct1/i
+ i = 3.14
+ end block
+ end subroutine foo
+end module mm
+!DEF: /tt MainProgram
+program tt
+ !REF: /mm
+ use :: mm
+ !DEF: /tt/foo (Subroutine) Use
+ call foo
+end program tt
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol06.f90 b/flang/test/SemanticsChecked/OpenMP/symbol06.f90
new file mode 100644
index 0000000000000..906264eb12642
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol06.f90
@@ -0,0 +1,16 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! 2.15.3 Data-Sharing Attribute Clauses
+! A list item that specifies a given variable may not appear in more than
+! one clause on the same directive, except that a variable may be specified
+! in both firstprivate and lastprivate clauses.
+
+ !DEF: /MainProgram1/a (Implicit) ObjectEntity REAL(4)
+ a = 1.
+ !$omp parallel do firstprivate(a) lastprivate(a)
+ !DEF: /MainProgram1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !DEF: /MainProgram1/OtherConstruct1/a (OmpFirstPrivate, OmpLastPrivate) HostAssoc REAL(4)
+ a = 2.
+ end do
+end program
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol07.f90 b/flang/test/SemanticsChecked/OpenMP/symbol07.f90
new file mode 100644
index 0000000000000..e2250f5c7908a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol07.f90
@@ -0,0 +1,37 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! Generic tests
+! 1. subroutine or function calls should not be fixed for DSA or DMA
+
+!DEF: /foo (Function) Subprogram REAL(4)
+!DEF: /foo/rnum ObjectEntity REAL(4)
+function foo(rnum)
+ !REF: /foo/rnum
+ real rnum
+ !REF: /foo/rnum
+ rnum = rnum+1.
+end function foo
+!DEF: /function_call_in_region EXTERNAL (Subroutine) Subprogram
+subroutine function_call_in_region
+ implicit none
+ !DEF: /function_call_in_region/foo (Function) ProcEntity REAL(4)
+ real foo
+ !DEF: /function_call_in_region/a ObjectEntity REAL(4)
+ real :: a = 0.
+ !DEF: /function_call_in_region/b ObjectEntity REAL(4)
+ real :: b = 5.
+ !$omp parallel default(none) private(a) shared(b)
+ !DEF: /function_call_in_region/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
+ !REF: /function_call_in_region/foo
+ !REF: /function_call_in_region/b
+ a = foo(b)
+ !$omp end parallel
+ !REF: /function_call_in_region/a
+ !REF: /function_call_in_region/b
+ print *, a, b
+end subroutine function_call_in_region
+!DEF: /mm MainProgram
+program mm
+ !REF: /function_call_in_region
+ call function_call_in_region
+end program mm
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol08.f90 b/flang/test/SemanticsChecked/OpenMP/symbol08.f90
new file mode 100644
index 0000000000000..3af85af74ee97
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol08.f90
@@ -0,0 +1,251 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! 2.15.1.1 Predetermined rules for associated do-loops index variable
+! a) The loop iteration variable(s) in the associated do-loop(s) of a do,
+! parallel do, taskloop, or distribute construct is (are) private.
+! b) The loop iteration variable in the associated do-loop of a simd construct
+! with just one associated do-loop is linear with a linear-step that is the
+! increment of the associated do-loop.
+! c) The loop iteration variables in the associated do-loops of a simd
+! construct with multiple associated do-loops are lastprivate.
+! d) A loop iteration variable for a sequential loop in a parallel or task
+! generating construct is private in the innermost such construct that
+! encloses the loop.
+! - TBD
+
+! All the tests assume that the do-loops association for collapse/ordered
+! clause has been performed (the number of nested do-loops >= n).
+
+! Rule a)
+! TODO: nested constructs (k should be private too)
+!DEF: /test_do (Subroutine) Subprogram
+subroutine test_do
+ implicit none
+ !DEF: /test_do/a ObjectEntity REAL(4)
+ real a(20,20,20)
+ !DEF: /test_do/i ObjectEntity INTEGER(4)
+ !DEF: /test_do/j ObjectEntity INTEGER(4)
+ !DEF: /test_do/k ObjectEntity INTEGER(4)
+ integer i, j, k
+!$omp parallel
+ !REF: /test_do/i
+ i = 99
+!$omp do collapse(2)
+ !DEF: /test_do/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,5
+ !DEF: /test_do/OtherConstruct1/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=6,10
+ !REF: /test_do/a
+ a(1,1,1) = 0.
+ !DEF: /test_do/OtherConstruct1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do k=11,15
+ !REF: /test_do/a
+ !REF: /test_do/OtherConstruct1/k
+ !REF: /test_do/OtherConstruct1/OtherConstruct1/j
+ !REF: /test_do/OtherConstruct1/OtherConstruct1/i
+ a(k,j,i) = 1.
+ end do
+ end do
+ end do
+!$omp end parallel
+end subroutine test_do
+
+! Rule a)
+!DEF: /test_pardo (Subroutine) Subprogram
+subroutine test_pardo
+ implicit none
+ !DEF: /test_pardo/a ObjectEntity REAL(4)
+ real a(20,20,20)
+ !DEF: /test_pardo/i ObjectEntity INTEGER(4)
+ !DEF: /test_pardo/j ObjectEntity INTEGER(4)
+ !DEF: /test_pardo/k ObjectEntity INTEGER(4)
+ integer i, j, k
+!$omp parallel do collapse(2) private(k) ordered(2)
+ !DEF: /test_pardo/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,5
+ !DEF: /test_pardo/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=6,10
+ !REF: /test_pardo/a
+ a(1,1,1) = 0.
+ !DEF: /test_pardo/OtherConstruct1/k (OmpPrivate) HostAssoc INTEGER(4)
+ do k=11,15
+ !REF: /test_pardo/a
+ !REF: /test_pardo/OtherConstruct1/k
+ !REF: /test_pardo/OtherConstruct1/j
+ !REF: /test_pardo/OtherConstruct1/i
+ a(k,j,i) = 1.
+ end do
+ end do
+ end do
+end subroutine test_pardo
+
+! Rule a)
+!DEF: /test_taskloop (Subroutine) Subprogram
+subroutine test_taskloop
+ implicit none
+ !DEF: /test_taskloop/a ObjectEntity REAL(4)
+ real a(5,5)
+ !DEF: /test_taskloop/i ObjectEntity INTEGER(4)
+ !DEF: /test_taskloop/j ObjectEntity INTEGER(4)
+ integer i, j
+!$omp taskloop private(j)
+ !DEF: /test_taskloop/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,5
+ !DEF: /test_taskloop/OtherConstruct1/j (OmpPrivate) HostAssoc INTEGER(4)
+ !REF: /test_taskloop/OtherConstruct1/i
+ do j=1,i
+ !DEF: /test_taskloop/OtherConstruct1/a (OmpFirstPrivate, OmpImplicit) HostAssoc REAL(4)
+ !REF: /test_taskloop/OtherConstruct1/j
+ !REF: /test_taskloop/OtherConstruct1/i
+ a(j,i) = 3.14
+ end do
+ end do
+!$omp end taskloop
+end subroutine test_taskloop
+
+! Rule a); OpenMP 4.5 Examples teams.2.f90
+! TODO: reduction; data-mapping attributes
+!DEF: /dotprod (Subroutine) Subprogram
+!DEF: /dotprod/b (OmpMapTo) ObjectEntity REAL(4)
+!DEF: /dotprod/c (OmpMapTo) ObjectEntity REAL(4)
+!DEF: /dotprod/n ObjectEntity INTEGER(4)
+!DEF: /dotprod/block_size ObjectEntity INTEGER(4)
+!DEF: /dotprod/num_teams ObjectEntity INTEGER(4)
+!DEF: /dotprod/block_threads ObjectEntity INTEGER(4)
+subroutine dotprod (b, c, n, block_size, num_teams, block_threads)
+ implicit none
+ !REF: /dotprod/n
+ integer n
+ !REF: /dotprod/b
+ !REF: /dotprod/n
+ !REF: /dotprod/c
+ !DEF: /dotprod/sum (OmpMapToFrom) ObjectEntity REAL(4)
+ real b(n), c(n), sum
+ !REF: /dotprod/block_size
+ !REF: /dotprod/num_teams
+ !REF: /dotprod/block_threads
+ !DEF: /dotprod/i ObjectEntity INTEGER(4)
+ !DEF: /dotprod/i0 ObjectEntity INTEGER(4)
+ integer block_size, num_teams, block_threads, i, i0
+ !REF: /dotprod/sum
+ sum = 0.0e0
+!$omp target map(to:b,c) map(tofrom:sum)
+!$omp teams num_teams(num_teams) thread_limit(block_threads) reduction(+:sum)
+!$omp distribute
+ !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/i0 (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ !REF: /dotprod/n
+ !REF: /dotprod/block_size
+ do i0=1,n,block_size
+!$omp parallel do reduction(+:sum)
+ !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ !REF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/i0
+ !DEF: /dotprod/min ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity
+ !REF: /dotprod/block_size
+ !REF: /dotprod/n
+ do i=i0,min(i0+block_size, n)
+ !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/sum (OmpReduction) HostAssoc REAL(4)
+ !REF: /dotprod/b
+ !REF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/i
+ !REF: /dotprod/c
+ sum = sum+b(i)*c(i)
+ end do
+ end do
+!$omp end teams
+!$omp end target
+ !REF: /dotprod/sum
+ print *, sum
+end subroutine dotprod
+
+! Rule b)
+! TODO: nested constructs (j, k should be private too)
+!DEF: /test_simd (Subroutine) Subprogram
+subroutine test_simd
+ implicit none
+ !DEF: /test_simd/a ObjectEntity REAL(4)
+ real a(20,20,20)
+ !DEF: /test_simd/i ObjectEntity INTEGER(4)
+ !DEF: /test_simd/j ObjectEntity INTEGER(4)
+ !DEF: /test_simd/k ObjectEntity INTEGER(4)
+ integer i, j, k
+!$omp parallel do simd
+ !DEF: /test_simd/OtherConstruct1/i (OmpLinear, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,5
+ !DEF: /test_simd/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=6,10
+ !DEF: /test_simd/OtherConstruct1/k (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do k=11,15
+ !REF: /test_simd/a
+ !REF: /test_simd/OtherConstruct1/k
+ !REF: /test_simd/OtherConstruct1/j
+ !REF: /test_simd/OtherConstruct1/i
+ a(k,j,i) = 3.14
+ end do
+ end do
+ end do
+end subroutine test_simd
+
+! Rule c)
+!DEF: /test_simd_multi (Subroutine) Subprogram
+subroutine test_simd_multi
+ implicit none
+ !DEF: /test_simd_multi/a ObjectEntity REAL(4)
+ real a(20,20,20)
+ !DEF: /test_simd_multi/i ObjectEntity INTEGER(4)
+ !DEF: /test_simd_multi/j ObjectEntity INTEGER(4)
+ !DEF: /test_simd_multi/k ObjectEntity INTEGER(4)
+ integer i, j, k
+!$omp parallel do simd collapse(3)
+ !DEF: /test_simd_multi/OtherConstruct1/i (OmpLastPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,5
+ !DEF: /test_simd_multi/OtherConstruct1/j (OmpLastPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do j=6,10
+ !DEF: /test_simd_multi/OtherConstruct1/k (OmpLastPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do k=11,15
+ !REF: /test_simd_multi/a
+ !REF: /test_simd_multi/OtherConstruct1/k
+ !REF: /test_simd_multi/OtherConstruct1/j
+ !REF: /test_simd_multi/OtherConstruct1/i
+ a(k,j,i) = 3.14
+ end do
+ end do
+ end do
+end subroutine test_simd_multi
+
+! Rule d)
+!DEF: /test_seq_loop (Subroutine) Subprogram
+subroutine test_seq_loop
+ implicit none
+ !DEF: /test_seq_loop/i ObjectEntity INTEGER(4)
+ !DEF: /test_seq_loop/j ObjectEntity INTEGER(4)
+ integer i, j
+ !REF: /test_seq_loop/i
+ i = -1
+ !REF: /test_seq_loop/j
+ j = -1
+ !$omp parallel
+ !REF: /test_seq_loop/i
+ !REF: /test_seq_loop/j
+ print *, i, j
+ !$omp parallel
+ !REF: /test_seq_loop/i
+ !DEF: /test_seq_loop/OtherConstruct1/OtherConstruct1/j (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ print *, i, j
+ !$omp do
+ !DEF: /test_seq_loop/OtherConstruct1/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4)
+ do i=1,10
+ !REF: /test_seq_loop/OtherConstruct1/OtherConstruct1/j
+ do j=1,10
+ end do
+ end do
+ !REF: /test_seq_loop/i
+ !REF: /test_seq_loop/OtherConstruct1/OtherConstruct1/j
+ print *, i, j
+ !$omp end parallel
+ !REF: /test_seq_loop/i
+ !REF: /test_seq_loop/j
+ print *, i, j
+ !$omp end parallel
+ !REF: /test_seq_loop/i
+ !REF: /test_seq_loop/j
+ print *, i, j
+end subroutine test_seq_loop
diff --git a/flang/test/SemanticsChecked/OpenMP/symbol09.f90 b/flang/test/SemanticsChecked/OpenMP/symbol09.f90
new file mode 100644
index 0000000000000..e2250f5c7908a
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/symbol09.f90
@@ -0,0 +1,37 @@
+! RUN: %python %S/../test_symbols.py %s %flang_fc1 -fopenmp
+
+! Generic tests
+! 1. subroutine or function calls should not be fixed for DSA or DMA
+
+!DEF: /foo (Function) Subprogram REAL(4)
+!DEF: /foo/rnum ObjectEntity REAL(4)
+function foo(rnum)
+ !REF: /foo/rnum
+ real rnum
+ !REF: /foo/rnum
+ rnum = rnum+1.
+end function foo
+!DEF: /function_call_in_region EXTERNAL (Subroutine) Subprogram
+subroutine function_call_in_region
+ implicit none
+ !DEF: /function_call_in_region/foo (Function) ProcEntity REAL(4)
+ real foo
+ !DEF: /function_call_in_region/a ObjectEntity REAL(4)
+ real :: a = 0.
+ !DEF: /function_call_in_region/b ObjectEntity REAL(4)
+ real :: b = 5.
+ !$omp parallel default(none) private(a) shared(b)
+ !DEF: /function_call_in_region/OtherConstruct1/a (OmpPrivate) HostAssoc REAL(4)
+ !REF: /function_call_in_region/foo
+ !REF: /function_call_in_region/b
+ a = foo(b)
+ !$omp end parallel
+ !REF: /function_call_in_region/a
+ !REF: /function_call_in_region/b
+ print *, a, b
+end subroutine function_call_in_region
+!DEF: /mm MainProgram
+program mm
+ !REF: /function_call_in_region
+ call function_call_in_region
+end program mm
diff --git a/flang/test/SemanticsChecked/OpenMP/sync-critical01.f90 b/flang/test/SemanticsChecked/OpenMP/sync-critical01.f90
new file mode 100644
index 0000000000000..b597eb17ea226
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/sync-critical01.f90
@@ -0,0 +1,41 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 5.0
+! 2.17.1 critical construct
+! CRITICAL start and end CRITICAL directive names mismatch
+integer function timer_tick_sec()
+ implicit none
+ integer t
+
+ !$OMP CRITICAL
+ t = t + 1
+ !$OMP END CRITICAL
+
+ !$OMP CRITICAL (foo)
+ t = t + 1
+ !$OMP END CRITICAL (foo)
+
+ !$OMP CRITICAL (foo)
+ t = t + 1
+ !ERROR: CRITICAL directive names do not match
+ !$OMP END CRITICAL (bar)
+
+ !$OMP CRITICAL (bar)
+ t = t + 1
+ !ERROR: CRITICAL directive names do not match
+ !$OMP END CRITICAL (foo)
+
+ !ERROR: CRITICAL directive names do not match
+ !$OMP CRITICAL (bar)
+ t = t + 1
+ !$OMP END CRITICAL
+
+ !$OMP CRITICAL
+ t = t + 1
+ !ERROR: CRITICAL directive names do not match
+ !$OMP END CRITICAL (foo)
+
+ timer_tick_sec = t
+ return
+
+end function timer_tick_sec
diff --git a/flang/test/SemanticsChecked/OpenMP/sync-critical02.f90 b/flang/test/SemanticsChecked/OpenMP/sync-critical02.f90
new file mode 100644
index 0000000000000..1fa9d6ad84f28
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/sync-critical02.f90
@@ -0,0 +1,55 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
+
+! OpenMP Version 5.0
+! 2.17.1 critical construct
+! If the hint clause is specified, the critical construct must have a name.
+program sample
+ use omp_lib
+ integer i, j
+ !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive
+ !$omp critical hint(omp_lock_hint_speculative)
+ j = j + 1
+ !$omp end critical
+
+ !$omp critical (foo) hint(omp_lock_hint_speculative)
+ i = i - 1
+ !$omp end critical (foo)
+
+ !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive
+ !$omp critical hint(omp_lock_hint_nonspeculative)
+ j = j + 1
+ !$omp end critical
+
+ !$omp critical (foo) hint(omp_lock_hint_nonspeculative)
+ i = i - 1
+ !$omp end critical (foo)
+
+ !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive
+ !$omp critical hint(omp_lock_hint_contended)
+ j = j + 1
+ !$omp end critical
+
+ !$omp critical (foo) hint(omp_lock_hint_contended)
+ i = i - 1
+ !$omp end critical (foo)
+
+ !ERROR: Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive
+ !$omp critical hint(omp_lock_hint_uncontended)
+ j = j + 1
+ !$omp end critical
+
+ !$omp critical (foo) hint(omp_lock_hint_uncontended)
+ i = i - 1
+ !$omp end critical (foo)
+
+ !$omp critical hint(omp_sync_hint_none)
+ j = j + 1
+ !$omp end critical
+
+ !$omp critical (foo) hint(omp_sync_hint_none)
+ i = i - 1
+ !$omp end critical (foo)
+
+end program sample
diff --git a/flang/test/SemanticsChecked/OpenMP/target-update01.f90 b/flang/test/SemanticsChecked/OpenMP/target-update01.f90
new file mode 100644
index 0000000000000..84dc60dcd75f5
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/target-update01.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+subroutine foo(x)
+ integer :: x
+ !ERROR: At least one motion-clause (TO/FROM) must be specified on TARGET UPDATE construct.
+ !$omp target update
+
+ !ERROR: At least one motion-clause (TO/FROM) must be specified on TARGET UPDATE construct.
+ !$omp target update nowait
+
+ !$omp target update to(x) nowait
+
+ !ERROR: At most one NOWAIT clause can appear on the TARGET UPDATE directive
+ !$omp target update to(x) nowait nowait
+
+ !ERROR: A list item ('x') can only appear in a TO or FROM clause, but not in both.
+ !BECAUSE: 'x' appears in the TO clause.
+ !BECAUSE: 'x' appears in the FROM clause.
+ !$omp target update to(x) from(x)
+
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/target.f90 b/flang/test/SemanticsChecked/OpenMP/target.f90
new file mode 100644
index 0000000000000..994c04048edff
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/target.f90
@@ -0,0 +1,11 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -Werror
+
+! Corner cases in OpenMP target directives
+
+subroutine empty_target()
+ integer :: i
+
+ !$omp target map(i)
+ !$omp end target
+
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/target01.f90 b/flang/test/SemanticsChecked/OpenMP/target01.f90
new file mode 100644
index 0000000000000..9836f0112738f
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/target01.f90
@@ -0,0 +1,58 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+subroutine foo(b)
+use iso_c_binding
+integer :: x,y
+type(C_PTR) :: b
+!ERROR: Variable 'x' may not appear on both MAP and PRIVATE clauses on a TARGET construct
+!$omp target map(x) private(x)
+ x = x + 1
+!$omp end target
+
+!ERROR: Variable 'y' in IS_DEVICE_PTR clause must be of type C_PTR
+!$omp target map(x) is_device_ptr(y)
+ x = x + 1
+!$omp end target
+
+!ERROR: Variable 'b' may not appear on both IS_DEVICE_PTR and HAS_DEVICE_ADDR clauses on a TARGET construct
+!$omp target map(x) is_device_ptr(b) has_device_addr(b)
+ x = x + 1
+!$omp end target
+
+!ERROR: Variable 'b' may not appear on both IS_DEVICE_PTR and PRIVATE clauses on a TARGET construct
+!$omp target map(x) is_device_ptr(b) private(b)
+ x = x + 1
+!$omp end target
+
+!ERROR: Variable 'y' may not appear on both HAS_DEVICE_ADDR and FIRSTPRIVATE clauses on a TARGET construct
+!$omp target map(x) has_device_addr(y) firstprivate(y)
+ y = y - 1
+!$omp end target
+
+end subroutine foo
+
+subroutine bar(b1, b2, b3)
+ use iso_c_binding
+ integer :: y
+ type(c_ptr) :: c
+ type(c_ptr), allocatable :: b1
+ type(c_ptr), pointer :: b2
+ type(c_ptr), value :: b3
+
+ !WARNING: Variable 'c' in IS_DEVICE_PTR clause must be a dummy argument. This semantic check is deprecated from OpenMP 5.2 and later.
+ !$omp target is_device_ptr(c)
+ y = y + 1
+ !$omp end target
+ !WARNING: Variable 'b1' in IS_DEVICE_PTR clause must be a dummy argument that does not have the ALLOCATABLE, POINTER or VALUE attribute. This semantic check is deprecated from OpenMP 5.2 and later.
+ !$omp target is_device_ptr(b1)
+ y = y + 1
+ !$omp end target
+ !WARNING: Variable 'b2' in IS_DEVICE_PTR clause must be a dummy argument that does not have the ALLOCATABLE, POINTER or VALUE attribute. This semantic check is deprecated from OpenMP 5.2 and later.
+ !$omp target is_device_ptr(b2)
+ y = y + 1
+ !$omp end target
+ !WARNING: Variable 'b3' in IS_DEVICE_PTR clause must be a dummy argument that does not have the ALLOCATABLE, POINTER or VALUE attribute. This semantic check is deprecated from OpenMP 5.2 and later.
+ !$omp target is_device_ptr(b3)
+ y = y + 1
+ !$omp end target
+end subroutine bar
diff --git a/flang/test/SemanticsChecked/OpenMP/target02.f90 b/flang/test/SemanticsChecked/OpenMP/target02.f90
new file mode 100644
index 0000000000000..06ce1c0875cc9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/target02.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 4.5
+
+program p
+integer :: y
+!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET construct
+!$omp target map(y) firstprivate(y)
+y = y + 1
+!$omp end target
+!ERROR: Variable 'y' may not appear on both MAP and FIRSTPRIVATE clauses on a TARGET SIMD construct
+!$omp target simd map(y) firstprivate(y)
+do i=1,1
+ y = y + 1
+end do
+!$omp end target simd
+
+end program p
diff --git a/flang/test/SemanticsChecked/OpenMP/task01.f90 b/flang/test/SemanticsChecked/OpenMP/task01.f90
new file mode 100644
index 0000000000000..4dc80d6d70e05
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/task01.f90
@@ -0,0 +1,31 @@
+! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s
+! OpenMP Version 4.5
+! 2.9.1 task Construct
+! Invalid entry to OpenMP structured block.
+
+recursive subroutine traverse ( P )
+ type Node
+ type(Node), pointer :: left, right
+ end type Node
+
+ type(Node) :: P
+
+ !CHECK: invalid branch into an OpenMP structured block
+ goto 10
+
+ if (associated(P%left)) then
+ !$omp task
+ call traverse(P%left)
+ !CHECK: In the enclosing TASK directive branched into
+ 10 stop
+ !$omp end task
+ endif
+
+ if (associated(P%right)) then
+ !$omp task
+ call traverse(P%right)
+ !$omp end task
+ endif
+ call process ( P )
+
+ end subroutine traverse
diff --git a/flang/test/SemanticsChecked/OpenMP/taskgroup01.f90 b/flang/test/SemanticsChecked/OpenMP/taskgroup01.f90
new file mode 100644
index 0000000000000..9de1df91bf3bd
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/taskgroup01.f90
@@ -0,0 +1,50 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
+
+use omp_lib
+ implicit none
+ integer :: xyz, abc
+ real :: reduction_var
+ !$omp parallel num_threads(4)
+ !$omp single
+ print *, "The"
+ !$omp taskgroup
+ !$omp task
+ print *, "almighty"
+ !$omp end task
+ !$omp task
+ print *, "sun"
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end single
+ !$omp end parallel
+
+ !$omp parallel private(xyz)
+ !$omp taskgroup allocate(xyz)
+ !$omp task
+ print *, "The "
+ !$omp taskgroup allocate(omp_large_cap_mem_space: abc)
+ !$omp task
+ print *, "almighty sun"
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end task
+ !$omp end taskgroup
+ !$omp end parallel
+
+ !ERROR: PRIVATE clause is not allowed on the TASKGROUP directive
+ !$omp taskgroup private(abc)
+ !$omp end taskgroup
+
+ !$omp parallel
+ !$omp task
+ !$omp taskgroup task_reduction(+ : reduction_var)
+ print *, "The "
+ !$omp taskgroup task_reduction(.or. : reduction_var) task_reduction(.and. : reduction_var)
+ print *, "almighty sun"
+ !$omp end taskgroup
+ !$omp end taskgroup
+ !$omp end task
+ !$omp end parallel
+end program
\ No newline at end of file
diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop-simd01.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop-simd01.f90
new file mode 100644
index 0000000000000..bb7266a52f61e
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/taskloop-simd01.f90
@@ -0,0 +1,17 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! OpenMP Version 5.0
+! 2.10.3 taskloop simd Construct
+
+program omp_taskloop_simd
+ integer i , j , k
+
+ !$omp taskloop simd reduction(+:k)
+ do i=1,10000
+ do j=1,i
+ k = k + 1
+ end do
+ end do
+ !$omp end taskloop simd
+
+end program omp_taskloop_simd
diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop01.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop01.f90
new file mode 100644
index 0000000000000..6bef584381518
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/taskloop01.f90
@@ -0,0 +1,23 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.9.2 taskloop Construct
+
+subroutine parallel_work
+ integer i
+ integer j
+
+ !$omp taskgroup
+ !$omp task
+ call long_running_task()
+ !$omp end task
+
+ !$omp taskloop private(j) grainsize(500) nogroup
+ do i=1,10000
+ do j=1,i
+ call loop_body(i, j)
+ end do
+ end do
+ !$omp end taskloop
+ !$omp end taskgroup
+
+end subroutine parallel_work
diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop02.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop02.f90
new file mode 100644
index 0000000000000..867ef8a9806d9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/taskloop02.f90
@@ -0,0 +1,21 @@
+! RUN: not %flang -fsyntax-only -fopenmp %s 2>&1 | FileCheck %s
+! OpenMP Version 4.5
+! 2.9.2 taskloop Construct
+! Invalid entry to OpenMP structured block.
+
+program omp_taskloop
+ integer i , j
+
+ !CHECK: invalid branch into an OpenMP structured block
+ goto 10
+
+ !$omp taskloop private(j) grainsize(500) nogroup
+ do i=1,10000
+ do j=1,i
+ !CHECK: In the enclosing TASKLOOP directive branched into
+ 10 call loop_body(i, j)
+ end do
+ end do
+ !$omp end taskloop
+
+end program omp_taskloop
diff --git a/flang/test/SemanticsChecked/OpenMP/taskloop03.f90 b/flang/test/SemanticsChecked/OpenMP/taskloop03.f90
new file mode 100644
index 0000000000000..7e2e426a3fe7e
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/taskloop03.f90
@@ -0,0 +1,25 @@
+! RUN: %S/test_errors.sh %s %t %flang -fopenmp
+! XFAIL: *
+
+! OpenMP Version 4.5
+! 2.9.2 taskloop Construct
+! All loops associated with the taskloop construct must be perfectly nested,
+! there must be no intervening code or any OpenMP directive between
+! any two loops
+
+program omp_taskloop
+ integer i, j
+
+ !$omp taskloop private(j) grainsize(500) nogroup
+ do i=1, 10000
+ do j=1, i
+ call loop_body(i, j)
+ end do
+ !ERROR: Loops associated with !$omp taskloop is not perfectly nested
+ !$omp single
+ print *, "omp single"
+ !$omp end single
+ end do
+ !$omp end taskloop
+
+end program omp_taskloop
diff --git a/flang/test/SemanticsChecked/OpenMP/taskwait.f90 b/flang/test/SemanticsChecked/OpenMP/taskwait.f90
new file mode 100644
index 0000000000000..e60051c9da8ac
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/taskwait.f90
@@ -0,0 +1,4 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+!$omp taskwait
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate01.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate01.f90
new file mode 100644
index 0000000000000..c2cf9ba99ab04
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/threadprivate01.f90
@@ -0,0 +1,53 @@
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.21.2 Threadprivate Directive
+
+module thread_private01
+ use omp_lib
+ type my_type(kind_param, len_param)
+ integer, KIND :: kind_param
+ integer, LEN :: len_param
+ integer :: t_i
+ integer :: t_arr(10)
+ end type my_type
+
+ type(my_type(2, 4)) :: my_var
+ integer :: arr(10)
+ integer(kind=4) :: x
+ character(len=32) :: w
+ integer, dimension(:), allocatable :: y
+
+ !$omp threadprivate(my_var)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(my_var%t_i)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(my_var%t_arr)
+
+ !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(my_var%kind_param)
+
+ !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(my_var%len_param)
+
+ !$omp threadprivate(arr)
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(arr(1))
+
+ !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(arr(1:2))
+
+ !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(x%KIND)
+
+ !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(w%LEN)
+
+ !ERROR: A type parameter inquiry cannot appear on the THREADPRIVATE directive
+ !$omp threadprivate(y%KIND)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate02.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate02.f90
new file mode 100644
index 0000000000000..7f6e8dcc8e8ab
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/threadprivate02.f90
@@ -0,0 +1,81 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.21.2 Threadprivate Directive
+
+program threadprivate02
+ integer :: arr1(10)
+ common /blk1/ a1
+ real, save :: eq_a, eq_b, eq_c, eq_d
+
+ !$omp threadprivate(arr1)
+
+ !$omp threadprivate(/blk1/)
+
+ !$omp threadprivate(blk1)
+
+ !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block
+ !$omp threadprivate(a1)
+
+ equivalence(eq_a, eq_b)
+ !ERROR: A variable in a THREADPRIVATE directive cannot appear in an EQUIVALENCE statement
+ !$omp threadprivate(eq_a)
+
+ !ERROR: A variable in a THREADPRIVATE directive cannot appear in an EQUIVALENCE statement
+ !$omp threadprivate(eq_c)
+ equivalence(eq_c, eq_d)
+
+contains
+ subroutine func()
+ integer :: arr2(10)
+ integer, save :: arr3(10)
+ common /blk2/ a2
+ common /blk3/ a3
+ save /blk3/
+
+ !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp threadprivate(arr2)
+
+ !$omp threadprivate(arr3)
+
+ !$omp threadprivate(/blk2/)
+
+ !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block
+ !$omp threadprivate(a2)
+
+ !$omp threadprivate(/blk3/)
+
+ !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block
+ !$omp threadprivate(a3)
+ end
+end
+
+module mod4
+ integer :: arr4(10)
+ common /blk4/ a4
+
+ !$omp threadprivate(arr4)
+
+ !$omp threadprivate(/blk4/)
+
+ !$omp threadprivate(blk4)
+
+ !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block
+ !$omp threadprivate(a4)
+end
+
+subroutine func5()
+ integer :: arr5(10)
+ common /blk5/ a5
+
+ !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp threadprivate(arr5)
+
+ !$omp threadprivate(/blk5/)
+
+ !ERROR: A variable that appears in a THREADPRIVATE directive must be declared in the scope of a module or have the SAVE attribute, either explicitly or implicitly
+ !$omp threadprivate(blk5)
+
+ !ERROR: A variable in a THREADPRIVATE directive cannot be an element of a common block
+ !$omp threadprivate(a5)
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate03.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate03.f90
new file mode 100644
index 0000000000000..b466a8e05e9c2
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/threadprivate03.f90
@@ -0,0 +1,28 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -pedantic
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.21.2 Threadprivate Directive
+
+module mod1
+end
+
+program main
+ use mod1
+ integer, parameter :: i = 1
+
+ !ERROR: The module name or main program name cannot be in a THREADPRIVATE directive
+ !$omp threadprivate(mod1)
+
+ !PORTABILITY: Name 'main' declared in a main program should not have the same name as the main program
+ !ERROR: The module name or main program name cannot be in a THREADPRIVATE directive
+ !$omp threadprivate(main)
+
+ !ERROR: The entity with PARAMETER attribute cannot be in a THREADPRIVATE directive
+ !$omp threadprivate(i)
+
+contains
+ subroutine sub()
+ !ERROR: The procedure name cannot be in a THREADPRIVATE directive
+ !$omp threadprivate(sub)
+ end
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate04.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate04.f90
new file mode 100644
index 0000000000000..3d8c7fb8de8fa
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/threadprivate04.f90
@@ -0,0 +1,53 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.21.2 Threadprivate Directive
+
+program main
+ integer :: i, N = 10
+ integer, save :: x1, x2, x3, x4, x5, x6, x7, x8, x9
+ common /blk1/ y1, /blk2/ y2, /blk3/ y3, /blk4/ y4, /blk5/ y5
+
+ !$omp threadprivate(x1, x2, x3, x4, x5, x6, x7, x8, x9)
+ !$omp threadprivate(/blk1/, /blk2/, /blk3/, /blk4/, /blk5/)
+
+ !$omp parallel num_threads(x1)
+ !$omp end parallel
+
+ !ERROR: COPYPRIVATE clause is not allowed on the OMP SINGLE directive, use it on OMP END SINGLE directive
+ !$omp single copyprivate(x2, /blk1/)
+ !$omp end single
+
+ !$omp single
+ !$omp end single copyprivate(x2, /blk1/)
+
+ !$omp do schedule(static, x3)
+ do i = 1, N
+ y1 = x3
+ end do
+ !$omp end do
+
+ !$omp parallel copyin(x4, /blk2/)
+ !$omp end parallel
+
+ !$omp parallel if(x5 > 1)
+ !$omp end parallel
+
+ !$omp teams thread_limit(x6)
+ !$omp end teams
+
+ !ERROR: A THREADPRIVATE variable cannot be in PRIVATE clause
+ !ERROR: A THREADPRIVATE variable cannot be in PRIVATE clause
+ !$omp parallel private(x7, /blk3/)
+ !$omp end parallel
+
+ !ERROR: A THREADPRIVATE variable cannot be in FIRSTPRIVATE clause
+ !ERROR: A THREADPRIVATE variable cannot be in FIRSTPRIVATE clause
+ !$omp parallel firstprivate(x8, /blk4/)
+ !$omp end parallel
+
+ !ERROR: A THREADPRIVATE variable cannot be in SHARED clause
+ !ERROR: A THREADPRIVATE variable cannot be in SHARED clause
+ !$omp parallel shared(x9, /blk5/)
+ !$omp end parallel
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate05.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate05.f90
new file mode 100644
index 0000000000000..cdbf3701b70ae
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/threadprivate05.f90
@@ -0,0 +1,44 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.21.2 Threadprivate Directive
+
+module mod0
+ integer :: mi
+
+contains
+ subroutine subm()
+ integer, save :: mmi
+
+ !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp threadprivate(mi)
+ mi = 1
+ contains
+ subroutine subsubm()
+ !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp threadprivate(mmi)
+ end
+ end
+end
+
+module mod1
+ integer :: mod_i
+end
+
+program main
+ use mod1
+ integer, save :: i
+ integer :: j
+
+ !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp threadprivate(mod_i)
+
+contains
+ subroutine sub()
+ !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
+ !$omp threadprivate(i, j)
+ i = 1
+ j = 1
+ end
+end
diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate06.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate06.f90
new file mode 100644
index 0000000000000..f31c38f6f2b24
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/threadprivate06.f90
@@ -0,0 +1,30 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.1
+! Check OpenMP construct validity for the following directives:
+! 2.21.2 Threadprivate Directive
+
+program main
+ call sub1()
+ print *, 'pass'
+end program main
+
+subroutine sub1()
+ common /c/ a
+ !$omp threadprivate(/c/)
+ integer :: a
+
+ a = 100
+ call sub2()
+ if (a .ne. 101) print *, 'err'
+
+contains
+ subroutine sub2()
+ common /c/ a
+ !$omp threadprivate(/c/)
+ integer :: a
+
+ !$omp parallel copyin(/c/)
+ a = a + 1
+ !$omp end parallel
+ end subroutine
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/threadprivate07.f90 b/flang/test/SemanticsChecked/OpenMP/threadprivate07.f90
new file mode 100644
index 0000000000000..c9a006ca0e083
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/threadprivate07.f90
@@ -0,0 +1,15 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+! Check Threadprivate Directive with local variable of a BLOCK construct.
+
+program main
+ call sub1()
+ print *, 'pass'
+end program main
+
+subroutine sub1()
+ BLOCK
+ integer, save :: a
+ !$omp threadprivate(a)
+ END BLOCK
+end subroutine
diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_addr.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_addr.f90
new file mode 100644
index 0000000000000..93a7643b5eb48
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/use_device_addr.f90
@@ -0,0 +1,17 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s
+! OpenMP Version 5.1
+! 2.14.2 use_device_addr clause
+! List item that appears in a use_device_addr clause has corresponding storage
+! in the device data environment, references to the list item in the associated
+! structured block are converted into references to the corresponding list item.
+
+subroutine omp_target_data
+ integer :: a(1024)
+ !CHECK: b, TARGET size=4096 offset=4096: ObjectEntity type: INTEGER(4) shape: 1_8:1024_8
+ integer, target :: b(1024)
+ a = 1
+ !$omp target data map(tofrom: a) use_device_addr(b)
+ !CHECK: b (OmpUseDeviceAddr): HostAssoc
+ b = a
+ !$omp end target data
+end subroutine omp_target_data
diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_addr1.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_addr1.f90
new file mode 100644
index 0000000000000..867e324b68ad9
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/use_device_addr1.f90
@@ -0,0 +1,33 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.0
+! 2.10.1 use_device_ptr clause
+! List item in USE_DEVICE_ADDR clause must not be structure element.
+! Same list item can not be present multiple times or in multipe
+! USE_DEVICE_ADDR clauses.
+
+subroutine omp_target_data
+ integer :: a(1024)
+ integer, target :: b(1024)
+ type my_type
+ integer :: my_b(1024)
+ end type my_type
+
+ type(my_type) :: my_var
+ a = 1
+
+ !ERROR: A variable that is part of another variable (structure element) cannot appear on the TARGET DATA USE_DEVICE_ADDR clause
+ !$omp target data map(tofrom: a) use_device_addr(my_var%my_b)
+ my_var%my_b = a
+ !$omp end target data
+
+ !ERROR: List item 'b' present at multiple USE_DEVICE_ADDR clauses
+ !$omp target data map(tofrom: a) use_device_addr(b,b)
+ b = a
+ !$omp end target data
+
+ !ERROR: List item 'b' present at multiple USE_DEVICE_ADDR clauses
+ !$omp target data map(tofrom: a) use_device_addr(b) use_device_addr(b)
+ b = a
+ !$omp end target data
+
+end subroutine omp_target_data
diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_ptr.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_ptr.f90
new file mode 100644
index 0000000000000..64b98cf67961d
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/use_device_ptr.f90
@@ -0,0 +1,21 @@
+! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s
+! OpenMP Version 5.0
+! 2.10.1 use_device_ptr clause
+! List items that appear in a use_device_ptr clause are converted into device
+! pointers to the corresponding list item in the device data environment.
+
+subroutine omp_target_data
+ use iso_c_binding
+ integer :: a(1024)
+ !CHECK: b size=8 offset=4096: ObjectEntity type: TYPE(c_ptr)
+ type(C_PTR) :: b
+ integer, pointer :: arrayB
+ a = 1
+ !$omp target data map(tofrom: a, arrayB) use_device_ptr(b)
+ !CHECK: b (OmpUseDevicePtr): HostAssoc
+ allocate(arrayB)
+ call c_f_pointer(b, arrayB)
+ a = arrayB
+ !$omp end target data
+end subroutine omp_target_data
+
diff --git a/flang/test/SemanticsChecked/OpenMP/use_device_ptr1.f90 b/flang/test/SemanticsChecked/OpenMP/use_device_ptr1.f90
new file mode 100644
index 0000000000000..176fb5f35a849
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/use_device_ptr1.f90
@@ -0,0 +1,64 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+! OpenMP Version 5.0
+! 2.10.1 use_device_ptr clause
+! List item in USE_DEVICE_PTR clause must not be structure element.
+! List item in USE_DEVICE_PTR clause must be of type C_PTR.
+! List items that appear in a use_device_ptr clause can not appear in
+! use_device_addr clause.
+! Same list item can not be present multiple times or in multipe
+! USE_DEVICE_PTR clauses.
+
+subroutine omp_target_data
+ use iso_c_binding
+ integer :: a(1024)
+ type(C_PTR) :: b
+ integer, pointer :: arrayB
+ type my_type
+ type(C_PTR) :: my_cptr
+ end type my_type
+
+ type(my_type) :: my_var
+ a = 1
+
+ !ERROR: A variable that is part of another variable (structure element) cannot appear on the TARGET DATA USE_DEVICE_PTR clause
+ !$omp target data map(tofrom: a, arrayB) use_device_ptr(my_var%my_cptr)
+ allocate(arrayB)
+ call c_f_pointer(my_var%my_cptr, arrayB)
+ a = arrayB
+ !$omp end target data
+
+ !WARNING: Use of non-C_PTR type 'a' in USE_DEVICE_PTR is deprecated, use USE_DEVICE_ADDR instead
+ !$omp target data map(tofrom: a) use_device_ptr(a)
+ a = 2
+ !$omp end target data
+
+ !ERROR: List item 'b' present at multiple USE_DEVICE_PTR clauses
+ !$omp target data map(tofrom: a, arrayB) use_device_ptr(b) use_device_ptr(b)
+ allocate(arrayB)
+ call c_f_pointer(b, arrayB)
+ a = arrayB
+ !$omp end target data
+
+ !ERROR: List item 'b' present at multiple USE_DEVICE_PTR clauses
+ !$omp target data map(tofrom: a, arrayB) use_device_ptr(b,b)
+ allocate(arrayB)
+ call c_f_pointer(b, arrayB)
+ a = arrayB
+ !$omp end target data
+
+ !ERROR: Variable 'b' may not appear on both USE_DEVICE_PTR and USE_DEVICE_ADDR clauses on a TARGET DATA construct
+ !$omp target data map(tofrom: a, arrayB) use_device_addr(b) use_device_ptr(b)
+ allocate(arrayB)
+ call c_f_pointer(b, arrayB)
+ a = arrayB
+ !$omp end target data
+
+ !ERROR: Variable 'b' may not appear on both USE_DEVICE_PTR and USE_DEVICE_ADDR clauses on a TARGET DATA construct
+ !$omp target data map(tofrom: a, arrayB) use_device_ptr(b) use_device_addr(b)
+ allocate(arrayB)
+ call c_f_pointer(b, arrayB)
+ a = arrayB
+ !$omp end target data
+
+end subroutine omp_target_data
+
diff --git a/flang/test/SemanticsChecked/OpenMP/workshare01.f90 b/flang/test/SemanticsChecked/OpenMP/workshare01.f90
new file mode 100644
index 0000000000000..9667a306061c0
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/workshare01.f90
@@ -0,0 +1,33 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.4 workshare Construct
+! Invalid do construct inside !$omp workshare
+
+subroutine workshare(aa, bb, cc, dd, ee, ff, n)
+ integer n, i
+ real aa(n,n), bb(n,n), cc(n,n), dd(n,n), ee(n,n), ff(n,n)
+
+ !ERROR: The structured block in a WORKSHARE construct may consist of only SCALAR or ARRAY assignments, FORALL or WHERE statements, FORALL, WHERE, ATOMIC, CRITICAL or PARALLEL constructs
+ !ERROR: OpenMP constructs enclosed in WORKSHARE construct may consist of ATOMIC, CRITICAL or PARALLEL constructs only
+ !$omp workshare
+ do i = 1, n
+ print *, "omp workshare"
+ end do
+
+ !$omp critical
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ aa = bb
+ !$omp end single
+ !$omp end critical
+
+ !$omp parallel
+ !$omp single
+ cc = dd
+ !$omp end single
+ !$omp end parallel
+
+ ee = ff
+ !$omp end workshare
+
+end subroutine workshare
diff --git a/flang/test/SemanticsChecked/OpenMP/workshare02.f90 b/flang/test/SemanticsChecked/OpenMP/workshare02.f90
new file mode 100644
index 0000000000000..e099ecb9f1e61
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/workshare02.f90
@@ -0,0 +1,65 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.4 workshare Construct
+! The !omp workshare construct must not contain any user defined
+! function calls unless the function is ELEMENTAL.
+
+module my_mod
+ contains
+ integer function my_func()
+ my_func = 10
+ end function my_func
+end module my_mod
+
+subroutine workshare(aa, bb, cc, dd, ee, ff, n)
+ use my_mod
+ integer n, i, j
+ real aa(n), bb(n), cc(n), dd(n), ee(n), ff(n)
+
+ !$omp workshare
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ aa = my_func()
+ cc = dd
+ ee = ff
+
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ where (aa .ne. my_func()) aa = bb * cc
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ where (dd .lt. 5) dd = aa * my_func()
+
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ where (aa .ge. my_func())
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ cc = aa + my_func()
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ elsewhere (aa .le. my_func())
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ cc = dd + my_func()
+ elsewhere
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ cc = ee + my_func()
+ end where
+
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ forall (j = 1:my_func()) aa(j) = aa(j) + bb(j)
+
+ forall (j = 1:10)
+ aa(j) = aa(j) + bb(j)
+
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ where (cc .le. j) cc = cc + my_func()
+ end forall
+
+ !$omp atomic update
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ j = j + my_func()
+
+ !$omp atomic capture
+ i = j
+ !ERROR: User defined non-ELEMENTAL function 'my_func' is not allowed in a WORKSHARE construct
+ j = j - my_func()
+ !$omp end atomic
+
+ !$omp end workshare
+
+end subroutine workshare
diff --git a/flang/test/SemanticsChecked/OpenMP/workshare03.f90 b/flang/test/SemanticsChecked/OpenMP/workshare03.f90
new file mode 100644
index 0000000000000..09d46abf42eec
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/workshare03.f90
@@ -0,0 +1,32 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.4 workshare Construct
+! All array assignments, scalar assignments, and masked array assignments
+! must be intrinsic assignments.
+
+module defined_assign
+ interface assignment(=)
+ module procedure work_assign
+ end interface
+
+ contains
+ subroutine work_assign(a,b)
+ integer, intent(out) :: a
+ logical, intent(in) :: b(:)
+ end subroutine work_assign
+end module defined_assign
+
+program omp_workshare
+ use defined_assign
+
+ integer :: a, aa(10), bb(10)
+ logical :: l(10)
+ l = .TRUE.
+
+ !$omp workshare
+ !ERROR: Defined assignment statement is not allowed in a WORKSHARE construct
+ a = l
+ aa = bb
+ !$omp end workshare
+
+end program omp_workshare
diff --git a/flang/test/SemanticsChecked/OpenMP/workshare04.f90 b/flang/test/SemanticsChecked/OpenMP/workshare04.f90
new file mode 100644
index 0000000000000..0ec635e52d2b7
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/workshare04.f90
@@ -0,0 +1,50 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.4 workshare Construct
+! Checks for OpenMP Workshare construct
+
+subroutine omp_workshare(aa, bb, cc, dd, ee, ff, n)
+ integer i, j, n, a(10), b(10)
+ integer, pointer :: p
+ integer, target :: t
+ real aa(n,n), bb(n,n), cc(n,n), dd(n,n), ee(n,n), ff(n,n)
+
+ !ERROR: The structured block in a WORKSHARE construct may consist of only SCALAR or ARRAY assignments, FORALL or WHERE statements, FORALL, WHERE, ATOMIC, CRITICAL or PARALLEL constructs
+ !$omp workshare
+ p => t
+
+ !$omp parallel
+ cc = dd
+ !$omp end parallel
+
+ !ERROR: OpenMP constructs enclosed in WORKSHARE construct may consist of ATOMIC, CRITICAL or PARALLEL constructs only
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp parallel workshare
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp single
+ ee = ff
+ !$omp end single
+ !$omp end parallel workshare
+
+ where (aa .ne. 0) cc = bb / aa
+
+ where (b .lt. 2) b = sum(a)
+
+ where (aa .ge. 2.0)
+ cc = aa + bb
+ elsewhere
+ cc = dd + ee
+ end where
+
+ forall (i = 1:10, n > i) a(i) = b(i)
+
+ forall (j = 1:10)
+ a(j) = a(j) + b(j)
+ end forall
+
+ !$omp atomic update
+ j = j + sum(a)
+
+ !$omp end workshare
+
+end subroutine omp_workshare
diff --git a/flang/test/SemanticsChecked/OpenMP/workshare05.f90 b/flang/test/SemanticsChecked/OpenMP/workshare05.f90
new file mode 100644
index 0000000000000..b57053e092e67
--- /dev/null
+++ b/flang/test/SemanticsChecked/OpenMP/workshare05.f90
@@ -0,0 +1,61 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! OpenMP Version 4.5
+! 2.7.4 workshare Construct
+! Checks for OpenMP Parallel constructs enclosed in Workshare constructs
+
+module workshare_mod
+ interface assignment(=)
+ module procedure work_assign
+ end interface
+
+ contains
+ subroutine work_assign(a,b)
+ integer, intent(out) :: a
+ logical, intent(in) :: b(:)
+ end subroutine work_assign
+
+ integer function my_func()
+ my_func = 10
+ end function my_func
+
+end module workshare_mod
+
+program omp_workshare
+ use workshare_mod
+
+ integer, parameter :: n = 10
+ integer :: i, j, a(10), b(10)
+ integer, pointer :: p
+ integer, target :: t
+ logical :: l(10)
+ real :: aa(n,n), bb(n,n), cc(n,n), dd(n,n), ee(n,n), ff(n,n)
+
+ !$omp workshare
+
+ !$omp parallel
+ p => t
+ a = l
+ !$omp single
+ ee = ff
+ !$omp end single
+ !$omp end parallel
+
+ !ERROR: A worksharing region may not be closely nested inside a worksharing, explicit task, taskloop, critical, ordered, atomic, or master region
+ !$omp parallel sections
+ !$omp section
+ aa = my_func()
+ !$omp end parallel sections
+
+ !$omp parallel do
+ do i = 1, 10
+ b(i) = my_func() + i
+ end do
+ !$omp end parallel do
+
+ !$omp parallel
+ where (dd .lt. 5) dd = aa * my_func()
+ !$omp end parallel
+
+ !$omp end workshare
+
+end program omp_workshare
diff --git a/flang/test/SemanticsChecked/PowerPC/ppc-vector-intrinsics.f90 b/flang/test/SemanticsChecked/PowerPC/ppc-vector-intrinsics.f90
new file mode 100644
index 0000000000000..e0df315fa57df
--- /dev/null
+++ b/flang/test/SemanticsChecked/PowerPC/ppc-vector-intrinsics.f90
@@ -0,0 +1,53 @@
+! RUN: %S/../test_errors.py %s %flang_fc1
+! REQUIRES: target=powerpc{{.*}}
+
+program test
+ vector(integer(4)) :: arg1, arg2, r
+ vector(real(4)) :: rr
+ integer :: i
+
+!ERROR: Actual argument #3 must be a constant expression
+ r = vec_sld(arg1, arg2, i)
+!ERROR: Argument #3 must be a constant expression in range 0 to 15
+ r = vec_sld(arg1, arg2, 17)
+
+!ERROR: Actual argument #3 must be a constant expression
+ r = vec_sldw(arg1, arg2, i)
+!ERROR: Argument #3 must be a constant expression in range 0 to 3
+ r = vec_sldw(arg1, arg2, 5)
+
+!ERROR: Actual argument #2 must be a constant expression
+ rr = vec_ctf(arg1, i)
+! ERROR: Argument #2 must be a constant expression in range 0 to 31
+ rr = vec_ctf(arg1, 37)
+end program test
+
+subroutine test_vec_permi()
+ vector(integer(8)) :: arg1, arg2, r
+ integer :: arg3
+!ERROR: Actual argument #3 must be a constant expression
+ r = vec_permi(arg1, arg2, arg3)
+! ERROR: Argument #3 must be a constant expression in range 0 to 3
+ r = vec_permi(arg1, arg2, 11)
+end
+
+subroutine test_vec_splat()
+ vector(integer(8)) :: arg1_8, r8
+ vector(integer(2)) :: arg1_2, r2
+ integer(2) :: arg2
+!ERROR: Actual argument #2 must be a constant expression
+ r8 = vec_splat(arg1_8, arg2)
+!ERROR: Argument #2 must be a constant expression in range 0 to 1
+ r8 = vec_splat(arg1_8, 3)
+!ERROR: Argument #2 must be a constant expression in range 0 to 7
+ r2 = vec_splat(arg1_2, 11)
+end
+
+subroutine test_vec_splat_s32()
+ integer(4) :: arg1
+ vector(integer(4)) :: r
+!ERROR: Actual argument #1 must be a constant expression
+ r = vec_splat_s32(arg1)
+!ERROR: Argument #1 must be a constant expression in range -16 to 15
+ r = vec_splat_s32(17)
+end
diff --git a/flang/test/SemanticsChecked/PowerPC/ppc-vector-types01.f90 b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types01.f90
new file mode 100644
index 0000000000000..ad69b69a47f76
--- /dev/null
+++ b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types01.f90
@@ -0,0 +1,69 @@
+! RUN: %flang_fc1 -fdebug-unparse %s | FileCheck %s
+! REQUIRES: target=powerpc{{.*}}
+
+ ! CHECK-LABEL: PROGRAM ppc_vec_unit
+ program ppc_vec_unit
+ implicit none
+ ! CHECK: VECTOR(INTEGER(KIND=4_4)) :: vi1, vi2
+ vector(integer(4)) :: vi1, vi2
+ ! CHECK-NEXT: VECTOR(REAL(KIND=8_4)) :: vr1, vr2
+ vector(real(8)) :: vr1, vr2
+ ! CHECK-NEXT: VECTOR(UNSIGNED(KIND=2_4)) :: vu1, vu2
+ vector(unsigned(2)) :: vu1, vu2
+ ! CHECK-NEXT: __VECTOR_PAIR :: vp1, vp2
+ __vector_pair :: vp1, vp2
+ ! CHECK-NEXT: __VECTOR_QUAD :: vq1, vq2
+ __vector_quad :: vq1, vq2
+ ! CHECK-NEXT: vi2=test_vec_integer_assign(vi1)
+ vi2 = test_vec_integer_assign(vi1)
+ ! CHECK-NEXT: vr2=test_vec_real_assign(vr1)
+ vr2 = test_vec_real_assign(vr1)
+ ! CHECK-NEXT: vu2=test_vec_unsigned_assign(vu1)
+ vu2 = test_vec_unsigned_assign(vu1)
+ ! CHECK-NEXT: vp2=test_vec_pair_assign(vp1)
+ vp2 = test_vec_pair_assign(vp1)
+ ! CHECK-NEXT: vq2=test_vec_quad_assign(vq1)
+ vq2 = test_vec_quad_assign(vq1)
+
+ contains
+ ! CHECK-LABEL: FUNCTION test_vec_integer_assign
+ function test_vec_integer_assign(arg1)
+ ! CHECK: VECTOR(INTEGER(KIND=4_4)) :: arg1, test_vec_integer_assign
+ vector(integer(4)) :: arg1, test_vec_integer_assign
+ ! CHECK-NEXT: test_vec_integer_assign=arg1
+ test_vec_integer_assign = arg1
+ end function test_vec_integer_assign
+
+ ! CHECK-LABEL: FUNCTION test_vec_real_assign
+ function test_vec_real_assign(arg1)
+ ! CHECK: VECTOR(REAL(KIND=8_4)) :: arg1, test_vec_real_assign
+ vector(real(8)) :: arg1, test_vec_real_assign
+ ! CHECK-NEXT: test_vec_real_assign=arg1
+ test_vec_real_assign = arg1
+ end function test_vec_real_assign
+
+ ! CHECK-LABEL: FUNCTION test_vec_unsigned_assign
+ function test_vec_unsigned_assign(arg1)
+ ! CHECK: VECTOR(UNSIGNED(KIND=2_4)) :: arg1, test_vec_unsigned_assign
+ vector(unsigned(2)) :: arg1, test_vec_unsigned_assign
+ ! CHECK-NEXT: test_vec_unsigned_assign=arg1
+ test_vec_unsigned_assign = arg1
+ end function test_vec_unsigned_assign
+
+ ! CHECK-LABEL: FUNCTION test_vec_pair_assign
+ function test_vec_pair_assign(arg1)
+ ! CHECK: __VECTOR_PAIR :: arg1, test_vec_pair_assign
+ __vector_pair :: arg1, test_vec_pair_assign
+ ! CHECK-NEXT: test_vec_pair_assign=arg1
+ test_vec_pair_assign = arg1
+ end function test_vec_pair_assign
+
+ ! CHECK-LABEL: FUNCTION test_vec_quad_assign
+ function test_vec_quad_assign(arg1)
+ ! CHECK: __VECTOR_QUAD :: arg1, test_vec_quad_assign
+ __vector_quad :: arg1, test_vec_quad_assign
+ ! CHECK-NEXT: test_vec_quad_assign=arg1
+ test_vec_quad_assign = arg1
+ end function test_vec_quad_assign
+
+ end
diff --git a/flang/test/SemanticsChecked/PowerPC/ppc-vector-types02.f90 b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types02.f90
new file mode 100644
index 0000000000000..8c96684c50eb7
--- /dev/null
+++ b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types02.f90
@@ -0,0 +1,60 @@
+! RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s
+! REQUIRES: target=powerpc{{.*}}
+
+! C: MainProgram scope: ppc_vec_types
+! CHECK-LABEL: MainProgram scope: ppc_vec_types size={{[0-9]*}} alignment={{[0-9]*}}
+program ppc_vec_types
+ implicit none
+ vector(integer(4)) :: vi
+ vector(real(8)) :: vr
+ vector(unsigned(2)) :: vu
+ __vector_pair :: vp
+ __vector_quad :: vq
+! CHECK-DAG: vi size=16 offset={{[0-9]*}}: ObjectEntity type: vector(integer(4))
+! CHECK-DAG: vr size=16 offset={{[0-9]*}}: ObjectEntity type: vector(real(8))
+! CHECK-DAG: vu size=16 offset={{[0-9]*}}: ObjectEntity type: vector(unsigned(2))
+! CHECK-DAG: vp size=32 offset={{[0-9]*}}: ObjectEntity type: __vector_pair
+! CHECK-DAG: vq size=64 offset={{[0-9]*}}: ObjectEntity type: __vector_quad
+
+contains
+! CHECK-LABEL: Subprogram scope: test_vec_integer_func size={{[0-9]*}} alignment={{[0-9]*}}
+ function test_vec_integer_func(arg1)
+ vector(integer(4)) :: arg1
+ vector(integer(4)) :: test_vec_integer_func
+! CHECK-DAG: arg1 size=16 offset={{[0-9]*}}: ObjectEntity dummy type: vector(integer(4))
+! CHECK-DAG: test_vec_integer_func size=16 offset={{[0-9]*}}: ObjectEntity funcResult type: vector(integer(4))
+ end function test_vec_integer_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_real_func size={{[0-9]*}} alignment={{[0-9]*}}
+ function test_vec_real_func(arg1)
+ vector(real(8)) :: arg1
+ vector(real(8)) :: test_vec_real_func
+! CHECK-DAG: arg1 size=16 offset={{[0-9]*}}: ObjectEntity dummy type: vector(real(8))
+! CHECK-DAG: test_vec_real_func size=16 offset={{[0-9]*}}: ObjectEntity funcResult type: vector(real(8))
+ end function test_vec_real_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_unsigned_func
+ function test_vec_unsigned_func(arg1)
+ vector(unsigned(2)) :: arg1
+ vector(unsigned(2)) :: test_vec_unsigned_func
+! CHECK-DAG: arg1 size=16 offset={{[0-9]*}}: ObjectEntity dummy type: vector(unsigned(2))
+! CHECK-DAG: test_vec_unsigned_func size=16 offset={{[0-9]*}}: ObjectEntity funcResult type: vector(unsigned(2))
+ end function test_vec_unsigned_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_pair_func
+ function test_vec_pair_func(arg1)
+ __vector_pair :: arg1
+ __vector_pair :: test_vec_pair_func
+! CHECK-DAG: arg1 size=32 offset={{[0-9]*}}: ObjectEntity dummy type: __vector_pair
+! CHECK-DAG: test_vec_pair_func size=32 offset={{[0-9]*}}: ObjectEntity funcResult type: __vector_pair
+ end function test_vec_pair_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_quad_func
+ function test_vec_quad_func(arg1)
+ __vector_quad :: arg1
+ __vector_quad :: test_vec_quad_func
+! CHECK-DAG: arg1 size=64 offset={{[0-9]*}}: ObjectEntity dummy type: __vector_quad
+! CHECK-DAG: test_vec_quad_func size=64 offset={{[0-9]*}}: ObjectEntity funcResult type: __vector_quad
+ end function test_vec_quad_func
+
+end program ppc_vec_types
diff --git a/flang/test/SemanticsChecked/PowerPC/ppc-vector-types03.f90 b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types03.f90
new file mode 100644
index 0000000000000..516b5eeb01d3a
--- /dev/null
+++ b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types03.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1
+! REQUIRES: target=aarch64{{.*}} || target=arm{{.*}} || target=x86{{.*}}
+
+program ppc_vec_types04
+ implicit none
+!ERROR: Vector type is only supported for PowerPC
+!ERROR: No explicit type declared for 'vi'
+ vector(integer(4)) :: vi
+!ERROR: Vector type is only supported for PowerPC
+!ERROR: No explicit type declared for 'vr'
+ vector(real(8)) :: vr
+!ERROR: Vector type is only supported for PowerPC
+!ERROR: No explicit type declared for 'vu'
+ vector(unsigned(2)) :: vu
+!ERROR: Vector type is only supported for PowerPC
+!ERROR: No explicit type declared for 'vp'
+ __vector_pair :: vp
+!ERROR: Vector type is only supported for PowerPC
+!ERROR: No explicit type declared for 'vq'
+ __vector_quad :: vq
+end program ppc_vec_types04
diff --git a/flang/test/SemanticsChecked/PowerPC/ppc-vector-types04.f90 b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types04.f90
new file mode 100644
index 0000000000000..6842233cab998
--- /dev/null
+++ b/flang/test/SemanticsChecked/PowerPC/ppc-vector-types04.f90
@@ -0,0 +1,47 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1
+! REQUIRES: target=powerpc{{.*}}
+
+subroutine vec_type_test(arg1, arg2, arg3, arg4)
+!ERROR: Assumed-shape entity of vector(real(4)) type is not supported
+ vector(real) :: arg1(:)
+!ERROR: Assumed Rank entity of vector(unsigned(4)) type is not supported
+ vector(unsigned) :: arg2(..)
+!ERROR: Deferred-shape entity of vector(integer(4)) type is not supported
+ vector(integer), allocatable :: arg3(:)
+!ERROR: Deferred-shape entity of vector(integer(4)) type is not supported
+ vector(integer), pointer :: arg4(:)
+!ERROR: Deferred-shape entity of vector(integer(4)) type is not supported
+ vector(integer), allocatable :: var1(:)
+!ERROR: Deferred-shape entity of vector(integer(4)) type is not supported
+ vector(integer), pointer :: var2(:)
+end subroutine vec_type_test
+
+subroutine vec_pair_type_test(arg1, arg2, arg3, arg4)
+!ERROR: Assumed-shape entity of __vector_pair type is not supported
+ __vector_pair :: arg1(:)
+!ERROR: Assumed Rank entity of __vector_pair type is not supported
+ __vector_pair :: arg2(..)
+!ERROR: Deferred-shape entity of __vector_pair type is not supported
+ __vector_pair, allocatable :: arg3(:)
+!ERROR: Deferred-shape entity of __vector_pair type is not supported
+ __vector_pair, pointer :: arg4(:)
+!ERROR: Deferred-shape entity of __vector_pair type is not supported
+ __vector_pair, allocatable :: var1(:)
+!ERROR: Deferred-shape entity of __vector_pair type is not supported
+ __vector_pair, pointer :: var2(:)
+end subroutine vec_pair_type_test
+
+subroutine vec_quad_type_test(arg1, arg2, arg3, arg4)
+!ERROR: Assumed-shape entity of __vector_quad type is not supported
+ __vector_quad :: arg1(:)
+!ERROR: Assumed Rank entity of __vector_quad type is not supported
+ __vector_quad :: arg2(..)
+!ERROR: Deferred-shape entity of __vector_quad type is not supported
+ __vector_quad, allocatable :: arg3(:)
+!ERROR: Deferred-shape entity of __vector_quad type is not supported
+ __vector_quad, pointer :: arg4(:)
+!ERROR: Deferred-shape entity of __vector_quad type is not supported
+ __vector_quad, allocatable :: var1(:)
+!ERROR: Deferred-shape entity of __vector_quad type is not supported
+ __vector_quad, pointer :: var2(:)
+end subroutine vec_quad_type_test
>From e3f48345d642f1bcaa11c24ca16e60f48e9c0606 Mon Sep 17 00:00:00 2001
From: Vlad Serebrennikov <serebrennikov.vladislav at gmail.com>
Date: Mon, 20 May 2024 05:31:05 +0300
Subject: [PATCH 30/30] Add missing test files
---
flang/test/SemanticsChecked/test_errors.py | 82 +++++++++++++++++
flang/test/SemanticsChecked/test_modfile.py | 98 +++++++++++++++++++++
flang/test/SemanticsChecked/test_symbols.py | 71 +++++++++++++++
3 files changed, 251 insertions(+)
create mode 100755 flang/test/SemanticsChecked/test_errors.py
create mode 100755 flang/test/SemanticsChecked/test_modfile.py
create mode 100755 flang/test/SemanticsChecked/test_symbols.py
diff --git a/flang/test/SemanticsChecked/test_errors.py b/flang/test/SemanticsChecked/test_errors.py
new file mode 100755
index 0000000000000..63ff3367edefd
--- /dev/null
+++ b/flang/test/SemanticsChecked/test_errors.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+
+"""Compiles a source file and checks errors against those listed in the file.
+
+Parameters:
+ sys.argv[1]: a source file with contains the input and expected output
+ sys.argv[2]: the Flang frontend driver
+ sys.argv[3:]: Optional arguments to the Flang frontend driver"""
+
+import sys
+import re
+import tempfile
+import subprocess
+import common as cm
+
+from difflib import unified_diff
+
+cm.check_args(sys.argv)
+srcdir = cm.set_source(sys.argv[1])
+with open(srcdir, "r") as f:
+ src = f.readlines()
+actual = ""
+expect = ""
+diffs = ""
+log = ""
+
+flang_fc1 = cm.set_executable(sys.argv[2])
+flang_fc1_args = sys.argv[3:]
+flang_fc1_options = "-fsyntax-only"
+
+# Compiles, and reads in the output from the compilation process
+cmd = [flang_fc1, *flang_fc1_args, flang_fc1_options, str(srcdir)]
+with tempfile.TemporaryDirectory() as tmpdir:
+ try:
+ proc = subprocess.run(
+ cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ check=True,
+ universal_newlines=True,
+ cwd=tmpdir,
+ )
+ except subprocess.CalledProcessError as e:
+ log = e.stderr
+ if e.returncode >= 128:
+ print(f"{log}")
+ sys.exit(1)
+
+# Cleans up the output from the compilation process to be easier to process
+for line in log.split("\n"):
+ m = re.search(r"[^:]*:(\d+:).*(?:error|warning|portability|because):(.*)", line)
+ if m:
+ if re.search(r"warning: .*fold.*host", line):
+ continue # ignore host-dependent folding warnings
+ actual += m.expand(r"\1\2\n")
+
+# Gets the expected errors and their line numbers
+errors = []
+for i, line in enumerate(src, 1):
+ m = re.search(r"(?:^\s*!\s*(?:ERROR|WARNING|PORTABILITY|BECAUSE): )(.*)", line)
+ if m:
+ errors.append(m.group(1))
+ continue
+ if errors:
+ for x in errors:
+ expect += f"{i}: {x}\n"
+ errors = []
+
+# Compares the expected errors with the compiler errors
+for line in unified_diff(actual.split("\n"), expect.split("\n"), n=0):
+ line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line)
+ line = re.sub(r"(^\+)(\d+:)", r"\nexpect at \g<2>", line)
+ diffs += line
+
+if diffs != "":
+ print(diffs)
+ print()
+ print("FAIL")
+ sys.exit(1)
+else:
+ print()
+ print("PASS")
diff --git a/flang/test/SemanticsChecked/test_modfile.py b/flang/test/SemanticsChecked/test_modfile.py
new file mode 100755
index 0000000000000..0e7806f27aa90
--- /dev/null
+++ b/flang/test/SemanticsChecked/test_modfile.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+
+"""Compiles a source file and compares generated .mod files against expected.
+
+Parameters:
+ sys.argv[1]: a source file with contains the input and expected output
+ sys.argv[2]: the Flang frontend driver
+ sys.argv[3:]: Optional arguments to the Flang frontend driver"""
+
+import sys
+import re
+import os
+import tempfile
+import subprocess
+import glob
+import common as cm
+
+from pathlib import Path
+from difflib import unified_diff
+
+cm.check_args_long(sys.argv)
+srcdir = Path(sys.argv[1])
+sources = list(glob.iglob(str(srcdir)))
+sources = sorted(sources)
+diffs = ""
+
+flang_fc1 = cm.set_executable(sys.argv[2])
+flang_fc_args = sys.argv[3:]
+flang_fc1_options = "-fsyntax-only"
+
+with tempfile.TemporaryDirectory() as tmpdir:
+ for src in sources:
+ src = Path(src).resolve()
+ actual = ""
+ expect = ""
+ expected_files = set()
+ actual_files = set()
+
+ if not src.is_file():
+ cm.die(src)
+
+ prev_files = set(os.listdir(tmpdir))
+ cmd = [flang_fc1, *flang_fc_args, flang_fc1_options, str(src)]
+ proc = subprocess.check_output(
+ cmd, stderr=subprocess.PIPE, universal_newlines=True, cwd=tmpdir
+ )
+ actual_files = set(os.listdir(tmpdir)).difference(prev_files)
+
+ # The first 3 bytes of the files are an UTF-8 BOM
+ with open(src, "r", encoding="utf-8", errors="strict") as f:
+ for line in f:
+ m = re.search(r"^!Expect: (.*)", line)
+ if m:
+ expected_files.add(m.group(1))
+
+ extra_files = actual_files.difference(expected_files)
+ if extra_files:
+ print(f"Unexpected .mod files produced: {extra_files}")
+ sys.exit(1)
+
+ for mod in expected_files:
+ mod = Path(tmpdir).joinpath(mod)
+ if not mod.is_file():
+ print(f"Compilation did not produce expected mod file: {mod}")
+ sys.exit(1)
+ with open(mod, "r", encoding="utf-8", errors="strict") as f:
+ for line in f:
+ if "!mod$" in line or "!need$" in line:
+ continue
+ actual += line
+
+ with open(src, "r", encoding="utf-8", errors="strict") as f:
+ for line in f:
+ if f"!Expect: {mod.name}" in line:
+ for line in f:
+ if re.match(r"^$", line):
+ break
+ m = re.sub(r"^!", "", line.lstrip())
+ expect += m
+
+ diffs = "\n".join(
+ unified_diff(
+ actual.replace(" ", "").split("\n"),
+ expect.replace(" ", "").split("\n"),
+ fromfile=mod.name,
+ tofile="Expect",
+ n=999999,
+ )
+ )
+
+ if diffs != "":
+ print(diffs)
+ print()
+ print("FAIL")
+ sys.exit(1)
+
+print()
+print("PASS")
diff --git a/flang/test/SemanticsChecked/test_symbols.py b/flang/test/SemanticsChecked/test_symbols.py
new file mode 100755
index 0000000000000..24dc5004a4229
--- /dev/null
+++ b/flang/test/SemanticsChecked/test_symbols.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+
+"""Compiles a source file with "-fdebug-unparse-with-symbols' and verifies
+we get the right symbols in the output, i.e. the output should be
+the same as the input, except for the copyright comment.
+
+Parameters:
+ sys.argv[1]: a source file with contains the input and expected output
+ sys.argv[2]: the Flang frontend driver
+ sys.argv[3:]: Optional arguments to the Flang frontend driver"""
+
+import sys
+import tempfile
+import re
+import subprocess
+import common as cm
+
+from difflib import unified_diff
+
+cm.check_args(sys.argv)
+src = cm.set_source(sys.argv[1])
+diff1 = ""
+diff2 = ""
+
+flang_fc1 = cm.set_executable(sys.argv[2])
+flang_fc1_args = sys.argv[3:]
+flang_fc1_options = "-fdebug-unparse-with-symbols"
+
+# Strips out blank lines and all comments except for "!DEF:", "!REF:", "!$acc" and "!$omp"
+with open(src, "r") as text_in:
+ for line in text_in:
+ text = re.sub(r"!(?![DR]EF:|\$omp|\$acc).*", "", line)
+ text = re.sub(r"^\s*$", "", text)
+ diff1 += text
+
+# Strips out "!DEF:" and "!REF:" comments
+for line in diff1:
+ text = re.sub(r"![DR]EF:.*", "", line)
+ diff2 += text
+
+# Compiles, inserting comments for symbols:
+cmd = [flang_fc1, *flang_fc1_args, flang_fc1_options]
+with tempfile.TemporaryDirectory() as tmpdir:
+ diff3 = subprocess.check_output(
+ cmd, input=diff2, universal_newlines=True, cwd=tmpdir
+ )
+
+# Removes all whitespace to compare differences in files
+diff1 = diff1.replace(" ", "")
+diff3 = diff3.replace(" ", "")
+diff_check = ""
+
+# Compares the input with the output
+diff_check = "\n".join(
+ unified_diff(
+ diff1.split("\n"),
+ diff3.split("\n"),
+ n=999999,
+ fromfile="Expected_output",
+ tofile="Actual_output",
+ )
+)
+
+if diff_check != "":
+ print(diff_check.replace(" ", ""))
+ print()
+ print("FAIL")
+ sys.exit(1)
+else:
+ print()
+ print("PASS")
More information about the flang-commits
mailing list