Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -811,8 +811,22 @@ // FIXME: We can promote this to an error. The function or variable can't // be defined anywhere else, so the program must necessarily violate the // one definition rule. - S.Diag(VD->getLocation(), diag::warn_undefined_internal) - << isa(VD) << VD; + bool IsImplicitBase = false; + if (FunctionDecl *BaseD = dyn_cast(VD)) { + OMPDeclareVariantAttr *DVAttr = BaseD->getAttr(); + if (DVAttr && !DVAttr->getTraitInfo().isExtensionActive( + llvm::omp::TraitProperty:: + implementation_extension_disable_implicit_base)) { + FunctionDecl *Func = dyn_cast( + cast(DVAttr->getVariantFuncRef())->getDecl()); + IsImplicitBase = + BaseD->isImplicit() && + Func->getName().str().find(BaseD->getName().str()) >= 0; + } + } + if (!S.getLangOpts().OpenMP || !IsImplicitBase) + S.Diag(VD->getLocation(), diag::warn_undefined_internal) + << isa(VD) << VD; } else if (auto *FD = dyn_cast(VD)) { (void)FD; assert(FD->getMostRecentDecl()->isInlined() && Index: clang/test/OpenMP/declare_variant.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/declare_variant.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify %s + +namespace { + // expected-warning@+1{{function '(anonymous namespace)::bar' has internal linkage but is not defined}} +void bar(); +} + +#pragma omp begin declare variant match(user={condition(1)}) +void bar() { +} +#pragma omp end declare variant + +// expected-warning@+1{{function 'baz' has internal linkage but is not defined}} +static void baz(); +#pragma omp begin declare variant match(device = {kind(nohost)}) +static void baz() {} +#pragma omp end declare variant + +#pragma omp begin declare variant match(device = {kind(host)}) +static void foo() {} +#pragma omp end declare variant + +int main() { + foo(); +// expected-note@+1{{used here}} + baz(); +// expected-note@+1{{used here}} + bar(); + + return 0; +}