Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -812,8 +812,21 @@ // 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 (const auto *BaseD = dyn_cast(VD)) { + auto *DVAttr = BaseD->getAttr(); + if (DVAttr && !DVAttr->getTraitInfo().isExtensionActive( + llvm::omp::TraitProperty:: + implementation_extension_disable_implicit_base)) { + const auto *Func = cast( + cast(DVAttr->getVariantFuncRef())->getDecl()); + IsImplicitBase = BaseD->isImplicit() && + Func->getIdentifier()->isMangledOpenMPVariantName(); + } + } + 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,32 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify %s + +namespace { +// TODO this must be fixed. This warning shouldn't be generated. +// expected-warning@+1{{function '(anonymous namespace)::bar' has internal linkage but is not defined}} +void bar(); +} // namespace + +#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; +}