diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10830,6 +10830,8 @@ def err_omp_declare_variant_incompat_types : Error< "variant in '#pragma omp declare variant' with type %0 is incompatible with" " type %1%select{| with appended arguments}2">; +def err_omp_declare_variant_same_base_function : Error< + "variant in '#pragma omp declare variant' is the same as the base function">; def warn_omp_declare_variant_marked_as_declare_variant : Warning< "variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'" >, InGroup; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -7171,6 +7171,13 @@ return None; } + if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { + Diag(VariantRef->getExprLoc(), + diag::err_omp_declare_variant_same_base_function) + << VariantRef->getSourceRange(); + return None; + } + // Check if function types are compatible in C. if (!LangOpts.CPlusPlus) { QualType NewType = diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c --- a/clang/test/OpenMP/declare_variant_messages.c +++ b/clang/test/OpenMP/declare_variant_messages.c @@ -113,6 +113,15 @@ return after_use(); } +// expected-error@+1 {{variant in '#pragma omp declare variant' is the same as the base function}} +#pragma omp declare variant (self) \ + match(construct={dispatch}, device={arch(arm)}) +void self(int n); + +void self_test(int n, int d_no) { + #pragma omp dispatch device(d_no) nowait + self(n); +} #pragma omp declare variant(after_use_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{'#pragma omp declare variant' cannot be applied for function after first usage; the original function might be used}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int after_use(void);