diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3965,7 +3965,8 @@ match for an OpenMP context. The default is ``all``, with ``none`` no trait in the selector is allowed to be in the OpenMP context, with ``any`` a single trait in both the selector and OpenMP context is sufficient. Only a single match -extension trait is allowed per context selector. +extension trait is allowed per context selector. Note that match extensions are +not propagated to nested selectors like the standard defines it for other traits. The disable extensions remove default effects of the ``begin declare variant`` applied to a definition. If ``disable_implicit_base`` is given, we will not introduce an implicit base function for a variant if no base function was diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1477,6 +1477,14 @@ MergedSelector = true; for (const OMPTraitProperty &ParentProperty : ParentSelector.Properties) { + // Do not propagate match extensions to nested contexts. + if (ParentProperty.Kind == llvm::omp::TraitProperty:: + implementation_extension_match_any || + ParentProperty.Kind == llvm::omp::TraitProperty:: + implementation_extension_match_all || + ParentProperty.Kind == llvm::omp::TraitProperty:: + implementation_extension_match_none) + continue; bool MergedProperty = false; for (OMPTraitProperty &Property : Selector.Properties) { // Ignore "equivalent" properties. diff --git a/clang/test/OpenMP/begin_declare_variant_nested_propagation.c b/clang/test/OpenMP/begin_declare_variant_nested_propagation.c new file mode 100644 --- /dev/null +++ b/clang/test/OpenMP/begin_declare_variant_nested_propagation.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c -std=c99 -fms-extensions -Wno-pragma-pack %s +// expected-no-diagnostics + +#pragma omp begin declare variant match(implementation={extension(match_any)}) +#pragma omp begin declare variant match(device = {vendor(cray, ibm)}) + this is never reached, we cannot have a cray ibm compiler hybrid, I hope. +#pragma omp end declare variant +#pragma omp end declare variant